HttpServletRequest接口:
在Servlet API中,ServletRequest接口被定义为用于封装请求的信息,ServletRequest对象由Servlet容器在用户请求Servlet时创建并传入Servlet的service()方法中。HttpServletRequest接口继承了ServletRequest接口,是专用于HTTP协议的子接口,用于封装HTTP请求信息。在HttpServlet类的service()方法中,传入的ServletRequest对象被强制转换为HttpServletRequest对象来进行HTTP请求信息的处理。
请求报文格式
请求方法 URL 协议版本
头部字段名:值
......
头部字段名:值
(空行)
请求正文
1.获取请求行信息
getMethod():获取请求使用的HTTP方法,如POST,GET getRequestURI():获取请求行中的资源名部分 getProtocol():获取使用的协议及版本号,如HTTP/1.1 getQueryString():获取请求URL后面的查询字符串,只对GET有效 getServletPath():获取Servlet所映射的路径 getContextPath():获取请求资源所属于的web应用的路径
例如:http://localhost:8080/JavaWeb/HttpServletRequestTest1?name=abc&password=123
servlet如下:
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html;charset=utf-8"); PrintWriter out = response.getWriter(); //获取访问使用的方法 out.println(request.getMethod()+"<br/>"); //获取请求行中的资源名部分 out.println(request.getRequestURI()+"<br/>"); //获取使用的协议及版本号,如HTTP/1.1 out.println(request.getProtocol()+"<br/>"); //getQueryString():获取请求URL后面的查询字符串,只对GET有效 out.print(request.getQueryString()+"<br/>"); //getServletPath():获取Servlet所映射的路径 out.println(request.getServletPath()+"<br/>"); //getContextPath():获取请求资源所属于的web应用的路径 out.println(request.getContextPath()+"<br/>"); }
结果:
GET /JavaWeb/HttpServletRequestTest1 HTTP/1.1 name=abc&password=123 /HttpServletRequestTest1 /JavaWeb
2.获取请求头信息
getIntHeader(String name):获取整数类型参数名为name的http头部 getDateHeader(String name):获取long类型参数名为name的http头部 getContextLength():获取请求内容的长度,以字节为单位 getContextType():获取请求的文档类型和编码 getLocale():获得用户浏览器设置的Locale信息 getCookies():获取一个Cookie[]数组,该数组包含这个请求中当前的所有cookie常见请求头:
请求头名称 | 说明 |
Host | 初试URL中的主机和端口。可以通过它可以得好主机名称和端口号 |
Connection | 表示是否需要持久连接。若值为Keep-Alive或使用http1.1(默认持久连接),则可以持久连接,当页面元素多的时可以减少下载时间 |
Content-Length | 表示消息正文的长度。 |
Cache-Control | 指定请求和响应的缓存机制。如no-cache,则请求和响应消息不能缓存 |
Accept | 浏览器可以接受的MIME类型。 |
Origin | 用来说明最初请求是从哪里发起。只适用于POST |
User-Agent | 浏览器相关信息。如浏览器类型及版本号、浏览器语言、客户的操作系统和版本 |
Accept-Encoding | 浏览器可以进行解码的数据编码方式 |
Accept-Charset | 浏览器可接受的字符集 |
Content-Type | 表示请求内容的MIME内容。Servlet默认为text/plain,但是通常在servlet中都要手动设置为text/html |
Referer | 包括一个url,表示从哪个地址出发访问到当前请求地址的 |
Accept-Language | 浏览器所希望的语言种类 |
Cookie | 表示客户端的Cookie信息 |
代码演示:
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html;charset=utf-8"); PrintWriter out = response.getWriter(); out.println("请求头Host的信息:"+request.getHeader("Host")+"<br/>"); out.println("请求头Content-Length的信息:"+request.getIntHeader("Content-Length")+"<br/>"); out.println("请求头If-Modified-Since的信息:"+request.getDateHeader("If-Modified-Since")+"<br/>"); out.println("请求内容的长度:"+request.getContentLength()+"<br/>"); out.println("请求的文档类型定义:"+request.getLocale()+"<br/>"); out.println("请求的Cookie数组对象:"+request.getCookies()+"<br/>"); Enumeration<String> headernames = request.getHeaderNames(); while(headernames.hasMoreElements()) { String name = headernames.nextElement(); out.println(name + ":" + request.getHeader(name)+"<br/>"); } out.flush(); out.close(); }
结果:
请求头Host的信息:localhost:8080 请求头Content-Length的信息:-1 请求头If-Modified-Since的信息:-1 请求内容的长度:-1 请求的文档类型定义:zh_CN 请求的Cookie数组对象:null host:localhost:8080 connection:keep-alive cache-control:max-age=0 upgrade-insecure-requests:1 user-agent:Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.79 Safari/537.36 accept:text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8 accept-encoding:gzip, deflate, br accept-language:zh-CN,zh;q=0.9
3.获取请求正文
请求正文内容为POST请求参数名称和值组成的一个字符串。POST请求主要通过form表单进行数据提交,而<form>表单元素的enctype属性可以指定两种编码方式,默认使用的是application/x-www-form-urlencoded。在这种情况下,浏览器提交表单的时候会将元素名和元素值以“=”分隔形成一个参数,每个参数之间以&分隔组成正文内容。
在Servlet中可以使用:getParameter(String name),getParameterNames(),getParameterValues(String name),getParametrerMap()等方法获取参数名和参数值。
当表单想服务器上传文件时enctype使用的是multipart/form-data。其编码方式的请求正文由描述头、空行和主体内容三部分组成,非文件类型元素的主体内容就是表单设置的值,文件类型的主体内容文文件的二进制数据形式。
在Servlet中可以使用:getInputStream(),getReader等方法进行获取。同时@MultiPartConfig注解方式也有方法提供。
4.请求参数的中文问题
在表单以POST提交的时候,浏览器按照当前页面的字符集对请求的中文数据进行编码,然后以报文本方式传递个Tomcat服务器,服务器端servlet在调用HttpServletRequest的getParameter()传递参数时,会以该对象的getCharacterEncoding(),返回的字符集进行解码,如果不适用setCharacterEncoding(charset)进行编码设置的话,服务器会默认使用iso-8859-1字符集进行解码,该字符集不包含中文,会出现中文参数乱码问题。
因此在调用参数之前,先写上一句
request.serCharacterEncoding("utf-8");
如果是GET请求,也可能出现乱码问题。比如jsp页面的字符集编码是GB2312。根据EFC1738规定,url中只有字母和数字以及一些特殊符号和保留字才可以不经编码直接使用于url,所以参数为中文的时候必须被浏览器进行编码后才能发给服务器。所以在jsp中可以进行如下设置
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Insert title here</title> </head> <body> </body> </html>
另外在jsp中对于超链接也可以进行编码设置
<a href="test.jsp?name=<%=java.net.URLEncoder.encode("张三","utf-8")%>"/>
当服务器发送的内容和浏览器端不同时候,可以在server.xml中配置Connector元素
<Connector connectionTimeout="2000" port = "8080" protocol="HTTP/1.1" redirectPort="8443" URLEncoding = "UTF-8"/>
或者
<Connector connectionTimeout="2000" port = "8080" protocol="HTTP/1.1" redirectPort="8443" useBodyEncodingForURI="true"/>
由于不同版本的服务器默认的字符集编码不同,所以应尽量避免使用GET请求来传递中文参数。
5.获取网络连接信息
getRemoteAddr():获取请求用户的ip地址 getRemoteHost():获取请求用户的主机名 getRemotePort():获取请求用户使用的端口号 getLocalAddr():获取web服务器的ip地址 getLocalName():获取web服务器的主机名 getLocarPort():获取web服务器使用的端口号 getServerName():获取网站的域名 getServerPort():获取url请求的端口号 getScheme():获取请求使用的协议 getRequestURL:获取请求的url地址
代码:
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html;charset=utf-8"); PrintWriter out = response.getWriter(); out.print("获取请求用户的ip地址"+request.getRemoteAddr()+"<br/>"); out.print("获取请求用户的主机名"+request.getRemoteHost()+"<br/>"); out.print("获取请求用户使用的端口号"+request.getRemotePort()+"<br/>"); out.print("获取web服务器的ip地址"+request.getLocalAddr()+"<br/>"); out.print("获取web服务器的主机名"+request.getLocalName()+"<br/>"); out.print("获取web服务器使用的端口号"+request.getLocalPort()+"<br/>"); out.print("获取网站的域名"+request.getServerName()+"<br/>"); out.print("获取url请求的端口号"+request.getServerPort()+"<br/>"); out.print("获取请求使用的协议"+request.getScheme()+"<br/>"); out.print("获取请求的url地址"+request.getRequestURL()+"<br/>"); out.flush(); out.close(); }
结果:
获取请求用户的ip地址0:0:0:0:0:0:0:1 获取请求用户的主机名0:0:0:0:0:0:0:1 获取请求用户使用的端口号4857 获取web服务器的ip地址0:0:0:0:0:0:0:1 获取web服务器的主机名0:0:0:0:0:0:0:1 获取web服务器使用的端口号8080 获取网站的域名localhost 获取url请求的端口号8080 获取请求使用的协议http 获取请求的url地址http://localhost:8080/JavaWeb/HttpServletRequestTest3
6.存取请求域属性
void setAttribute(String name, Object value):设定name的属性值为value,保存在request范围内 Object getAttribute(String name):从request范围了获取name属性的值 void removeAttribute(String name):从request范围移除name属性的值 Enumeration getAttributeNames():获取所有request范围的属性