zoukankan      html  css  js  c++  java
  • Javaweb:Request和Response

    Http协议简介

    HTTP协议即超文本传输协议。是客户端和服务端交互时,数据的格式规范。分为HTTP请求和HTTP响应。

    • 浏览器向服务器请求某个web资源时,称之为浏览器向服务器发送了一个http请求。
    • 一个HTTP响应代表着服务器向浏览器回送数据。

    简单来说就是:请求:客户端发送给服务端的数据;响应:服务端发送给客户端的数据。

    请求和响应分为行,头,体。先有请求后有响应,没有请求就没有响应。

    HttpServletRequest

    概述

    HttpServletRequest对象代表客户端的请求,当客户端通过HTTP协议访问服务器时,HTTP请求头中的所有信息都封装在这个对象中,开发人员通过这个对象的方法,可以获得客户这些信息。

    request就是将请求文本封装而成的对象,所以通过request能获得请求文本中的所有内容,请求头、请求体、请求行

    一个请求的例子:

    请求行、请求头、请求体

    请求行

    • 本次请求的基本信息
    • 格式:请求方式 请求资源 协议版本
    • 例如POST /day29/demo01 HTTP/1.1

    请求头

    • 本次请求的附加信息
    • 格式:一行一个键值对,一个键值对是一个请求头,一次请求可以有多个请求头
    • 例如:Referer:http://localhost:8080/day29/_01http.html
    • 相关方法:
      • String getHeader(String name) 根据头名称得到头信息值
      • long getDateHeader(java.lang.String name) 获得指定头内容Date
      • int getIntHeader(java.lang.String name) 获得指定头内容int
      • Enumeration getHeaderNames() 得到所有头信息name
      • Enumeration getHeaders(String name) 根据头名称得到相同名称头信息值

    代码示例:

    Enumeration<String> headerNames = req.getHeaderNames();
            while(headerNames.hasMoreElements()){
                String key = (String)headerNames.nextElement();
                String value = req.getHeader(key);
                System.out.println(key+"="+value);
            } 
    

    请求体

    • 本次请求的正文数据,是提交的表单参数
    • 格式:表单数据的提交格式 name=value&name=value&…
    • 例如:username=lisi
    • 注意:只有是POST提交,必须有带name属性的表单项,这时候请求体里才有数据;否则没有请求体
    • 与表单获取相关的方法:
      • String getParameter(name) :根据表单中name属性的名,获取value属性的值方法
      • String[] getParameterValues(String name):专为复选框取取提供的方法
      • getParameterNames():得到表单提交的所有name的方法
      • Map<String , String[]> getParameterMap(): 得到表单提交的所有值的方法 //做框架用,非常实用
      • getInputStream: 以字节流的方式得到所有表单数据
    • 与操作非表单数据相关的方法(request也是一个域对象):
      • void setAttribute(String name, Object value);
      • Object getAttribute(String name);
      • Void removeAttribute(String name);
    • 与请求转发相关的方法:
      • RequestDispatcher getRequestDispatcher(String path) //得到请求转发或请求包含的协助对象
      • forward(ServletRequest request, ServletResponse response) //转发的方法
      • include(ServletRequest request, ServletResponse response) //请求包含
    • 与编码相关的方法:
      • 解决post方式编码
        • request.setCharacterEncoding("UTF-8") :告诉服务器客户端什么编码,只能处理post请求方式
      • 解决get方式编码
        • String name = new String(name.getBytes(“iso-8859-1”),”UTF-8”);

    补充:其他常用请求方法

    • getMethod();
    • getRequestURL();
    • getRequestURI();
    • getServerName();
    • getServerPort();
    • getContextPath();
    • getServletPath();
    • getQueryString();
    • getRemoteAddr();
    • getProtocol();

    示例:

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //1.统一资源标记符   /Web_Servlet/ServletTest3
        String uri = req.getRequestURI();
        System.out.println(uri);
        //2.统一资源定位符    http://localhost:6060/Web_Servlet/ServletTest3 
        StringBuffer url = req.getRequestURL();
        System.out.println(url);
        //3.协议和版本    HTTP/1.1
        String potocol = req.getProtocol();
        System.out.println(potocol);
        //4.协议    http
        String scheme = req.getScheme();
        System.out.println(scheme);
        //5.主机(域名)  localhost,如果你使用的是ip地址,就显示ip地址
        String serverName = req.getServerName();
        System.out.println(serverName);
        //6.端口  6060(这是我自己修改了的端口,默认是8080)
        int port = req.    getServerPort();
        System.out.println(port);
        //7.发布到tomcat下的项目名称  /Web_Servlet
        String contextPath = req.getContextPath();
        System.out.println(contextPath);
        //8.servlet路径    /ServletTest3 
        String servletPath = req.getServletPath();
        System.out.println(servletPath);
        //9.获取所有请求参数,即?之后所有东西。    username=faker&password=mid
        String queryString = req.getQueryString();
        System.out.println(queryString);
        //10.远程主机的ip地址    0:0:0:0:0:0:0:1
        String remoteAddr = req.getRemoteAddr();
        System.out.println(remoteAddr);   
    }
    

    总结几个常用的方法

    • 获取请求行的数据

      • 获取请求方式数据
        • 语法:Request对象.getMethod():
        • 方法返回对应的请求方式字符串 (常见的请求方式 get/post)
        • 一般默认请求方式都是get,只有指定了post才会有post请求。
      • 获取请求行中项目路径
        • 语法:Request对象.getContextPath();
        • 方法返回对应的项目路径字符串
      • 获取客户端IP
        • 语法:Request对象.getRemoteAddr();
        • 方法返回访问客户的IP地址
    • 获取请求头的数据

      • 获取指定请求头的值
        • 语法:Request.getHeader(键)
        • 在请求头中,数据以键值对的方式进行存储,传入键,获取值
      • 获取所有请求头的值
        • 语法:Request.getHeaderNames()
        • 以枚举对象的形式,返回所有请求头的值.
    • 获取请求体的数据

      • 获取单值参数:String value = request.getParameter(标签体的name属性)
      • 获取多值参数:String[] values = request.getParametreValues(标签体的name属性)
      • 获取所有参数:Map<String, String[]> map = request.getParameterMap()

    获取表单数据出现乱码的问题

    Get方式不会出现乱码,因为Tomcat 8版本以上的为我们解决了。

    Post方式则会出现乱码问题:一切乱码原因都是因为解码和编码方式不同

    • request默认采用iso-8859字符集解码,而我们的页面是utf-8字符集编码
    • 解决方法:修改解码方式,语法:Request.setCharacterEncoding(“utf-8”)
    • 注意:必须在接收参数之前执行

    request域对象的理解

    Request是域对象,由Servlet规范提供的,能够存取数据的对象,在其作用范围里可以共享数据。

    不同域对象的区别:作用范围不同

    域对象存取数据的方法:

    • 存数据:setAttribute(String name, Object value)
    • 取数据:getAttribute(String name)
    • 删数据:removeAttribute(String name)

    request域对象的作用范围:

    • 何时创建:一次请求开始
    • 何时销毁:一次请求结束
    • 作用范围:一次请求期间

    Request底层原理图

    HttpServletResponse

    概述

    Web服务器收到客户端的http请求,会针对每一次请求,分别创建一个用于代表请求的request对象、和代表响应的response对象。request和response对象即然代表请求和响应,那我们要获取客户机提交过来的数据,只需要找request对象就行了。要向容器输出数据,只需要找response对象就行了。
    HttpServletResponse对象代表服务器的响应。这个对象中封装了向客户端发送数据、发送响应头,发送响应状态码的方法。

    先看一个图片总览来对response建立印象

    Response响应数据

    如上图所示,我们能很快发现response的几个关键术语,比如响应头、响应体、状态码等

    在一个访问过程中我们可以看到如下图所示的响应信息:

    响应行的数据表示http协议版本为HTTP/1.1,状态码为200,这个状态码的描述是OK。

    关于响应状态码

    响应状态码:服务器告诉客户端(浏览器)本次请求和响应的一个状态

    状态码都是3位数字

    • 1xx:服务器接收客户端消息,但没有接收完成,等待一段时间以后,发送1xxx状态码
    • 2xx:成功,代表:200
    • 3xx:重定向,代表:302(重定向)304(访问缓存)
    • 4xx:客户端错误,代表404(请求路径中没有响应的资源)405(请求方式与处理方法没有对应)
    • 5xx:服务端错误,代表500(服务器内部错误)

    响应头中的数据

    • Content-Type: text/html —— 表示数据类型
    • Content-Length: 137 —— 表示数据长度
    • Date: Sun, 01 Mar 2020 10:19:50 GMT —— 日期

    可以对应上面的图片来查看响应头的相关信息。

    Response工作流程

    相关方法

    • setStatus(int sc) 设置响应状态码
    • setHeader(String name, String value) 设置响应头信息
    • getWrite(); 字符输出流
    • getOutputStream(); 字节输出流
    • setCharacterEncoding(String charset) 告知服务器使用什么编码
    • setContentType(String type) 告诉响应的内容类型(text/html,application/json等)

    题外话1:两种setCharacterEncoding

    request.setCharacterEncoding()指定后可以通过getParameter()则直接获得正确的字符串,如果不指定,则默认使用iso8859-1编码。值得注意的是在执行setCharacterEncoding()之前,不能执行任何getParameter()。而且,该指定只对POST方法有效,对GET方法无效。
    分析原因,应该是在执行第一个getParameter()的时候,Java将会按照编码分析所有的提交内容,而后续的getParameter()不再进行分析,所以setCharacterEncoding()无效。而对于GET方法提交表单是,提交的内容在URL中,一开始就已经按照编码分析提交内容,setCharacterEncoding()自然就无效。

    response.setCharacterEncoding设置HTTP 响应的编码,如果之前使用response.setContentType设置了编码格式,则使用response.setCharacterEncoding指定的编码格式覆盖之前的设置.与response.setContentType相同的是,调用此方法,必须在getWriter执行之前或者response被提交之前

    request和response经常会涉及到重定向和转发,将在下一个专题中提及。

  • 相关阅读:
    将训练好的Tensorflow模型部署到web应用中
    python pip升级
    python time
    python 队列模拟递归遍历目录(广度遍历)
    python 栈模拟递归遍历目录(深度遍历)
    python 递归遍历目录
    python 队列
    python 栈
    python 递归
    python 语音模块
  • 原文地址:https://www.cnblogs.com/kylinxxx/p/14234544.html
Copyright © 2011-2022 走看看