request对象和respones对象

本文详细介绍了在web项目中request和response对象的作用。request对象用于封装客户端的请求信息,包括请求行、请求头、请求体数据,并提供了获取参数、转发请求和共享数据的方法。response对象则用于封装服务器返回给客户端的响应,包括设置响应行、响应头和响应体,以及实现重定向。同时,文中还讲解了请求转发和重定向的区别以及URL的相对路径和绝对路径的使用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、web项目,是通过response和request对象通信,request封装请求消息,response对象封装返回消息。

    1.服务器会根据请求url中的资源路径创建对应的Servlet的对象。
    2.服务器会创建request和respones对象。
    3.服务器将request和response两个对象传递给service()方法。
    4.程序员可以通过request对象获取请求数据,通过respones对象设置响应消息数据。
    5.服务器在给浏览器做出响应之前,会从response对象中拿出程序员设置的响应消息数据。

二、request
    结构
        1.ServletRequest -- 接口
        2.HttpServletRequest --接口(实现ServletRequest)
        3.org.apache.catalina.connector.RequestFacade (tomCat创建用于实现HttpServletRequest接口)
    功能
        1.获取请求行数据
            1.获取请求方式 String getMethod()
            2.获取虚拟目录(项目根目录) String getContexPath()
            3.获取Servlet路径(定义的servlet请求路径) String getServletPath()
            4.获取get方式请求参数 String getQueryString();
            5.获取URI String getRequestURI() --请求的路径
            6.获取url StringBuffer getRequestURL(); --http://IP:端口/请求路径
            //URL:统一资源定位符;URI:统一资源标识符
            7.获取协议及版本 String getProtocol() --http/1.1
            8.获取客户机IP String getRemoteAddr()

package com.xiaoqiang.web;

import javax.servlet.ServletException;
import javax.servlet.ServletInputStream;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedReader;
import java.io.IOException;
import java.util.Enumeration;

@WebServlet("/demo/requestDemo")
public class RequestDemoServlet extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //获取请求行数据
        // 1.获取请求方式 String getMethod()
        String method = req.getMethod();
        System.out.println("获取请求方式 String getMethod():" + method);
        // 2.获取虚拟目录(项目根目录) String getContexPath()
        String contextPath = req.getContextPath();
        System.out.println("获取虚拟目录(项目根目录) String getContexPath():" + contextPath);
        //3.获取Servlet路径(定义的servlet请求路径) String getServletPath()
        String servletPath = req.getServletPath();
        System.out.println("3.获取Servlet路径 String getServletPath():" + servletPath);
        //4.获取get方式请求参数 String getQueryString();
        String queryString = req.getQueryString();
        System.out.println("获取get方式请求参数 String getQueryString():" + queryString);
        //5.获取URI String getRequestURI() --请求的路径
        String requestURI = req.getRequestURI();
        System.out.println("获取URI String getRequestURI() --请求的路径:"+requestURI);
        //6.获取url StringBuffer getRequestURL(); --http://IP:端口/请求路径
        StringBuffer requestURL = req.getRequestURL();
        System.out.println("获取url StringBuffer getRequestURL(); --http://IP:端口/请求路径:" + requestURL.toString());
        //7.获取协议及版本 String getProtocol() --http/1.1
        String protocol = req.getProtocol();
        System.out.println("获取协议及版本 String getProtocol() --http/1.1:" + protocol);
        //8.获取客户机IP String getRemoteAddr()
        String remoteAddr = req.getRemoteAddr();
        System.out.println("获取客户机IP String getRemoteAddr():" + remoteAddr);

        //获取请求头数据
//        1.getHeaderNames()获取所有的请求头名称
        Enumeration<String> headerNames = req.getHeaderNames();
//        2.遍历获取到的请求头名称,String getHeader(String name) 通过请求头的名称获取请求头的值
        while (headerNames.hasMoreElements()){ //hasMoreElements() 迭代标志,是否有下一个请求头
            String s = headerNames.nextElement();//获取下一请求头名称
            String header = req.getHeader(s); //通过请求头的名称获取请求头的值
            System.out.println("请求头"+s +"的值是:" + header);
        }

    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
       //获取请求体
//            1.获取字符流
        BufferedReader reader = req.getReader();
        String line=null;
        while ((line = reader.readLine()) != null){
            System.out.println(line);
        }

    }
}

        2.获取请求头数据
            1.getHeaderNames():获取所有的请求头名称
            2.String getHeader(String name) 通过请求头的名称获取请求头的值

        3.获取请求体数据
            *请求体:只有POST请求才有请求体,在请求体中封装了POST请求的请求参数
            步骤*
                1.获取流对象(字节流、字符流)
                      BufferedReader getReader() 获取字符输入流
                       ServletInputStream getInputStream() 获取字节输入流,可以操作有类的数据
                2.从流对象中获取数据
        4.其他功能
            1.获取请求参数通用方式
                String getParameter(String name);根据参数名称获取参数值
                String[] getParameterValues("");根据参数名称获取参数值数组(多用于复选框)
                Enumeration<String> getParameterNames();获取所有参数名称
                Map<String, String[]> getParameterMap();获取所有参数的map集合,将参数名和参数值转换为Map集合, String[]避免参数有多个值的获取
                 //避免中文乱码,设置的值需要和请求页面的值要一致request.setCharacterEncoding("utf-8");
                

package com.xiaoqiang.web;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Enumeration;
import java.util.Map;
import java.util.Set;

@WebServlet("/obtainParameterServlet")
public class ObtainParameterServlet extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //避免中文乱码,设置的值需要和请求页面的值要一致
        req.setCharacterEncoding("utf-8");
//        String parameter = req.getParameter("");
//        String[] parameterValues = req.getParameterValues("");
//        Enumeration<String> parameterNames = req.getParameterNames();
//        Map<String, String[]> parameterMap = req.getParameterMap();
        //请求示例:http://localhost:8080/studyWeb/obtainParameterServlet?name=11111&passWord=22222
//        获取所有参数名
//        Enumeration<String> parameterNames = req.getParameterNames();
//        while (parameterNames.hasMoreElements()){
//            String s = parameterNames.nextElement();
//              根据参数名获取参数值
//            String parameter = req.getParameter(s);
//            System.out.println("参数" + s +"的值是:" + parameter);
//        }

        //请求示例:http://localhost:8080/studyWeb/obtainParameterServlet?name=11111&name=222&name=333&paw=44444
        Map<String, String[]> parameterMap = req.getParameterMap();
        Set<String> strings = parameterMap.keySet();
        for (String str : strings) {
            String[] values = parameterMap.get(str);
            String v = "";
            for (String value : values) {
                v = v + value + " ";
            }
            System.out.println("参数" + str + "的值是:" + v);
        }

        //请求示例:http://localhost:8080/studyWeb/obtainParameterServlet?name=11111&name=222&name=333
//        String[] parameterValues = req.getParameterValues("name");
//        for (String str : parameterValues) {
//            System.out.println("name的值:" + str + " ");
//        }


    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //采用通用的获取参数的方式,post和get获取请求值的方式不再有区别,写一份获取值的代码即可
        this.doGet(req, resp);
    }
}
package com.xiaoqiang.web;

import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;

@WebServlet("/responseDemo2Servlet")
public class ResponseDemo2Servlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        this.doPost(req,resp);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("responseDemo2Servlet.....");
        //获取字符输出流前设置编码格式,并告诉浏览器使用什么编码格式解码,防止乱码
//        resp.setCharacterEncoding("utf-8");
//        resp.setHeader("content-type","text/html;charset=utf-8");
        resp.setContentType("text/html;charset=utf-8");
        //获取字符输出流
        PrintWriter writer = resp.getWriter();
        //输出数据
        writer.println("<h1>你好 response</h1>");
    }
}

            2.请求转发 - 服务器内部资源跳转方式
                RequestDispatcher getRequestDispatcher(String path);获取请求对象转发器
                forward(req,resp);调用转发器的方法转发请求
                特点:1.浏览器地址栏路径不发生变化
                    2.只能转发到当前服务内的资源
                    3.转发基于客户端的一次请求即可

            3.共享数据
                域对象:一个有作用范围的对象,在范围内都可以访问该对象。
                request域:代表一次请求的范围,一般用于请求转发的多个资源中共享数据。
                方法:
                    void setAttribute(String name,Object obj);存储数据
                    Object getAttribute(String name);获取数据
                    void removeAttribute(String name)移除数据

            4.获取ServletContext
                ServletContext getServletContext(); 获取ServletContext对象

package com.xiaoqiang.web;

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@WebServlet("/forwardServlet")
public class ForwardServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        req.setAttribute("source","访问来源forwardServlet");
        RequestDispatcher requestDispatcher = req.getRequestDispatcher("/receiveServlet");
        requestDispatcher.forward(req,resp);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        this.doGet(req,resp);
    }
}
package com.xiaoqiang.web;

import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@WebServlet("/receiveServlet")
public class ReceiveServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

        String source = (String) req.getAttribute("source");
        System.out.println("接收者:receiveServlet" +"__" + source);

    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        this.doGet(req,resp);
    }
}

三、response的继承结构
    1.设置响应行
        格式:HTTP/1.1 200 OK 
        设置状态码 void setStatus(int sc)
    2.设置响应头
        void setHeader(String name,String value)
    
    3.设置响应体
        1.步骤:
            1.获取输出流
                1.字符输出流 PringWriter getWriter()
                    为避免浏览器解析输出数据中文乱码,需要告诉浏览器使用什么格式解码
                    resp.setHeader("content-type","text/html;charset=utf-8") 或者 resp.setContentType("text/html;charset=utf-8")
                2.字节输出流  ServletOutputStream getOutputStream();

            2.使用输出流将数据输出到客户端

    4.重定向:浏览器请求资源A,资源A告诉浏览器需要请求资源B,浏览器会去请求资源B
        1.设置状态码为301或302告诉浏览器重定向
        2.在请求头中设置请求头location,值为需要重定向到地址的资源路径
        3.java简单的重定向方法:void sendRedirect(String s)

    转发(forward)和重定向(redirect)的区别
        转发:转发地址栏不变化、只能访问当前服务下的资源、转发浏览器只请求一次,可以使用request域共享数据
        重定向:地址栏发生变化,可以访问其他服务器资源,重定向浏览器接会有两次请求,会产生两个request对象,不能通过request共享数据

    绝对路径和相对路径
        1.相对路径:不以/开头的资源路径,通过相对路径不可以确定唯一资源
            例如:./index.html 或者 index.html
            规则:相对路径会以当前资源为基准,寻找目标资源,要使用相对路径需要确定当前资源和目标资源的相对的关系
            当前目录 ./ 或者直接写目标的名称会从当前资源所在的路径开始
            后退一级 ../
        2.绝对路径:以/(项目根目录或者说项目虚拟目录)开头的路径,通过绝对路径可以确定唯一资源
            例如:http://localhost:8080/studyWeb/responseDemo2Servlet
            可以简写为:/studyWeb/responseDemo2Servlet
        3.使用规则:判断路径给谁用的
                1.给客服端使用:需要加虚拟目录(项目访问路径)
                    建议动态获取虚拟目录:request.getContextPath()
                2.给服务器使用:不需要加虚拟目录

package com.xiaoqiang.web;

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;

@WebServlet("/responseServlet")
public class ResponseServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        this.doPost(req,resp);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("responseServlet......");
        //设置状态码,  告诉浏览器需要重定向
//        resp.setStatus(302);
        //设置请求头,告诉浏览器请求的地址
//        resp.setHeader("location","/studyWeb/responseDemo2Servlet");
//        JAVA封装的重定向方法
//        resp.sendRedirect("/studyWeb/responseDemo2Servlet");
        //动态获取项目虚拟目录,防止虚拟目录变更造成资源请求404
        String contextPath = req.getContextPath();
        resp.sendRedirect(contextPath + "/responseDemo2Servlet");
        //获取输出流--字符输出流
//        PrintWriter writer = resp.getWriter();
//        writer.println("");
        //获取输出流-- 字节输出流
//        ServletOutputStream outputStream = resp.getOutputStream();
    }
}
package com.xiaoqiang.web;

import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;

@WebServlet("/responseDemo2Servlet")
public class ResponseDemo2Servlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        this.doPost(req,resp);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("responseDemo2Servlet.....");
        //获取字符输出流前设置编码格式,并告诉浏览器使用什么编码格式解码,防止乱码
//        resp.setCharacterEncoding("utf-8");
//        resp.setHeader("content-type","text/html;charset=utf-8");
        resp.setContentType("text/html;charset=utf-8");
        //获取字符输出流
        PrintWriter writer = resp.getWriter();
        //输出数据
        writer.println("<h1>你好 response</h1>");
    }
}
package com.xiaoqiang.web;

import javax.imageio.ImageIO;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.io.PrintWriter;
import java.nio.charset.StandardCharsets;
import java.util.Random;

@WebServlet("/responseDemo3Servlet")
public class ResponseDemo3Servlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        this.doPost(req,resp);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //告知浏览器解码格式
//        resp.setContentType("text/html;charset=utf-8");
        //获取字节输出流
//        ServletOutputStream outputStream = resp.getOutputStream();
        //输出字节
//        outputStream.write("你好".getBytes(StandardCharsets.UTF_8));
        //创建图片对象
        int width=100;
        int height=50;
        BufferedImage bufferedImage = new BufferedImage(width,height,BufferedImage.TYPE_INT_RGB);

        //美化图片
        //填充颜色
        Graphics graphics = bufferedImage.getGraphics();//获取画笔
        graphics.setColor(Color.yellow);//设置画笔颜色
        graphics.fillRect(0,0,width,height);
        //画边框
        graphics.setColor(Color.blue);
        graphics.drawRect(0,0,width,height-1);

        String strs = "AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz0123456789";
        Random random = new Random();

        graphics.setColor(Color.black);
        for (int i = 0; i < 4; i++) {
            int index = random.nextInt(strs.length());
            String str = strs.substring(index,index+1);
            graphics.drawString(str,width/5*i,height/2);
        }



        ImageIO.write(bufferedImage,"jpg",resp.getOutputStream());

    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值