• Request和Response原理与详细运用


                1.先了解一下Request对象和Response对象的原理图解
                2. request对象继承体系结构:
                3. request功能:
                    1. 获取请求消息数据
                2.获取头数据
                    案例:User-agent(判断浏览器版本信息)
                    案例:Referer防盗链
                3. 获取请求体数据:
                其他功能
                    1.获取请求参数通用方式:
                    2.请求转发
                    3.数据共享
                4.response
                    4.1response对象的功能主要是:
                        (1)设置响应头信息
                        设置状态码
                            状态码
                        响应正文
                        重定向

    request和response有一些细节的东西有点遗忘了,从新回顾学习一遍。
    1.先了解一下Request对象和Response对象的原理图解
    request对象和response对象由服务器创建供给我们使用。

    前者获取请求方式,后者设置响应方式。
    2. request对象继承体系结构:

    ServletRequest        --    接口
        |    继承
    HttpServletRequest    -- 接口
        |    实现
    org.apache.catalina.connector.RequestFacade 类(tomcat)

    3. request功能:
    1. 获取请求消息数据

        1. 获取请求行数据
            * GET /demo1?name=zhangsan HTTP/1.1
            * 方法:
                1. 获取请求方式 :GET
                    * String getMethod()  
                2. (重点)获取虚拟目录:/虚拟路径
                    * String getContextPath()
                3. 获取Servlet路径: /demo1
                    * String getServletPath()
                4. 获取get方式请求参数:name=zhangsan
                    * String getQueryString()
                5. (重点)获取请求URI:/虚拟路径/demo1
                    * String getRequestURI():        /虚拟路径/demo1
                    * StringBuffer getRequestURL()  :http://localhost/demo1

                    * URL:统一资源定位符 : http://localhost/demo1                                   
                    * URI:统一资源标识符:   /demo1                                    
                6. 获取协议及版本:HTTP/1.1
                    * String getProtocol()

                7. 获取客户机的IP地址:
                    * String getRemoteAddr()

    2.获取头数据

        方法:
        (重点)String getHeader(String name):通过请求头的名称获取请求头的值
        Enumeration getHeaderNames():获取所有的请求头名称(迭代器原理)

    1. @WebServlet("/requestDemo2")
    2. public class requestDemo2 extends HttpServlet {
    3. @Override
    4. protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    5. //演示获取请求头数据
    6. //1.获取所有请求头名称
    7. Enumeration headerNames = request.getHeaderNames();
    8. //2.遍历
    9. while (headerNames.hasMoreElements()) {
    10. String name = headerNames.nextElement();
    11. //根据名称获取请求头的值
    12. String value = request.getHeader(name);
    13. System.out.println(name + "---" + value);
    14. }
    15. }
    16. @Override
    17. protected void doPost (HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    18. super.doPost(request, response);
    19. }
    20. }

    案例:User-agent(判断浏览器版本信息)

    1. public class requestDemo3 extends HttpServlet {
    2. protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    3. //演示获取请求头数据:user-agent
    4. String agent = request.getHeader("user-agent");
    5. //判断agent的浏览器版本
    6. if(agent.contains("Chrome")){
    7. //谷歌
    8. System.out.println("谷歌");
    9. }else if(agent.contains("Firefox")){
    10. //火狐
    11. System.out.println("火狐");
    12. }
    13. }
    14. protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    15. }
    16. }

     案例:Referer防盗链

    1.正版播放
    1)设置项目的虚拟路径为/reStart
    2)编写一个播放页面

    1. "en">
    2. "UTF-8">
    3. 播放电影
    4. <a href = "/reStart/requestDemo4">播放电影

    3)创建一个播放类

    1. @WebServlet("/requestDemo4")
    2. public class requestDemo4 extends HttpServlet {
    3. protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    4. }
    5. protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    6. //演示获取请求头数据:referer
    7. String referer = request.getHeader("referer");
    8. System.out.println(referer);//http://localhost/day14/login.html
    9. //防盗链
    10. if(referer != null ){
    11. if(referer.contains("/reStart")){
    12. //正常访问
    13. // System.out.println("播放电影....");
    14. response.setContentType("text/html;charset=utf-8");
    15. response.getWriter().write("播放电影....");
    16. }else{
    17. //盗链
    18. //System.out.println("想看电影吗?来优酷吧...");
    19. response.setContentType("text/html;charset=utf-8");
    20. response.getWriter().write("想看电影吗?来优酷吧...");
    21. }
    22. }
    23. }
    24. }

    3. 获取请求体数据:

        请求体:只有POST请求方式,才有请求体,在请求体中封装了POST请求的请求参数
        * 步骤:
        1. 获取流对象
        * BufferedReader getReader():获取字符输入流,只能操作字符数据
        * ServletInputStream getInputStream():获取字节输入流,可以操作所有类型数据

        再从流对象中拿数据

    其他功能
    1.获取请求参数通用方式:

    获取请求参数通用方式:不论get还是post请求方式都可以使用下列方法来获取请求参数

        String getParameter(String name):根据参数名称获取参数值 username=zs&password=123
        String[] getParameterValues(String name):根据参数名称获取参数值的数组 hobby=xx&hobby=game
        ---------通常是前端页面传来复选框数据,在Servlet里用此方法请求获得数据
        Enumeration getParameterNames():获取所有请求的参数名称
        Map getParameterMap():获取所有参数的map集合

        中文乱码问题:
        * get方式:tomcat 8 已经将get方式乱码问题解决了
        * post方式:会乱码
        * 解决:在获取参数前,设置request的编码request.setCharacterEncoding(“utf-8”);

    代码: 

    1. public class requestDemo5 extends HttpServlet {
    2. protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    3. //设置流的编码--解决post中文乱码问题
    4. request.setCharacterEncoding("utf-8");
    5. //根据参数名称获取参数值
    6. String username = request.getParameter("username");
    7. System.out.println("post");
    8. System.out.println(username);
    9. //根据参数名称获取参数值的数组
    10. String[] hobbies = request.getParameterValues("hobby");
    11. for (String hobby : hobbies) {
    12. System.out.println(hobby);
    13. }
    14. //获取所有请求的参数名称
    15. Enumeration parameterNames = request.getParameterNames();
    16. while (parameterNames.hasMoreElements()) {
    17. String name = parameterNames.nextElement();
    18. System.out.println(name);
    19. String value = request.getParameter(name);
    20. System.out.println(value);
    21. System.out.println("----------------");
    22. }
    23. // 获取所有参数的map集合
    24. Map parameterMap = request.getParameterMap();
    25. //遍历
    26. Set keyset = parameterMap.keySet();
    27. for (String name : keyset) {
    28. //获取键获取值
    29. String[] values = parameterMap.get(name);
    30. System.out.println(name);
    31. for (String value : values) {
    32. System.out.println(value);
    33. }
    34. System.out.println("-----------------");
    35. }
    36. }
    37. protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    38. this.doPost(request, response);
    39. }
    40. }

     2.请求转发:

        请求转发:一种在服务器内部的资源跳转方式(通常一个项目会由多个类来完成,会在类间转发)
        1. 步骤:
            通过request对象获取请求转发器对象:RequestDispatcher getRequestDispatcher(String path)
            使用RequestDispatcher对象来进行转发:forward(ServletRequest request, ServletResponse response)
            req.getRequestDispatcher(“路径”).forward(req,resp);
            特点:
            1. 浏览器地址栏路径不发生变化
            2. 只能转发到当前服务器内部资源中。
            3. 转发是一次请求
            这儿学习一下—请求转发和重定向区别:
            https://blog.csdn.net/u010452388/article/details/80398929

    3.数据共享

    共享数据:
    * 域对象:一个有作用范围的对象,可以在范围内共享数据(四大作用域这儿区别先不谈可以单独去了解)
    * request域:代表一次请求的范围,一般用于请求转发的多个资源中共享数据
    * 方法:
    1. void setAttribute(String name,Object obj):存储数据
    2. Object getAttitude(String name):通过键获取值
    3. void removeAttribute(String name):通过键移除键值对

    4.获取ServletContext:

        ServletContext getServletContext()

    4.response

          response是Servlet.service方法的一个参数,类型为javax.servlet.http.HttpServletResponse。在客户端发出每个请求时,服务器都会创建一个response对象,并传入给Servlet.service()方法。response对象是用来对客户端进行响应的,这说明在service()方法中使用response对象可以完成对客户端的响应工作。

    4.1response对象的功能主要是:

    (1)设置响应头信息

    (2)发送状态码

    (3)设置响应正文

    (4)重定向
    (1)设置响应头信息

    setHeader()方法
    (1)response.setHeader(“content-type”, “text/html;charset=utf-8”):设置content-type响应头,该头的作用是告诉浏览器响应内容为html类型,编码为utf-8。而且同时会设置response的字符流编码为utf-8,即response.setCharaceterEncoding(“utf-8”);

    (2)response.setHeader(“Refresh”,“5; URL=http://www.baidu.com”):5秒后自动跳转到百度主页。
    设置状态码

    response.setStatus(200):设置状态码;

    补充:
    状态码

    Response 消息中的第一行叫做状态行,由HTTP协议版本号, 状态码, 状态消息 三部分组成。

    状态码用来告诉HTTP客户端,HTTP服务器是否产生了预期的Response.

    HTTP/1.1中定义了5类状态码, 状态码由三位数字组成,第一个数字定义了响应的类别

    1XX 提示信息 - 表示请求已被成功接收,继续处理

    2XX 成功 - 表示请求已被成功接收,理解,接受

    3XX 重定向 - 要完成请求必须进行更进一步的处理

    4XX 客户端错误 - 请求有语法错误或请求无法实现

    5XX 服务器端错误 - 服务器未能实现合法的请求

    看看一些常见的状态码
    302 Found

    重定向,新的URL会在response 中的Location中返回,浏览器将会自动使用新的URL发出新的Request

    例如在IE中输入, http://www.google.com. HTTP服务器会返回302, IE取到Response中Location header的新URL, 又重新发送了一个Request.

    304 Not Modified

    代表上次的文档已经被缓存了, 还可以继续使用

    如果你不想使用本地缓存可以用Ctrl+F5 强制刷新页面

    400 Bad Request 客户端请求与语法错误,不能被服务器所理解

    403 Forbidden 服务器收到请求,但是拒绝提供服务

    404 Not Found

    请求资源不存在(输错了URL)

    比如在IE中输入一个错误的URL

    500 Internal Server Error 内部服务器错误

    503 Server Unavailable 服务器当前不能处理客户端的请求,一段时间后可能恢复正常
    200 OK

    最常见的就是成功响应状态码200了, 这表明该请求被成功地完成,所请求的资源发送回客户端
    响应正文

    esponse是响应对象,向客户端输出响应正文(响应体)可以使用response的响应流,repsonse一共提供了两个响应流对象:

    (1)PrintWriter out = response.getWriter():获取字符流;

    (2)ServletOutputStreamout = response.getOutputStream():获取字节流;

    乱码问题:
    1.请求转发虽然不能输出响应体,但还是可以设置响应头的,例如:response.setContentType(”text/html;charset=utf-8”);

    2.response.setCharacterEncoding(“utf-8”):设置字符响应流的字符编码为utf-8;
    重定向

    1.两次请求,客户端请求服务器的一个资源,服务器响应数据给客户端,客户端再次请求服务器的另一个资源。请求资源的地点变了,客户端访问地址也会改变的。
    2.重定向的状态码为302
     

  • 相关阅读:
    详解Mysql中redo log、undo log、bin log
    分布式训练框架
    Lua类型系统详解(一)
    apollo 8.0 系统安装与实践
    Java多线程(6):锁与AQS(下)
    JVM总结全
    后端Web开发之Maven
    触觉设备,临场感,预测控制,DOB
    蓝桥杯算法基础(38)c++ STL
    Allegro172版本DFM规则之DFT Mask和silkscreen
  • 原文地址:https://blog.csdn.net/qq_46084827/article/details/126852190