動態代理解決網站字符集編碼
阿新 • • 發佈:2018-10-31
1、首先看一個裝飾模式解決字符集編碼問題
我們使用裝飾者對request進行增強,從而使得get和post使用request.getParameter()獲得的資料沒有亂碼:
首先來一個Servlet,用於處理客戶端請求:
package 裝飾者模式解決亂碼; import java.io.IOException; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class DataServlet extends HttpServlet { private static final long serialVersionUID = 1L; public DataServlet() { super(); } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //獲得資料 String username = request.getParameter("username"); String password = request.getParameter("password"); System.out.println("前:" +username+"@"+password); } protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //獲得資料 String username = request.getParameter("username"); String password = request.getParameter("password"); System.out.println("前:" +username+"@"+password); } }
建立HttpServletRequest的增強類,藉助HttpServletRequestWrapper:
package 裝飾者模式解決亂碼; import java.io.UnsupportedEncodingException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequestWrapper; /** * * sun 提供 HttpServletRequest 介面使用裝飾者編寫預設類,及所有的方法都沒有增強的。 * * 之後我們只需要繼承即可 * * 增強response物件,提供使用裝飾者設計模式編寫預設類:HttpServletResponseWrapper */ public class MyRequest extends HttpServletRequestWrapper { //保持對介面的引用 private HttpServletRequest request; //構造方法 public MyRequest(HttpServletRequest request) { super(request); //賦值 this.request = request; } //重寫某個方法 @Override public String getParameter(String name) { //首先獲得引數,這是沒有改變編碼的值 String value = request.getParameter(name); //首先判斷請求方式 String method = request.getMethod(); if ("GET".equals(method)) { try { value = new String(value.getBytes("ISO-8859-1"), "utf-8"); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } }else { try { request.setCharacterEncoding("utf-8"); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } } return value; } }
在客戶端向伺服器傳送請求時,我們需要對其進行攔截:
package 裝飾者模式解決亂碼; import java.io.IOException; import javax.servlet.Filter; import javax.servlet.FilterChain; import javax.servlet.FilterConfig; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class EncodingFilter implements Filter { public EncodingFilter() { } public void destroy() { } public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException { //強轉 HttpServletRequest request = (HttpServletRequest) req; HttpServletResponse response = (HttpServletResponse) res; //post編碼 response.setCharacterEncoding("UTF-8"); //使用裝飾者模式增強 MyRequest myRequest = new MyRequest(request); //放行 chain.doFilter(myRequest, response); System.out.println("我是中國人!"); /*//0 強轉 HttpServletRequest request = (HttpServletRequest) req; HttpServletResponse response = (HttpServletResponse) resp; //1 post亂碼 request.setCharacterEncoding("UTF-8"); //2 使用裝飾者增強request MyRequest myRequest = new MyRequest(request); chain.doFilter(myRequest, response);*/ } public void init(FilterConfig fConfig) throws ServletException { } }
2、動態代理解決
客戶端頁面:
<%@ 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>動態代理解決get方式亂碼問題</title>
</head>
<body>
<form action="/proxy/DataServlet" method="get">
使用者名稱:<input type="text" name="username" value="胡根得" /><br/>
密碼:<input type="password" name=password value="就不告訴你"><br/>
<input type="submit" value="提交get請求">
</form>
</body>
</html>
寫一個Servlet:
package solveresponseencoding;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@WebServlet("/DataServlet")
public class DataServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
public DataServlet() {
super();
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//獲得請求引數
String username = request.getParameter("username");
String password = request.getParameter("password");
//列印值
System.out.println(request.getMethod() + " : " + username + " @ " + password);
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
}
<span style="font-size:18px;">package solveresponseencoding;
import java.io.IOException;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@WebFilter("/*")
public class EncodingFilter implements Filter {
public EncodingFilter() {
}
public void destroy() {
}
/*
* 本方法會攔截所有請求,在本方法中對request進行增強
*/
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
//強轉
final HttpServletRequest request = (HttpServletRequest) req;
HttpServletResponse response = (HttpServletResponse) res;
//解決post亂碼
request.setCharacterEncoding("utf-8");
//建立動態代理物件
HttpServletRequest myRequest = (HttpServletRequest) Proxy.newProxyInstance(
EncodingFilter.class.getClassLoader(),
new Class[]{HttpServletRequest.class},
new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//如果是getParameter方法,獲取引數
if ("getParameter".equals(method.getName())) {
String value = request.getParameter((String)args[0]);
//System.out.println("value值為:"+value);
//如果是get請求,就增強
if ("GET".equalsIgnoreCase(request.getMethod())) {
value = new String(value.getBytes("ISO-8859-1"), "utf-8");
System.out.println("我是get方法:");
}
return value;
}
return method.invoke(request, args);
}
});
chain.doFilter(myRequest, response);
}
public void init(FilterConfig fConfig) throws ServletException {
}
}
</span>