HttpServletRequest
HttpServletRequest
简介:
HttpServletRequest 对象代表客户端的请求,当客户端通过HTTP协议访问服务器时,HTTP请求头中的所有信息都封装在这个对象中,通过这个对象提供的方法,可以获得客户端请求的所有信息,包括请求的地址,请求的参数,提交的数据,上传的文件客户端的 ip甚至客户端操作系统 都包含在其内。java中HttpServletRequest专门处理GET/POST请求。
HTTP请求协议
- a.请求地址(URL)
- b.请求头(Request headers)
- c.实体数据(Entity body)
//HTTP 1.1协议信息
POST /examples/default.jsp HTTP/1.1
Accept: text/plain; text/html
Accept-Language: en-gb
Connection: Keep-Alive
Host: localhost
User-Agent: Mozilla/4.0 (compatible; MSIE 4.01; Windows 98)
Content-Length: 33
Content-Type: application/x-www-form-urlencoded
Accept-Encoding: gzip, deflate
lastName=Franks&firstName=Michael
HttpServletRequest封装了所有的http头部信息,java中就可以通过这个类很容易获取。
常用方法如下:
1. 获得客户端信息
getMethod //返回HTTP请求消息中的请求方式。 getRequestURI //返回请求行中的资源名部分。 getQueryString //返回请求行中的参数部分。 getProtocol //返回请求行中的协议名和版本。 getContextPath //返回请求资源所属于的WEB应用程序的路径。 getPathInfo //返回请求URL中的额外路径信息。额外路径信息是请求URL中的位于Servlet的路径之后和查询参数之前的内容,它以“/”开头。 getPathTranslated //返回URL中的额外路径信息所对应的资源的真实路径。 getServletPath //返回Servlet的名称或Servlet所映射的路径。获取网络连接信息 getRemoteAddr //返回发出请求的客户机的IP地址,其格式为“192.168.0.3”这种形式的字符文本。 (*) getRemoteHost //返回发出请求的客户机的完整主机名,即“pc1.it315.org”这种格式。 getRemotePort //返回发出请求的客户机所使用的网络接口的端口号。 getLocalAddr //返回WEB服务器上接收当前请求的网络接口的IP地址。 getLocalName //返回WEB服务器上接收当前请求的网络接口的IP地址所对应的主机名。 getLocalPort //返回WEB服务器上接收当前请求的网络接口的端口号。 getServerName //返回当前请求所指向的主机名。 getServerPort //返回当前请求所连接的服务器端口号。 getScheme //返回请求的协议名,例如http、https或ftp。 getRequestURL //返回客户端发出请求时的完整URL。
2. 获得客户端机器请求头部信息
getHeader(string name) //返回String
getHeaders(String name) //返回Enumeration
getHeaderNames方法
getIntHeader方法
getDateHeader方法
getContentType方法
getContentLength方法
getCharacterEncoding方法
3. 常用的方法
String getMethod() 返回这个请求使用的HTTP方法(例如:GET、POST、PUT)
String getQueryString() 返回这个请求URL所包含的查询字符串。一个查询字串符在一个URL中由一个“?”代表。
String getRequestURI() 返回请求的路径
HttpSession getSession() 返回一个当前有效的session
String getParameter(String key) 是从Get或者Post提交的数据中获取数据
setAttribute(String name,Object o) 将数据作为request对象的一个属性存放到request对象中,例如:request.setAttribute("data", data);
getAttribute(String name) 返回获取request对象的name属性的属性值或是session内存在的对象尤服务器端设置,例如:request.getAttribute("data")
removeAttribute(String name) 移除request对象的name属性,例如:request.removeAttribute("data")
getAttributeNames 获取request对象的所有属性名,返回的是一个,例如:EnumerationattrNames = request.getAttributeNames();
String getHeader("referer") 则是获取上一次请求的url
4. 获得客户请求参数(客户端提交的数据)
getParameter(String)(常用)
getParameterValues(String name)(常用)
getParameterNames()(不常用)
getParameterMap()(编写框架时常用)
HttpServletRequest请求转发(服务器端跳转forward)
在Servlet中请求转发是大量要使用的,因为当我们访问一个Servlet的时候通常会执行一些后台的业务逻辑,然后跳转到一个结果页面,那么跳转到结果页面的这个过程就是请求转发,举个例子我们做登录的功能,我们填写用户名密码然后提交到一个负责登录的Servlet,Servlet为我们做用户名和密码的校验,如果我们都正确的话,我们就要跳转到登录的提示页面,如果错误就要跳转到登录失败的页面。
Request的请求转发也可以叫做服务器端的跳转,虽然有页面的跳转但是我们会发现地址栏是不会有变化的。
request.getRequestDispatcher("/success.html").forward(request, response);
HttpServletRequest获取上传的文件
// 获取上传的文件对象
Part part = request.getPart("file");
// 获取上传的文件名字
String fileName = part.getSubmittedFileName();
// 获取输入流
InputStream ins = part.getInputStream();
// 获取上传的contentType
String contentType = part.getContentType();
//获取上传的文件的大小
long size = part.getSize();
GET/POST请求
1、他们都可以向服务器发送数据,Get是从服务器上获取数据,Post则是传输数据给服务器进行增删改等操作。
2、GET提交,请求的数据会附在URL之后(就是把数据放置在HTTP协议头中),以?分割URL和传输数据,多个参数用&连接;例如:login.action?name=hyddd&password=idontknow&verify=%E4%BD%A0 %E5%A5%BD。如果数据是英文字母/数字,原样发送,如果是空格,转换为+,如果是中文/其他字符,则直接把字符串用BASE64加密,得出如: %E4%BD%A0%E5%A5%BD,其中%XX中的XX为该符号以16进制表示的ASCII。
3、POST提交:把提交的数据放置在是HTTP包的包体中。上文示例中红色字体标明的就是实际的传输数据 。因此,GET提交的数据会在地址栏中显示出来,而POST提交,地址栏不会改变
4、Get限制form表单数据必须为ASCII字符,而Post支持整个ISO10646字符集
注意事项
1. 如果提交FORM表单的页面与处理表单请求的Servlet程序都是由同一个人或同一个项目组开发的,那么只要在处理表单提交的Servlet程序中将传递给setCharacterEncoding方法的字符集编码设置为该表单所在页面的字符集编码即可。
2. 如果Servlet程序可以接收来自多个其他站点的FORM表单提交的数据,而每个其他站点的页面所采用的字符集编码可能各不一样,要想让Servlet程序知道FORM表单内容的字符集编码,可以在FORM表单中增加一个隐藏字段来传递当前FORM内容的字符集编码名称。
3. 只要超链接、FORM表单的action属性设置、请求转发和重定向的URL等任何一种请求路径中要包含参数,就必须对参数部分进行URL编码。对参数进行URL编码时所选择的字符集编码应尽量与当前页面的字符集编码保持一致,也可以用一个参数来指定URL编码内容的字符集编码名称。
4. 所有标准的浏览器和客户机终端都支持UTF-8编码,如果WEB服务器要能兼容处理各个国家和地区版本的浏览器所传递的FORM表单信息,网页文档应当使用UTF-8编码格式。
5. 在编写应用程序时应该注意一些隐性的字符编码错误。有些程序在输出时有编码转换错误,在读取输入时返回的字符串也有转换错误,当该程序输出它所读取到的有问题的字符串时,显示的结果可能是正常的中文字符
6. HttpServletRequest对象处理所有客户端请求的数据是最重要的java类之一,一定要重点学好。
HttpServletRequest方法详解
1、HttpServletRequest获取所有参数
HttpServletRequest获取所有参数有以下2种方法:
1. request.getParameterNames()
该方法获取所有参数名称列表,得到枚举类型的参数名称,参数名称若有重复的只能得到第一个,示例如下:
private Map showParams(HttpServletRequest request) {
Map map = new HashMap();
Enumeration paramNames = request.getParameterNames();
while (paramNames.hasMoreElements()) {
String paramName = (String) paramNames.nextElement();
String[] paramValues = request.getParameterValues(paramName);
if (paramValues.length == 1) {
String paramValue = paramValues[0];
if (paramValue.length() != 0) {
map.put(paramName, paramValue);
}
}
}
return map;
}
2. request.getParameterMap()
该方法返回一个Map类型的值,该返回值记录着前端(如jsp页面)所提交请求中的请求参数和请求参数值的映射关系。这个返回值有个特别之处——只能读。
//获取request对象
HttpServletRequest request = ServletActionContext.getRequest();
Map<String,String[]> map=request.getParameterMap();
//遍历
for(Iterator iter=map.entrySet().iterator();iter.hasNext();){
Map.Entry element=(Map.Entry)iter.next(); //key值
Object strKey = element.getKey(); //value,数组形式
String[] value=(String[])element.getValue();
System.out.print(strKey.toString() +"=");
for(int i=0;i<value.length;i++){
System.out.print(value[i]+",");
}
System.out.println();
}
2、HttpServletRequest获取URL(参数,路径,端口号,协议等)详解
HttpServletRequest获取URL常用方法如下:
假设客户端请求的地址url:http://localhost:8082/TestReq/MyServlet/username=51gjie&age=20
//客户请求求的URL,不包括参数数据
request.getRequestURL //返回http://localhost:8082/TestReq/MyServlet
//将URL的域名和尾随的参数截取掉,剩下的那部分就是URI
request.getRequestURI //返回/TestReq/MyServlet
//返回URL上的参数部分的字符串,必须是GET的请求才有效,不然报错
request.getQueryString //返回username=51gjie&age=20
//返回请求的方案名,如http,ftp,https等
request.getScheme //返回http
//HTTP请求的的方法名,默认是GET,也可以指定PUT或POST
request.getMethod //返回GET
//即斜杆加工程名
request.getContextPath //返回/TestReq
//服务器主机名
request.getServerName //返回localhost
//服务器上web应用的访问端口
request.getServerPort request.getLocalPort //返回8082
//返回请求的协议名和版本,如HTTP/1.1等
request.getProtocol //返回HTTP/1.1
//工程部署的完整路径字符串接上参数中的字符串
request.getRealPath("/WEB-INF") //返回d:\omc_jboss\server\default\.\deploy\TestReq.war\WEB-INF
//工程之后到参数之前的这部分字符串
request.getServletPath //返回/MyServlet
//字符串包含与客户端发送请求的URL相关的额外信息
request.getPathInfo //返回null
//请求URL体内容的长度,只对POST和PUT类型的请求有效
request.getContentLength //返回-1
//返回一个表示在服务器文件系统上的PathInfol转换成路径的字符串
request.getPathTranslated //返回null
3、HttpServletRequest获取真实IP地址(无视代理)详解
HttpServletRequest获取IP地址(无代理)
//获取发送请求的客户端主机的IP
request.getRemoteAddr //返回127.0.0.1
HttpServletRequest获取真实IP地址(代理)
如果通过Apache,Squid等反向代理软件就不能获取到客户端的真实IP地址了。如果使用了反向代理软件,用 request.getRemoteAddr()方法获取的IP地址是代理的IP,而并不是客户端的真实IP。获取真实IP有如下2种方法:
//获取真实IP一
public String getRemortIP(HttpServletRequest request) {
if (request.getHeader("x-forwarded-for") == null) {
return request.getRemoteAddr();
}
return request.getHeader("x-forwarded-for");
}
//获取真实IP二
public String getRemoteHost(javax.servlet.http.HttpServletRequest request){
String ip = request.getHeader("x-forwarded-for");
if(ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)){
ip = request.getHeader("Proxy-Client-IP");
}
if(ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)){
ip = request.getHeader("WL-Proxy-Client-IP");
}
if(ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)){
ip = request.getRemoteAddr();
}
return ip.equals("0:0:0:0:0:0:0:1")?"127.0.0.1":ip;
}
4、HttpServletRequest获取GET请求参数5种方法
HttpServletRequest获取HTTP GET请求过来的字符串有如下5种方式:
4.1、request.getQueryString()
获取到完整的GET请求字符串(userName=51gjie&password=123456),然后解析字符串
4.2、request.getReader()
BufferedReader reader = request.getReader();
String par = reader.readLine() ; //userName=51gjie&password=123456
和上面一样,获取到完整的GET请求字符串,然后解析字符串
4.3、request.getParameter(key)
Enumeration names = request.getParameterNames();
while(names.hasMoreElements()){
String name = (String) names.nextElement();
String value = request.getParameter(name);
System.out.println(name+"---"+value);
}
Enumeration getParameterNames()获取所有的请求参数的名称
String getParameter(String name)根据名称获取对应的请求参数的值
4.4、request.getParameterMap()
Map<string,string[]> map = request.getParameterMap();
Set<entry<string, string[]="">> entrySet = map.entrySet();
for (Entry<string, string[]=""> entry : entrySet) {
String key = entry.getKey();
String[] value = entry.getValue();
System.out.println(key + "----" + Arrays.toString(value));
}
Map<String , String[]> getParameterMap()获取所有的请求参数对应的Map集合, 键是请求参数的名称 ,值是请求参数的值
4.5、@RequestParam
@RequestMapping(value = "/testurl", method = RequestMethod.GET)@ResponseBody
public ServiceResult TestUrl(HttpServletRequest request,@RequestParam("username")String username,
@RequestParam("pwd")String pwd) {
String txt = username + pwd;
}
controller中直接获取到GET字符串里面的参数。
Spring MVC中可以直接通过方法中的变量获取到GET请求的参数信息。
5、HttpServletRequest获取POST请求参数 3 种方法
客户端通过HTTP POST多参数字符串,比如(username=51gjie&pwd=123456789),HttpServletRequest 获取到POST的参数有如下3种方法:
5.1、request.getInputStream()
private static String getPostData(HttpServletRequest request) {
StringBuffer data = new StringBuffer();
String line = null;
BufferedReader reader = null;
try {
reader = request.getReader();
while (null != (line = reader.readLine()))
data.append(line);
} catch (IOException e) {
} finally {
}
return data.toString();
}
获取到POST过来的信息(username=51gjie&pwd=123456789),后面直接解析字符串就好了。
request.getInputStream()执行一次后(可正常读取body数据),之后再执行就无效了。
5.2、@RequestBody
@RequestMapping(value = "/testurl", method = RequestMethod.POST)
@ResponseBody
public ServiceResult TestUrl(HttpServletRequest request,
@RequestBody JSONObject jsonObject){
String username = jsonObject.get("username").toString();
String pwd = jsonObject.get("pwd").toString();
}
@RequestBody 可以使用JSONObject, Map ,或者ObjectDTO绑定body。
5.3、@RequestParam
@RequestMapping(value = "/testurl", method = RequestMethod.POST)
@ResponseBody
public ServiceResult TestUrl(HttpServletRequest request,@RequestParam("username")String username,
@RequestParam("pwd")String pwd) {
String txt = username + pwd;
}