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():获取所有的请求头名称(迭代器原理)

@WebServlet("/requestDemo2")
public class requestDemo2 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //演示获取请求头数据
        //1.获取所有请求头名称
        Enumeration<String> headerNames = request.getHeaderNames();
        //2.遍历
        while (headerNames.hasMoreElements()) {
            String name = headerNames.nextElement();
            //根据名称获取请求头的值
            String value = request.getHeader(name);
            System.out.println(name + "---" + value);
        }
    }
        @Override
        protected void doPost (HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            super.doPost(request, response);
        }
    }

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

public class requestDemo3 extends HttpServlet {
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //演示获取请求头数据:user-agent
        String agent = request.getHeader("user-agent");
        //判断agent的浏览器版本
        if(agent.contains("Chrome")){
            //谷歌
            System.out.println("谷歌");
        }else if(agent.contains("Firefox")){
            //火狐
            System.out.println("火狐");
        }
    }
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    }
}

 案例:Referer防盗链

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

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>播放电影</title>
</head>
<body>
<a href = "/reStart/requestDemo4">播放电影</a>
</body>
</html>

3)创建一个播放类

@WebServlet("/requestDemo4")
public class requestDemo4 extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    }
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //演示获取请求头数据:referer
        String referer = request.getHeader("referer");
        System.out.println(referer);//http://localhost/day14/login.html
        //防盗链
        if(referer != null ){
            if(referer.contains("/reStart")){
                //正常访问
                // System.out.println("播放电影....");
                response.setContentType("text/html;charset=utf-8");
                response.getWriter().write("播放电影....");
            }else{
                //盗链
                //System.out.println("想看电影吗?来优酷吧...");
                response.setContentType("text/html;charset=utf-8");
                response.getWriter().write("想看电影吗?来优酷吧...");
            }
        }
    }
}

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<String,String[]> getParameterMap():获取所有参数的map集合

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

代码: 

     public class requestDemo5 extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //设置流的编码--解决post中文乱码问题
        request.setCharacterEncoding("utf-8");
        //根据参数名称获取参数值
        String username = request.getParameter("username");
        System.out.println("post");
        System.out.println(username);

        //根据参数名称获取参数值的数组
        String[] hobbies = request.getParameterValues("hobby");
        for (String hobby : hobbies) {
            System.out.println(hobby);
        }

        //获取所有请求的参数名称
        Enumeration<String> parameterNames = request.getParameterNames();
        while (parameterNames.hasMoreElements()) {
            String name = parameterNames.nextElement();
            System.out.println(name);
            String value = request.getParameter(name);
            System.out.println(value);
            System.out.println("----------------");
        }

        // 获取所有参数的map集合
        Map<String, String[]> parameterMap = request.getParameterMap();
        //遍历
        Set<String> keyset = parameterMap.keySet();
        for (String name : keyset) {

            //获取键获取值
            String[] values = parameterMap.get(name);
            System.out.println(name);
            for (String value : values) {
                System.out.println(value);
            }

            System.out.println("-----------------");
        }

    }

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

 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
 

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值