重学JavaWeb(16)响应对象response、请求对象request

1. 响应对象response

1. 原理
(1)response和request对象是由服务器创建,管理,销毁的
(2)继承体系

ServletResponse(接口)<----继承----  HttpServletResponse(接口) <----实现----org.apache.catalina.connector.ResponseFacade@3bec9d4

ServletRequest(接口)<--------继承<-------HttpServletRequest(接口)<--------实现 org.apache.catalina.connector.RequestFacade@6049a827

在这里插入图片描述

(3)当服务器收到浏览器的请求后,服务器会创建Servlet对象,也会去创建请求和响应对象,请求对象会把浏览器的请求信息封装到请求对象里面,然后服务器通过调用service()方法,然后把请求和响应对象传给该方法,所以就可以在service()方法里面取出这两个对象来用。如果你要设置响应信息,你就把响应的数据设置到响应对象里面,服务器在正式响应浏览器之前,会从响应对象里面取出响应的数据,给浏览器响应回去

2. response设置响应消息之设置响应行
(1)方法:setStatus(int code):设置响应状态码
(2)重定向

1. 状态码:302
2. 特点:
	1. 两次请求,两次响应
	2. 地址栏发生变化
	3. 不仅可以访问内部资源,也可以访问外部资源
3. 方法
	1.1 设置状态码302:response.setStatus(302)
	1.2 设置响应头:response.setHeader("location","https://www.baidu.com") 
	2. 以上两个步骤可以合为一个:response.sendRedirect("https://www.baidu.com")

在这里插入图片描述
(3)重定向的代码示例

@WebServlet(name = "ServletDemo01", value = "/demo01")
public class ServletDemo01 extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //设置响应状态码
        response.setStatus(302);
        //重定向,跳转到本地页面
        response.setHeader("location","/1115/home.jsp");

        //重定向合为一步,跳转外部页面
        response.sendRedirect("https://www.baidu.com");
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        this.doPost(request, response);
    }
}

3. response设置响应消息之设置响应体
(1)响应体响应的是数据,需要通过流的形式,获取输出流写出数据
(2)为了防止乱码,需要设置一下服务器对字符流的编码

1.1 在获取流之前告诉服务器用的是什么编码:response.setCharacterEncoding("utf-8")
1.2 告诉浏览器我们用的是什么编码 ,好让浏览器用响应的编码去解码:response.setHeader("content-type","text/html;charset=utf-8")
2. 两步可以合成一步:response.setContentType("text/html;charset=utf-8");//作用:设置字符打印输出流的编码,并告诉浏览器用相应的编码去解码

(3)获取流的方法

1. PrintWriter getWriter():获取发送字符数据的对象
2. ServletOutputStream getOutputStream():获取发送字节数据的对象

(4)代码示例

@WebServlet(name = "ServletDemo02", value = "/demo02")
public class ServletDemo02 extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //解决中文乱码,设置编码集
        response.setContentType("text/html;charset=utf-8");
        //获取字符输出流
        PrintWriter writer = response.getWriter();
        //输出数据
        writer.write("<h1 style='color:red'>你好,response对象~</h1>");

    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        this.doPost(request, response);
    }
}

=======================================================================================

@WebServlet(name = "ServletDemo03", value = "/demo03")
public class ServletDemo03 extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

        //获取访问服务器的IP地址
        String remoteAddr = request.getRemoteAddr();
        System.out.println(remoteAddr);

        //读取WEB/INF下的timg.jpg图片
        String realPath = this.getServletContext().getRealPath("/WEB-INF/timg.jpg");
        FileInputStream is = new FileInputStream(realPath);
        //通过响应对象获取字节流并响应给浏览器
        ServletOutputStream os = response.getOutputStream();
        int len = 0;
        byte[] bytes = new byte[1024 * 8];
        while ((len = is.read(bytes)) != -1){
            os.write(bytes,0,len);
            os.flush();
        }
        is.close();
        os.close();
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        this.doPost(request, response);
    }
}

4. 案例:写一个验证码给网页
(1)Servlet代码

@WebServlet(name = "CheckCodeServlet", value = "/checkcode")
public class CheckCodeServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //创造图片
        int width = 100;
        int height = 60;
        BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
        //美化图片
        Graphics graphics = image.getGraphics();  //获取画笔
        graphics.setColor(Color.PINK);   //设置颜色
        graphics.fillRect(0,0,width,height);   //填充背景
        graphics.setColor(Color.blue);   //设置颜色
        graphics.drawRect(0,0,width-1,height-1);  //画边框
        //生成随机验证码
        String str = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghigklmnopqrstuvwxyz0123456789";
        graphics.setColor(Color.cyan);
        graphics.setFont(new Font("宋体",Font.PLAIN,30));
        Random random = new Random();
        for (int i = 1; i <= 4; i++) {
            int index = random.nextInt(str.length());
            char c = str.charAt(index);
            graphics.drawString(c+"",(width/5)*i,height/2);
        }
        //画干扰线
        graphics.setColor(Color.YELLOW);
        for (int i = 0; i < 10; i++) {
            int x1 = random.nextInt(width);
            int x2 = random.nextInt(width);
            int y1 = random.nextInt(height);
            int y2 = random.nextInt(height);
            graphics.drawLine(x1,y1,x2,y2);
        }
        //响应图片
        ImageIO.write(image,"png",response.getOutputStream());
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        this.doPost(request, response);
    }
}

(2)页面代码

<%--
  Created by IntelliJ IDEA.
  User: wzr
  Date: 2020/11/15
  Time: 14:38
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
    <div align="center">
        <form action="/1115/#" method="get">
            用户名<input type="text" name="username">
            <br>
            密码<input type="password" name="password">
            <br>
            验证码<input type="text" name="check">
            <br>
            <img src="/1115/checkcode" id="checkCode" onclick="change()">
            <br>
            <a href="javascript:void(0)" onclick="change()">看不清,换一张</a>
            <br>
            <input type="submit" value="提交">
        </form>
    </div>
</body>
</html>
<script>
    var change = function () {
        var img = document.getElementById("checkCode");
        //拼接一个随机参数,让服务器每次都响应
        img.src = "/1115/checkcode?time=" + new Date().getTime();
    }
</script>

2. 请求对象request

1. 原理
(1)request请求对象,里面封装了请求的信息
2. 获取请求行信息

	GET /MyServlet/index.jsp?name=zhangsan&age=23  HTTP/1.1
1. request.getMethod();//获取请求方式
2. request.getContextPath();//获取项目名称
3. request.getRequestURI();//获取URI
4. request.getRequestURL();//获取URL
5. request.getRemoteAddr();//获取IP地址 
6. request.getQueryString();//获取请求参数(GET)
7. request.getProtocol();//获取协议版本
@WebServlet(name = "ServletDemo04", value = "/demo04")
public class ServletDemo04 extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //http://localhost:8080/1115/demo04?username=zhangsan&password=123456

        //1. request.getMethod();//获取请求方式
        String method = request.getMethod();
        System.out.println(method);   //GET
        //2. request.getContextPath();//获取项目名称(上下文路径)
        String contextPath = request.getContextPath();
        System.out.println(contextPath);   // /1115
        //3. request.getRequestURI();//获取URI
        String requestURI = request.getRequestURI();
        System.out.println(requestURI);   //  /1115/demo04
        //4. request.getRequestURL();//获取URL
        StringBuffer requestURL = request.getRequestURL();
        System.out.println(requestURL);   //http://localhost:8080/1115/demo04
        //5. request.getRemoteAddr();//获取IP地址
        String remoteAddr = request.getRemoteAddr();
        System.out.println(remoteAddr);   //0:0:0:0:0:0:0:1
        //6. request.getQueryString();//获取请求参数
        String queryString = request.getQueryString();
        System.out.println(queryString);   //username=zhangsan&password=123456
        //如果请求参数中有中文:String decode = URLDecoder.decode(queryString, "utf-8")

        //7. request.getProtocol();//获取协议版本
        String protocol = request.getProtocol();
        System.out.println(protocol);    //HTTP/1.1
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        this.doPost(request, response);
    }
}

3. 获取请求头信息

1. request.getHeader("user-agent");//获取请求头的值
2. request.getHeader("Referer");//获取来访者地址
@WebServlet(name = "ServletDemo05", value = "/demo05")
public class ServletDemo05 extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //1. request.getHeader("user-agent");//获取请求头的值
        String userAgent = request.getHeader("User-Agent");
        System.out.println(userAgent);   //Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:82.0) Gecko/20100101 Firefox/82.0
        //2. request.getHeader("Referer");//获取来访者地址
        String referer = request.getHeader("Referer");
        System.out.println(referer);   //null
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        this.doPost(request, response);
    }
}

4. 获取请求体信息
(1)请求体:用于封装POST请求的请求参数
(2)方法

1. 获取字符数据:getReader();返回一个高效的字符流。我们通过一次读取一行的方法来获取请求参数数据,然后拆分字符串获取我们想要的数据
2. 获取字节数据:getInputStream(); 后期上传文件时讲解
@WebServlet(name = "ServletDemo06", value = "/demo06")
public class ServletDemo06 extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        BufferedReader reader = request.getReader();
        String s = reader.readLine();
        System.out.println(s);  //name=zhangsan&pwd=12345

    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        this.doPost(request, response);
    }
}

5. 通用的方式获取请求参数

1. request.getParameter(name):通过请求参数的名称来获取值
2. request.getParameterValues(name):通过请求参数的名称,来获取值的数组,一般用于复选框
3. request.getParameterMap():获取所有参数的map集合
【注意】 
	1. tomcat 8.0 以上GET请求的中文参数不乱码,tomcat已经处理了,我们不用处理	
	2. POST请求特有的方式处理中文乱码:request.setCharacterEncoding("utf-8");
<%--
  Created by IntelliJ IDEA.
  User: wzr
  Date: 2020/11/15
  Time: 15:42
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
<div align="center">
    <form action="/1115/demo07" method="post">
        用户名<input type="text" name="username">
        <br>
        密码<input type="password" name="password">
        <br>
        爱好<<br>
        篮球<input type="checkbox" name="hobby" value="lq">
        足球<input type="checkbox" name="hobby" value="zq">
        排球<input type="checkbox" name="hobby" value="pq">
        <input type="submit" value="提交">
    </form>
</div>
</body>
</html>

=======================================================================================

@WebServlet(name = "ServletDemo07", value = "/demo07")
public class ServletDemo07 extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //1. request.getParameter(name):通过请求参数的名称来获取值
        String username = request.getParameter("username");
        System.out.println(username);   //zhangsan
        String password = request.getParameter("password");
        System.out.println(password);   //123456

        //2. request.getParameterValues(name):通过请求参数的名称,来获取值的数组,一般用于复选框
        String[] hobbies = request.getParameterValues("hobby");
        System.out.println(Arrays.toString(hobbies));   //[zq, pq]

        //3. request.getParameterMap():获取所有参数的map集合
        Map<String, String[]> parameterMap = request.getParameterMap();
        System.out.println(parameterMap);   //org.apache.catalina.util.ParameterMap@782f1fa
        Set<Map.Entry<String, String[]>> entries = parameterMap.entrySet();
        for (Map.Entry<String, String[]> entry : entries) {
            String key = entry.getKey();
            String[] value = entry.getValue();
            System.out.println(key + "-->" + Arrays.toString(value));
        }
        /**
         * username-->[zhangsan]
         * password-->[123456]
         * hobby-->[zq, pq]
         */

    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        this.doPost(request, response);
    }
}

6. 请求转发
(1)请求转发与重定向的比较

1. 请求转发
	1. 一次请求一次响应
	2. 地址栏不发生变化
	3. 只能访问内部站点资源
	4. 可以访问WEB-INF下的资源
2. 重定向
	1. 两次请求两次响应
	2. 地址栏发生变化
	3. 即能访问内部站点资源,又可以访问外部站点资源
	4. 不能访问WEB-INF下的资源

在这里插入图片描述
(2)方法

request.getRequestDispatcher("/xxxxx").forward(request, response)
@WebServlet(name = "ServletA", value = "/a")
public class ServletA extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        System.out.println("A收到了请求");
        System.out.println("下来给B");
        request.getRequestDispatcher("/b").forward(request,response);
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        this.doPost(request, response);
    }
}

=======================================================================================

@WebServlet(name = "ServletB", value = "/b")
public class ServletB extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        System.out.println("B收到了请求");
        System.out.println("下来给C");
        request.getRequestDispatcher("/c").forward(request,response);

    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        this.doPost(request, response);
    }
}

=======================================================================================

@WebServlet(name = "ServletC", value = "/c")
public class ServletC extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        System.out.println("C收到了请求");
        System.out.println("下来给WEB-INF下的D");
        request.getRequestDispatcher("/WEB-INF/D.jsp").forward(request,response);

    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        this.doPost(request, response);
    }
}

=======================================================================================

<%--
  Created by IntelliJ IDEA.
  User: wzr
  Date: 2020/11/15
  Time: 16:08
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
<h1>D.jsp</h1>
</body>
</html>

7. ServletRequest域对象
(1)ServletRequest也是一个域对象,称为请求域
(2)范围:一次请求和响应的范围

@WebServlet(name = "ServletDemo08", value = "/demo08")
public class ServletDemo08 extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        request.setAttribute("name","zhangsan");
        //内部转发
        request.getRequestDispatcher("/demo09").forward(request,response);
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        this.doPost(request, response);
    }
}

=======================================================================================

@WebServlet(name = "ServletDemo09", value = "/demo09")
public class ServletDemo09 extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        String name = (String) request.getAttribute("name");
        System.out.println(name);  //zhangsan
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        this.doPost(request, response);
    }
}

3. 关于路径的书写

1. 请求转发不需要写上下文路径
2. 项目中页面路径和重定向路径,需要加上上下文路径
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值