Servlet(2):Requset/Response Encoding and Filter

Requset/Response Encoding

表单提交分GET和POST,接下来分开讨论。

(1)GET/URL提交的数据

在 Tomcat中,默认情况下使用"URIEncoding"的值(tomcat8.0后是UTF-8,之前是ISO-8859-1)对URL提交的数据和表单中GET方式提交的数据进行解码。由于浏览器已经进行了一次编码(UTF-8),所以后台什么都不需要做。

 1     @Override
 2     protected void doGet(HttpServletRequest request, HttpServletResponse response)
 3             throws ServletException, IOException {
 4 
 5         // 不需要设置 request.setCharacterEncoding()
 6         // request.setCharacterEncoding("UTF-8");
 7         // 设置response的Character
 8         response.setContentType("text/html");
 9         response.setCharacterEncoding("UTF-8");
10         // 也可以直接写成
11         // response.setContentType("text/html;charset=UTF-8");
12     }

URIEncoding 是对所有 GET 方式的请求的数据进行统一的重新编码(解码),而 useBodyEncodingForURI 则是根据响应该请求的页面的request.setCharacterEncoding 参数对数据进行的重新编码(解码),不同的页面可以有不同的重新编码(解码)的编码。

所以,如果要修改编码格式,可以使用下面两个方法:

<Connector port="8080" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" URIEncoding="GBK" />
response.setContentType("text/html;charset=GBK");

<Connector port="8080" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" useBodyEncodingForURI="true" />
request.setCharacterEncoding("GBK");
response.setContentType("text/html;charset=GBK");

(2)POST提交的数据

由于"URIEncoding"只对GET方式有效,所以POST时必须设置request.setCharacterEncoding

request.setCharacterEncoding("UTF-8");
response.setContentType("text/html;charset=UTF-8");

(3)综合以上讨论,如果使用Tomcat8以上,UTF-8编码的项目,则不需要修改server.xml,再在每个servlet中加上下面代码即可。

request.setCharacterEncoding("UTF-8");
response.setCharacterEncoding("UTF-8");

(4)[Add] HttpServletRequest的常用方法

getRequestURL:返回客户端发出请求时的完整URL
getRequestURI:返回请求行中的资源名部分
getQueryString:返回请求行中的参数部分
getPathInfo:返回请求URL中的额外路径信息。额外路径信息是请求URL中的位于Servlet的路径之后和查询参数之前的内容,它以“/”开头
getRemoteAddr:返回发出请求的客户机的IP地址。
getRemoteHost:返回发出请求的客户机的完整主机名
getRemotePort:返回客户机所使用的网络端口号
getLocalAddr:返回WEB服务器的IP地址
getLocalName:方法返回WEB服务器的主机名

Filter

Filter也称之为过滤器,它是Servlet技术中最实用的技术,Web开发人员通过Filter技术,对web服务器管理的所有web资源:例如Jsp, Servlet, 静态图片文件或静态 html 文件等进行拦截,从而实现一些特殊的功能。例如实现URL级别的权限访问控制、过滤敏感词汇、压缩响应信息等一些高级功能。

它主要用于对用户请求进行预处理,也可以对HttpServletResponse进行后处理。使用Filter的完整流程:Filter对用户请求进行预处理,接着将请求交给Servlet进行处理并生成响应,最后Filter再对服务器响应进行后处理。

上面的如果每个Servlet中都添加Encode的代码会非常麻烦,可以用Filter解决。以下是代码。

 1 package com.mytest.servlettest.servlet;
 2 
 3 import java.io.IOException;
 4 import java.io.PrintWriter;
 5 
 6 import javax.servlet.ServletException;
 7 import javax.servlet.annotation.WebServlet;
 8 import javax.servlet.http.HttpServlet;
 9 import javax.servlet.http.HttpServletRequest;
10 import javax.servlet.http.HttpServletResponse;
11 
12 /**
13  * Servlet implementation class Login
14  */
15 @WebServlet("/login")
16 public class Login extends HttpServlet {
17 
18     private static final long serialVersionUID = 1L;
19 
20     /**
21      * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
22      */
23     @Override
24     protected void doGet(HttpServletRequest request, HttpServletResponse response)
25             throws ServletException, IOException {
26 
27         response.setContentType("text/html");
28 
29         PrintWriter out = response.getWriter();
30         out.println("<!DOCTYPE html>");
31         out.println("<html>");
32         out.println("<head>");
33         out.println("<title>Login Page</title>");
34         out.println("</head>");
35         out.println("<body>");
36         out.println("<form action="welcome" method="POST">");
37         out.println("帐号: <input type="text" name="userId"/><br/>");
38         out.println("密码: <input type="password" name="password"/><br/>");
39         out.println("<input type="submit" value="提交"/>");
40         out.println("</body>");
41         out.println("</html>");
42 
43         System.out.println("[login]" + request.getCharacterEncoding());
44         System.out.println("[login]" + response.getCharacterEncoding());
45     }
46 
47     /**
48      * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
49      */
50     @Override
51     protected void doPost(HttpServletRequest request, HttpServletResponse response)
52             throws ServletException, IOException {
53         doGet(request, response);
54     }
55 }
 1 package com.mytest.servlettest.servlet;
 2 
 3 import java.io.IOException;
 4 import java.io.PrintWriter;
 5 
 6 import javax.servlet.ServletException;
 7 import javax.servlet.annotation.WebServlet;
 8 import javax.servlet.http.HttpServlet;
 9 import javax.servlet.http.HttpServletRequest;
10 import javax.servlet.http.HttpServletResponse;
11 
12 /**
13  * Servlet implementation class Welcome
14  */
15 @WebServlet("/welcome")
16 public class Welcome extends HttpServlet {
17 
18     private static final long serialVersionUID = 1L;
19 
20     /**
21      * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
22      */
23     @Override
24     protected void doGet(HttpServletRequest request, HttpServletResponse response)
25             throws ServletException, IOException {
26 
27         response.setContentType("text/html");
28 
29         String userId = request.getParameter("userId");
30         String password = request.getParameter("password");
31 
32         PrintWriter out = response.getWriter();
33         out.println("<!DOCTYPE html>");
34         out.println("<html>");
35         out.println("<head>");
36         out.println("<title>Login Page</title>");
37         out.println("</head>");
38         out.println("<body>");
39         if ("123".equals(password)) {
40             out.println("欢迎您, " + userId);
41         } else {
42             out.println("您的帐号或密码错误!");
43         }
44         out.println("<a href = "login">返回</a>");
45         out.println("</body>");
46         out.println("</html>");
47 
48         System.out.println("[welcome]" + request.getCharacterEncoding());
49         System.out.println("[welcome]" + response.getCharacterEncoding());
50     }
51 
52     /**
53      * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
54      */
55     @Override
56     protected void doPost(HttpServletRequest request, HttpServletResponse response)
57             throws ServletException, IOException {
58         doGet(request, response);
59     }
60 }
 1 package com.mytest.servlettest.filter;
 2 
 3 import javax.servlet.*;
 4 import java.io.IOException;
 5 
 6 /**
 7  * Created by Administrator on 2017/9/4.
 8  */
 9 public class CharacterEncodingFilter implements Filter {
10 
11     private String encoding;
12 
13     public void setEncoding(String encoding) {
14         this.encoding = encoding;
15     }
16 
17     @Override
18     public void init(FilterConfig filterConfig) throws ServletException {
19         encoding = filterConfig.getInitParameter("encoding");
20         if (encoding == null || encoding == "") {
21             encoding = "UTF-8";
22         }
23     }
24 
25     @Override
26     public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
27         servletRequest.setCharacterEncoding(encoding);
28         servletResponse.setCharacterEncoding(encoding);
29         filterChain.doFilter(servletRequest, servletResponse);
30     }
31 
32     @Override
33     public void destroy() {
34     }
35 }
 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 3          xmlns="http://xmlns.jcp.org/xml/ns/javaee"
 4          xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
 5          id="WebApp_ID" version="3.1">
 6     <filter>
 7         <filter-name>characterEncodingFilter</filter-name>
 8         <filter-class>com.mytest.servlettest.filter.CharacterEncodingFilter</filter-class>
 9         <init-param>
10             <param-name>encoding</param-name>
11             <param-value>UTF-8</param-value>
12         </init-param>
13     </filter>
14     <filter-mapping>
15         <filter-name>characterEncodingFilter</filter-name>
16         <url-pattern>/*</url-pattern>
17     </filter-mapping>
18     <welcome-file-list>
19         <welcome-file>login</welcome-file>
20     </welcome-file-list>
21 </web-app>

推荐使用Spring的CharacterEncodingFilter

 1 <filter>  
 2     <filter-name>characterEncodingFilter</filter-name>  
 3     <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>  
 4     <init-param>  
 5         <param-name>encoding</param-name>  
 6         <param-value>UTF-8</param-value>  
 7     </init-param>  
 8     <init-param>  
 9         <param-name>forceEncoding</param-name>  
10         <param-value>true</param-value>  
11     </init-param>  
12 </filter>  
13 <filter-mapping>  
14     <filter-name>characterEncodingFilter</filter-name>  
15     <url-pattern>/*</url-pattern>  
16 </filter-mapping>  

CharacterEncodingFilter

原文地址:https://www.cnblogs.com/storml/p/7476309.html