我们使用装饰者对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 {
}
}
客户端页面:
<%@ page language="java" contentType="text/html; charset=utf-8"
pageEncoding="utf-8"%>
动态代理解决get方式乱码问题
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);
}
}
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 {
}
}