Servlet Request经常使用方法

接下来记录一下Servlet Request和Response的经常使用API,以及乱码问题。html

Request

Request即HttpRequest,能够获取客户端相关的信息、获取请求头以及获取请求参数等。java

获取客户端相关的信息

常使用的API有以下web

(1)getRequestURL方法 -- 返回客户端发出请求完整URL
(2)getRequestURI方法 -- 返回请求行中的资源名部分
(3)getQueryString方法 -- 返回请求行中的参数部分
(4)getRemoteAddr方法 -- 返回发出请求的客户机的IP地址
(5)getMethod -- 获得客户机请求方式
(6)getContextPath -- 得到当前web应用虚拟目录名称 -- 在写路径时不要将web应用的虚拟路径的名称写死, 应该在须要写web应用的名称的地方经过getContextPath方法动态获取api

代码数组

 1 package com.boe.request;  2 
 3 import javax.servlet.ServletException;  4 import javax.servlet.annotation.WebServlet;  5 import javax.servlet.http.HttpServlet;  6 import javax.servlet.http.HttpServletRequest;  7 import javax.servlet.http.HttpServletResponse;  8 import java.io.IOException;  9 
10 /**
11  * 获取客户端相关信息 12  */
13 @WebServlet("/RequestDemo1") 14 public class RequestDemo1 extends HttpServlet { 15 
16     protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { 17         /*getRequestURL方法 -- 返回客户端发出请求完整URL 18  getRequestURI方法 -- 返回请求行中的资源名部分 19  getQueryString方法 -- 返回请求行中的参数部分 20  getRemoteAddr方法 -- 返回发出请求的客户机的IP地址 21  getMethod -- 获得客户机请求方式 22  getContextPath -- 得到当前web应用虚拟目录名称 -- 在写路径时不要将web应用的虚拟路径的名称写死, 应该在须要写web应用的名称的地方经过getContextPath方法动态获取*/
23 
24         //url
25         StringBuffer requestURL = request.getRequestURL(); 26         System.out.println("url:"+requestURL);//统一完整路径名,包括协议,虚拟主机和资源,url:http://localhost/day09-reqres/RequestDemo1
27         //uri
28         String uri=request.getRequestURI(); 29         System.out.println("uri:"+uri);// 统一资源路径名 uri:/day09-reqres/RequestDemo1 30         //queryString
31         String qs=request.getQueryString(); 32         System.out.println("qs:"+qs); 33         //ip
34         String addr = request.getRemoteAddr();//alt+shift+L,能够默认提示变量名
35         System.out.println("addr:"+addr);//addr:127.0.0.1 36         //method
37         String method = request.getMethod(); 38         System.out.println(method);//GET 39         //contextpath
40         String contextPath = request.getContextPath(); 41         System.out.println(contextPath);///day09-reqres 会动态变化,万分注意!
42  } 43 
44     protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { 45  doPost(request, response); 46  } 47 }

访问后控制台浏览器

获取请求头信息

上面是获取客户端信息的相关api,这个是获取请求头的api,就F12 request请求内容比较多的那一部份内容里的信息,它经常使用的方法以下。缓存

(1)getHeader(name)方法 --- String
(2)getHeaders(String name)方法 --- Enumeration<String>
(3)getHeaderNames方法 --- Enumeration<String>
(4)getIntHeader(name)方法 --- int
(5)getDateHeader(name)方法 --- long(日期对应毫秒)tomcat

代码部分服务器

 1 package com.boe.request;  2 
 3 import javax.servlet.ServletException;  4 import javax.servlet.annotation.WebServlet;  5 import javax.servlet.http.HttpServlet;  6 import javax.servlet.http.HttpServletRequest;  7 import javax.servlet.http.HttpServletResponse;  8 import java.io.IOException;  9 import java.util.Enumeration; 10 
11 /**
12  * 获取请求头的信息 13  */
14 @WebServlet("/RequestDemo2") 15 public class RequestDemo2 extends HttpServlet { 16     protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { 17         /*name getHeader(name)方法 --- String 18  getHeaders(String name)方法 --- Enumeration<String> 19  getHeaderNames方法 --- Enumeration<String> 20  getIntHeader(name)方法 --- int 21  getDateHeader(name)方法 --- long(日期对应毫秒)*/
22 
23         //获取请求头名称为host的请求头中包含的信息
24         String host = request.getHeader("host"); 25         System.out.println("host:"+host); 26         System.out.println("-------------分割线-------------"); 27         //获取请求头名称为host的请求头们中包含的信息,返回一个枚举类型
28         Enumeration<String> hosts = request.getHeaders("host"); 29         while(hosts.hasMoreElements()){ 30             String s = hosts.nextElement(); 31             System.out.println("hosts value:"+s); 32  } 33         System.out.println("-------------分割线-------------"); 34         //获取所有请求头的名称
35         Enumeration<String> headerNames = request.getHeaderNames(); 36         while(headerNames.hasMoreElements()){ 37             String head = headerNames.nextElement(); 38             String value=request.getHeader(head); 39             System.out.println("head:"+head+", "+"value:"+value); 40  } 41         System.out.println("-------------分割线-------------"); 42  } 43 
44     protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { 45  doPost(request, response); 46  } 47 }

访问后控制台输出效果session

web中实际信息

能够看出,代码中获取的内容和网页中的信息一致。

获取请求参数

可使用request获取请求参数,这个比较经常使用,如获取用户登陆的用户名和密码等,经常使用的方法以下。

(1)getParameter(String name) --- String 经过name得到值
(2)getParameterValues(String name) --- String[ ] 经过name得到多值 checkbox
(3)getParameterMap() --- Map<String,String[ ]> key :name value: 多值 将查询的参数保存在一个Map中
(5)getParameterNames() --- Enumeration<String> 得到全部name

提交参数分为POST和GET提交的方式,这里先准备一个页面进行测试,所以须要Servlet的代码和html的代码。

html页面

 1 <!DOCTYPE html>
 2 <html>
 3     <head>
 4         <meta charset="utf-8" /><!---->
 5     </head>
 6     <body>
 7         <h1>GET提交</h1>
 8         <form action="/day09-reqres/RequestDemo3" method="GET">
 9             用户名: <input type="text" name="username" />
10             昵称: <input type="text" name="nickname" />
11             <input type="submit" value="提交" />
12         </form>
13         <h1>POST提交</h1>
14         <form action="/day09-reqres/RequestDemo3" method="POST">
15             用户名: <input type="text" name="username" />
16             昵称: <input type="text" name="nickname" />
17             爱好: <input type="checkbox" name="like" value="lanqiu" />篮球 18                 <input type="checkbox" name="like" value="zuqiu" />足球 19                 <input type="checkbox" name="like" value="taiqiu" />台球 20             <input type="submit" value="提交" />
21         </form>
22     </body>
23 </html>

servlet代码

 1 package com.boe.request;  2 
 3 import com.sun.scenario.effect.impl.sw.sse.SSEBlend_SRC_OUTPeer;  4 
 5 import javax.servlet.ServletException;  6 import javax.servlet.annotation.WebServlet;  7 import javax.servlet.http.HttpServlet;  8 import javax.servlet.http.HttpServletRequest;  9 import javax.servlet.http.HttpServletResponse; 10 import java.io.IOException; 11 import java.util.Arrays; 12 import java.util.Enumeration; 13 import java.util.Map; 14 
15 //请求参数相关的api
16 @WebServlet("/RequestDemo3") 17 public class RequestDemo3 extends HttpServlet { 18     protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { 19         /*getParameter(String name) --- String 经过name得到值 20  getParameterValues(String name) --- String[ ] 经过name得到多值 checkbox 21  getParameterMap() --- Map<String,String[ ]> key :name value: 多值 将查询的参数保 22  存在一个Map中 23  getParameterNames() --- Enumeration<String> 得到全部name*/
24 
25         //获取单个参数值
26         String encoding = request.getCharacterEncoding(); 27         System.out.println("服务器默认使用字符集"+encoding); 28         //设置字符集为utf-8 ,只对post请求有效 29         //request.setCharacterEncoding("utf-8");
30         System.out.println("设置完成以后的字符集"+request.getCharacterEncoding()); 31 
32         String method = request.getMethod(); 33         if("GET".equals(method)){ 34             System.out.println("GET请求"); 35             //getBytes先编码,能够指定系统的字符集,执行后返回一个byte[]数组 36             //new String后解码,需传入byte[]数组,以及解码字符集
37             String user=new String(request.getParameter("username").getBytes("iso-8859-1"),"utf-8"); 38             String nickname=new String(request.getParameter("nickname").getBytes("iso-8859-1"),"utf-8"); 39             System.out.println("user:"+user+":nickname:"+nickname); 40  } 41 
42 
43         String user = request.getParameter("username"); 44         String nickname = request.getParameter("nickname"); 45         System.out.println("user:"+user+":nickname:"+nickname); 46 
47         //获取多个参数值,如checkbox
48         String[] likes = request.getParameterValues("like"); 49  System.out.println(Arrays.toString(likes)); 50 
51         //返回全部的key value,name包括username,nickname和like
52         Map<String, String[]> parameterMap = request.getParameterMap(); 53 
54         //获得所有请求参数
55         Enumeration<String> parameterNames = request.getParameterNames(); 56         while(parameterNames.hasMoreElements()){ 57             String name=parameterNames.nextElement();//获取参数的名字
58             String parameter = request.getParameter(name);//这个只能拿到一个参数,若是有多个只能拿一个
59             System.out.println("name="+name+",value="+parameter); 60             //获取多个参数
61             String[] parameters = request.getParameterValues(name); 62             System.out.println("name="+name+",value="+Arrays.toString(parameters)); 63  } 64 
65  } 66 
67     protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { 68  doPost(request, response); 69  } 70 }

准备好后,开始测试。

(1)POST提交

能够看到POST提交英文是没有任何问题的,而且注意request.getParameter方法一次只能返回有一个参数,就算这个属性有多个参数也只能返回一个。须要返回多个参数时使用getParameterValues方法。

若是是提交中文,request的请求body里是有中文显示的,可是到了服务端获取后,中文部分就变成了乱码。 

web页面正常显示

查看html代码部分,meta标签里charset属性是utf-8,表明浏览器使用utf-8来打开页面,浏览器使用什么编码格式打开浏览器,再发送数据到服务器(这里是tomcat服务器)的时候就默认使用什么编码格式发送,所以浏览器发送的是utf-8,这个是能够正常携带中文信息的,可是tomcat默认的解码格式是iso-8859-1,所以首先编解码格式不一致会形成乱码,另一方面由于iso-8859-1由于没法表示中文,也将显示乱码。

要想解决这个办法,可使用request.setCharacterEncoding方法来解决,可是这个须要写到获取参数以前,修改后继续提交中文发现编码字符集变成了utf-8,而且能够正常解码中文。

(2)GET请求

GET请求的话比较特殊,它的请求参数跟POST请求提交的不太同样,是在请求行里的 ,所以出现乱码解决的方式也有区别,仍是在上面代码的基础上进行测试。

若是提交的是英文,正常提交没问题。

web页面中请求参数是在请求行里的。

若是提交的是中文,在注释掉new String部门代码,并保留request.setCharacterEncoding代码,发现依然显示乱码。

提交显示乱码

而且web端request里内容不是中文,而是16进制的形式表示。说明request.setCharacterEncoding设置的编码格式,对请求行没有效果,GET请求处理服务端乱码须要使用另一种方式,即须要上面红色方框的内容,即系统默认是iso-8859-1接受数据那就按照它来编码变成字节数组,而后将字节数组再使用utf-8来解码变成字符。

 

这样设置后继续提交中文,发现服务端能够正常得到。

请求转发

请求转发,是使用RequestDispatcher资源调度,将请求从当前资源交给下一个资源处理,下一个资源能够是servlet,也能够是JSP。转发的过程当中,只有一次请求和一次响应,而且地址不变。下面使用三个servlet,来感觉如下请求转发的特色。

准备了RequestDemo4~6,具体代码以下,在使用的过程当中部分代码须要修改。

RequestDemo4

 1 package com.boe.request;  2 
 3 import javax.servlet.RequestDispatcher;  4 import javax.servlet.ServletException;  5 import javax.servlet.annotation.WebServlet;  6 import javax.servlet.http.HttpServlet;  7 import javax.servlet.http.HttpServletRequest;  8 import javax.servlet.http.HttpServletResponse;  9 import java.io.IOException; 10 
11 /**
12  * 重定转发,和RequestDemo5一组 13  */
14 @WebServlet("/RequestDemo4") 15 public class RequestDemo4 extends HttpServlet { 16     protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { 17         //建立调度器
18         RequestDispatcher dispatcher = request.getRequestDispatcher("/RequestDemo5"); 19         response.getWriter().write("this is demo4");//请求转发前,向response缓冲区中写入数据,请求转发时,会将response缓冲区清空一次 20 
21         //response.flushBuffer();//会报错,提示IllegalStateException: Cannot forward after response has been committed,默认提交
22         /**
23  * public void flushBuffer() throws java.io.IOException 24  * 强行将缓冲区中的全部内容写入客户端。调用此方法会自动提交响应,这意味着将编写状态代码和头。后面再次转发会失败 25          */
26 
27         //利用调度器完成转发 28         //不容许屡次转发,可是能够多重转发,能够转发到demo5,接着demo6这种
29         System.out.println("这是demo4"); 30  dispatcher.forward(request,response); 31         //request.getRequestDispatcher("index.jsp").forward(request,response);
32         System.out.println("demo4转发完成"); 33  } 34 
35     protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { 36  doPost(request, response); 37  } 38 }
View Code

RequestDemo5

 1 package com.boe.request;  2 
 3 import javax.servlet.RequestDispatcher;  4 import javax.servlet.ServletException;  5 import javax.servlet.annotation.WebServlet;  6 import javax.servlet.http.HttpServlet;  7 import javax.servlet.http.HttpServletRequest;  8 import javax.servlet.http.HttpServletResponse;  9 import java.io.IOException; 10 
11 /**
12  * 重定转发,和RequestDemo4一组 13  */
14 @WebServlet("/RequestDemo5") 15 public class RequestDemo5 extends HttpServlet { 16     protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { 17         //response.getWriter().write("this is demo5");
18         RequestDispatcher dispatcher = request.getRequestDispatcher("RequestDemo6"); 19         System.out.println("这是demo5"); 20  dispatcher.forward(request,response); 21         System.out.println("demo5转发完成"); 22  } 23 
24     protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { 25  doPost(request, response); 26  } 27 }
View Code

RequestDemo6

 1 package com.boe.request;  2 
 3 import javax.servlet.ServletException;  4 import javax.servlet.annotation.WebServlet;  5 import javax.servlet.http.HttpServlet;  6 import javax.servlet.http.HttpServletRequest;  7 import javax.servlet.http.HttpServletResponse;  8 import java.io.IOException;  9 
10 @WebServlet("/RequestDemo6") 11 public class RequestDemo6 extends HttpServlet { 12     protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { 13         System.out.println("这是demo6"); 14         response.getWriter().write("<h1 style='font:微软雅黑;color:blue'>this is demo6</h1>"); 15         System.out.println("demo6完成输出"); 16  } 17 
18     protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { 19  doPost(request, response); 20  } 21 }
View Code

(1)正常转发,将response.flushBuffer先注释掉,控制台和web端显示以下。

能够看到能够多重转发,请求链能够在多个资源上传递,而且从控制台输出顺序,能够看到转发代码部分执行完成以后,才执行转发代码以后的代码,所以''demo04转发完成''最后输出。

最后输出'this is demo6',而刚开始RequestDemo4中的输出被覆盖了。说明在转发前往response缓存中写入的数据,在转发后会被清空

 

(2) response.flushBuffer取消注释,继续测试,发现控制台会报错。提示IllegalStateException: Cannot forward after response has been committed,而且提示在第30行出现问题,第30行是转发的代码,为啥这里不能转发了呢?其实就是flushBuffer的缘由,它会在转发前将写入response中的缓存强行提交发送给浏览器,所以下面再次转发就不能够了。所以若是在转发前response缓冲区中就有内容提交了给了浏览器,转发会失败

(3)测试demo4中转发给demo05后又转发给jsp,即测试屡次转发,发现报错内容跟上面同样,也是提示IllegalStateException: Cannot forward after response has been committed,所以一个请求也不能屡次转发

域对象

request能够做用域对象使用,所谓域对象就是有一个能够看到的范围,而且在这个范围内经过map能够共享资源。request就是一种域对象,此外还有其余几种域对象,如servletContext、session和pageContext。经过往域对象中设置值,能够在域对象的范围内都能被访问到,这里使用request,就能在整条访问链上都能获得存入的数据。

RequestDemo08的代码,用于发送数据。

 1 package com.boe.request;  2 
 3 import javax.servlet.ServletException;  4 import javax.servlet.annotation.WebServlet;  5 import javax.servlet.http.HttpServlet;  6 import javax.servlet.http.HttpServletRequest;  7 import javax.servlet.http.HttpServletResponse;  8 import java.io.IOException;  9 
10 /**
11  * 做为域对象使用-在一个范围内共享数据,这里使用的域对象就是request 12  */
13 @WebServlet("/RequestDemo8") 14 public class RequestDemo8 extends HttpServlet { 15     protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { 16         //向域中设置数据
17         request.setAttribute("name","clyang"); 18         request.getRequestDispatcher("/RequestDemo9").forward(request,response); 19  } 20 
21     protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { 22  doPost(request, response); 23  } 24 }

RequestDemo09的代码,用于接收数据。

 1 package com.boe.request;  2 
 3 import javax.servlet.ServletException;  4 import javax.servlet.annotation.WebServlet;  5 import javax.servlet.http.HttpServlet;  6 import javax.servlet.http.HttpServletRequest;  7 import javax.servlet.http.HttpServletResponse;  8 import java.io.IOException;  9 import java.util.Enumeration; 10 
11 /**
12  * 得到域数据 13  */
14 @WebServlet("/RequestDemo9") 15 public class RequestDemo9 extends HttpServlet { 16     protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { 17         //获取域属性
18         String name= (String) request.getAttribute("name"); 19         System.out.println("name="+name); 20         //获取域属性名字
21         Enumeration<String> attributeNames = request.getAttributeNames(); 22         while(attributeNames.hasMoreElements()){ 23             String s = attributeNames.nextElement(); 24             System.out.println("域属性的名字为:"+s); 25  } 26         response.getWriter().write("<h1 style='font:微软雅黑;color:blue'>"+name+"</h1>"); 27  } 28 
29     protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { 30  doPost(request, response); 31  } 32 }

控制台和web输出状况,能够看到转发后还能够经过request获取name的属性值,由于还在域的范围内,因此能够获取。

 request做用域的范围:一个请求链。

 request做用域的生命周期:一次请求开始到请求结束。

请求包含

请求包含指的是服务器内部实现资源合并的效果。若是浏览器请求ServletA,在A的内部能够经过request.getRequestDispatcher("B的虚拟路径").include(request, response)将ServletB包含进来,B处理的结果将会并入A处理的结果一块儿响应给浏览器,准备两个servlet,将数据合并后发送给浏览器。
 
RequestDemo11的代码
 1 package com.boe.request;  2 
 3 import javax.servlet.RequestDispatcher;  4 import javax.servlet.ServletException;  5 import javax.servlet.annotation.WebServlet;  6 import javax.servlet.http.HttpServlet;  7 import javax.servlet.http.HttpServletRequest;  8 import javax.servlet.http.HttpServletResponse;  9 import java.io.IOException; 10 
11 /**
12  * 请求包含 13  */
14 @WebServlet("/RequestDemo11") 15 public class RequestDemo11 extends HttpServlet { 16     protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { 17         //建立调度器
18         RequestDispatcher dispatcher = request.getRequestDispatcher("/RequestDemo12"); 19         response.getWriter().write("9999 from demo11 "); 20         //利用调度器完成请求包含
21  dispatcher.include(request,response); 22  } 23 
24     protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { 25  doPost(request, response); 26  } 27 }
RequestDemo12的代码
 1 package com.boe.request;  2 
 3 import javax.servlet.ServletException;  4 import javax.servlet.annotation.WebServlet;  5 import javax.servlet.http.HttpServlet;  6 import javax.servlet.http.HttpServletRequest;  7 import javax.servlet.http.HttpServletResponse;  8 import java.io.IOException;  9 
10 @WebServlet("/RequestDemo12") 11 public class RequestDemo12 extends HttpServlet { 12     protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { 13         response.getWriter().write(" 1 from demo12"); 14  } 15 
16     protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { 17  doPost(request, response); 18  } 19 }

测试结果,能够看到两次请求的内容会并到一块儿,发送给浏览器。

参考博文:

(1)http://www.javashuo.com/article/p-oxfvvfbb-cp.html

相关文章
相关标签/搜索