Request
Request
1.HttpServletRequest对象
在Servlet API中,定义了一个HttpServletRequest接口,它继承自ServletRequest接口,专门用来封装HTTP请求消息。由于HTTP请求消息分为请求行、请求消息头和请求消息体三部分,因此,在HttpServletRequest接口中定义了获取请求行、请求头和请求消息体的相关方法。
2.获取请求行信息的相关方法
当访问Servlet时,会在请求消息的请求行中,包含请求方法、请求资源名、请求路径等信息,为了获取这些信息,在HttpServletRequest接口中,定义了一系列用于获取请求行的方法,如下所示。
@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请求头字段的方法,如表所示。
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接口中,定义了一系列获取请求参数的方法,如表所示。
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对象的方法,如表所示。
获取到RequestDispatcher对象后,最重要的工作就是通知其它Web资源处理当前的Servlet请求,为此,在RequestDispatcher接口中,定义了两个相关方法,如所示。
列举的两个方法中,forward()方法可以实现请求转发,include()方法可以实现请求包含,关于请求转发相关知识,将在下面的小节中进行详细讲解。
请求包含:就是将当前页面和被包含页面的输出结果,合并一起响应给浏览器。
8.请求转发
在Servlet中,如果当前Web资源不想处理请求时,可以通过forward()方法将当前请求传递给其它的Web资源进行处理,这种方式称为请求转发。为了更好地理解使用forward()方法实现请求转发的工作原理,接下来通过一张图来描述,如图所示。
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.getSession().getServletContext().getRealPath("upload/" ); 获取不到 tomcat 服务器目录
-
PHP fastcgi_finish_request 方法
-
Request获取Session的方法总结
-
request.getParameter()取值为null的解决方法
-
通过过滤器(Filter)解决JSP的Post和Request中文乱码问题
-
JSP利用过滤器解决request中文乱码问题
-
微信小程序 request接口的封装实例代码
-
php错误提示failed to open stream: HTTP request failed!的完美解决方法
-
修改MaxFieldLength与MaxRequestBytes彻底解决Request Too Long的问题
-
使用python的request库爬取某小说书网站