欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Request

程序员文章站 2022-03-13 23:30:56
...

Request

1.HttpServletRequest对象
在Servlet API中,定义了一个HttpServletRequest接口,它继承自ServletRequest接口,专门用来封装HTTP请求消息。由于HTTP请求消息分为请求行、请求消息头和请求消息体三部分,因此,在HttpServletRequest接口中定义了获取请求行、请求头和请求消息体的相关方法。

2.获取请求行信息的相关方法
当访问Servlet时,会在请求消息的请求行中,包含请求方法、请求资源名、请求路径等信息,为了获取这些信息,在HttpServletRequest接口中,定义了一系列用于获取请求行的方法,如下所示。
Request

@WebServlet(name = "RequestLineServlet",urlPatterns = "/requestLine")
public class RequestLineServlet extends HttpServlet {
  public void doGet(HttpServletRequest request,
           HttpServletResponse response)throws IOException {
    response.setContentType("text/html;charset=utf-8");
    PrintWriter out = response.getWriter();
    // 获取请求行的相关信息
 response.setContentType("text/html;charset=utf-8");
    PrintWriter out = response.getWriter();
  
    out.println("getURL : " + request.getRequestURL()+"<br/>");
    out.println("getScheme: " + request.getScheme()+"<br/>");
    out.println("getServerName: " + request.getServerName() + "<br/>");
    out.println("getServerPort: " + request.getServerPort()+"<br/>");
    out.println("getURI : " + request.getRequestURI()+"<br/>");
    out.println("getContextPath: " + request.getContextPath()+"<br/>");
    out.println("getServletPath: " + request.getServletPath()+"<br/>");
    out.println("getQueryString: " + request.getQueryString()+"<br/>");
    out.println("===================================<br/>");
    out.println("getMethod: " + request.getMethod()+"<br/>");
    out.println("===================================<br/>");
    out.println("getProtocol: " + request.getProtocol()+"<br/>");
    out.println("===================================<br/>");
    out.println("getRemoteAddr: " + request.getRemoteAddr()+"<br/>");
    out.println("getRemoteHost: " + request.getRemoteHost()+"<br/>");
    out.println("getRemotePort: " + request.getRemotePort()+"<br/>");
    out.println("getLocalAddr: " + request.getLocalAddr()+"<br/>");
    out.println("getLocalName: " + request.getLocalName()+"<br/>");
out.println("getLocalPort: " + request.getLocalPort()+"<br/>");
  }
  public void doPost(HttpServletRequest request,
            HttpServletResponse response)throws ServletException,
IOException {
    doGet(request, response);
  }
}

3.获取请求头信息的相关方法
当请求Servlet时,需要通过请求头向服务器传递附加信息,例如,客户端可以接收的数据类型,压缩方式,语言等等。为此,在HttpServletRequest接口中,定义了一系列用于获取HTTP请求头字段的方法,如表所示。

Request

package hm01_request;

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.io.PrintWriter;
import java.util.Enumeration;

/*

 请求行 :
 请求网址:http://localhost:8080/web10/req?name=jay
 请求方法:GET
 版本:HTTP/1.1

 请求头 :  键值对形式提交 , 浏览器发送 , 不同键表示不同含义.

Host: localhost:8080  [请求的服务器主机名]
User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:66.0) Gecko/20100101 Firefox/66.0 [客户端浏览器与操作系统相关信息]
Accept: text/html,application/xhtml+xml,application/xml;q=0.9, * / *;q=0.8
Accept-Language: zh-CN,zh;q=0.7,en-US;q=0.3
Accept-Encoding: gzip, deflate
Connection: keep-alive
Cookie: JSESSIONID=81171565BD6F3D522CEF1B4767C2554F; Idea-68280b0=38d88edf-afc4-40e4-9c11-79743f1df182
Upgrade-Insecure-Requests: 1


POST 提交 :
请求行与 头就基本与 GET一致 .
只不过参数的部分 保存 请求体中 . 格式 : name=admin&password=superbaby
 */
@WebServlet(urlPatterns = "/req3")
public class Req3Servlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request, response);
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
         // 解析请求头
        String host = request.getHeader("host");
        System.out.println(host);

        // 获取所有的头的键   --  返回枚举类型 .
        Enumeration<String> names = request.getHeaderNames();

        //  枚举类型的遍历   - 枚举 就相当于你学的迭代器 .

        while (names.hasMoreElements()) {    // hasMoreElements  -->  hasNext
            String s = names.nextElement();  // nextElement      -->  next
            System.out.println(s);

            // 获取 值
            String value = request.getHeader(s);
            System.out.println(s +" -- " + value);
        }
    }
}

4.获取请求参数
在实际开发中,经常需要获取用户提交的表单数据,例如,用户名、密码、电子邮件等,为了方便获取表单中的请求参数,在HttpServletRequest接口中,定义了一系列获取请求参数的方法,如表所示。

Request
5.解决请求参数的中文乱码问题
在填写表单数据时,难免会输入中文,如姓名、公司名称等。由于HTML设置了浏览器在传递请求参数时,采用的编码方式是UTF-8,但在解码时采用的是默认的ISO8859-1,因此会导致乱码的出现。

在HttpServletRequest接口中,提供了一个setCharacterEncoding()方法,该方法用于设置request对象的解码方式。

package hm02_Attribute;

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(urlPatterns = "/ch")
public class ChinaServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request, response);
    }
    /*
      获取请求中的中文数据.

     GET 方式请求: 自动处理 tomcat8特性.
     POST 方式 :  依然乱码 . 通过
     setCharacterEncoding 设置编码

     */
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // 获取 参数前 ,设置请求对象中编码
        request.setCharacterEncoding("utf-8");
        // 设置 回写的编码
        response.setContentType("text/html;charset=utf-8");

        String name = request.getParameter("name");

        System.out.println(name);

        response.getWriter().println(name);




    }
}

6.Request对象保存数据
Request对象不仅可以获取一系列数据,还可以通过属性传递数据。在ServletRequest接口中,定义了一系列操作属性的方法,具体如下:

setAttribute()方法
该方法用于将一个对象与一个名称关联后存储进ServletRequest对象中,其完整语法定义如下:
public void setAttribute(java.lang.String name,java.lang.Object o);
需要注意的是,如果ServletRequest对象中已经存在指定名称的属性,setAttribute()方法将会先删除原来的属性,然后再添加新的属性。如果传递给setAttribute()方法的属性值对象为null,则删除指定名称的属性,这时的效果等同于removeAttribute()方法。

getAttribute()方法
该方法用于从ServletRequest对象中返回指定名称的属性对象,其完整的语法定义如下:
public java.lang.String getAttribute (java.lang.String name);

removeAttribute()方法
该方法用于从ServletRequest对象中删除指定名称的属性,其完整的语法定义如下:
public void removeAttribute(java.lang.String name);

getAttributeNames()方法
该方法用于返回一个包含ServletRequest对象中的所有属性名的Enumeration对象,在此基础上,可以对ServletRequest对象中的所有属性进行遍历处理。getAttributeNames()方法的完整语法定义如下:
public java.util.Enumeration getAttributeNames();

7.RequestDispatcher对象的应用
RequestDispatcher接口
当一个Web资源收到客户端的请求后,如果希望服务器通知另外一个资源去处理请求,这时,除了使用sendRedirect()方法实现请求重定向外,还可以通过RequestDispatcher接口的实例对象来实现。在ServletRequest接口中定义了一个获取RequestDispatcher对象的方法,如表所示。
Request
获取到RequestDispatcher对象后,最重要的工作就是通知其它Web资源处理当前的Servlet请求,为此,在RequestDispatcher接口中,定义了两个相关方法,如所示。
Request
列举的两个方法中,forward()方法可以实现请求转发,include()方法可以实现请求包含,关于请求转发相关知识,将在下面的小节中进行详细讲解。
请求包含:就是将当前页面和被包含页面的输出结果,合并一起响应给浏览器。

8.请求转发
在Servlet中,如果当前Web资源不想处理请求时,可以通过forward()方法将当前请求传递给其它的Web资源进行处理,这种方式称为请求转发。为了更好地理解使用forward()方法实现请求转发的工作原理,接下来通过一张图来描述,如图所示。

Request
Request

package hm02_Attribute;

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(urlPatterns = "/a")
public class AServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request, response);
    }
    /*
      请求 转发:
      getRequestDispatcher : 获取转发器 , 参数地址 , 不需要添加 项目的名称 , 直接填写 资源路径即可.

     */
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //  使用 request 保存 数据  .
        request.setAttribute("name" , "tom");


        // 转发 到  BServlet  中

        // 1. 获取转发器
        RequestDispatcher rd = request.getRequestDispatcher("/b");

        // 2. 发送 (走你)
        rd.forward(request ,response);


    }
}
package hm02_Attribute;

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(urlPatterns = "/b")
public class BServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request, response);
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        System.out.println("BServlet.doGet");

        // 获取request 对象 保存数据
        Object name = request.getAttribute("name");

        // 回写到页面
        response.getWriter().println(name);

    }
}

9.重定向和转发的区别
Request
重定向的地址栏会发生变化,转发的地址栏不变.
重定向两次请求两次响应,转发一次请求一次响应.
重定向路径需要加工程名,转发的路径不需要加工程名.
重定向可以跳转到任意网站,转发只能在服务器内部进行转发.