彻底解决get/post中文乱码
1.包装模式过滤器
- spring boot 中使用@Component 或者@Configuration
package com.dancer4code.actuator.filter;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
* Created with IntelliJ IDEA.
* User: liangqing.zhao(zlq)
* Date: 2019/10/4 19:45
* Description:
*/
//@Component
//@WebFilter
//@Configuration
//@Order(value = 15)
public class MyCharacterEncodingFilter implements Filter {
@Override
public void doFilter(ServletRequest servletRequest,
ServletResponse servletResponse, FilterChain filterChain)
throws IOException, ServletException {
//System.out.println("----------------MyCharacterEncordingFilter------doFilter-----------------");
HttpServletRequest request = (HttpServletRequest) servletRequest;
HttpServletResponse response = (HttpServletResponse) servletResponse;
request.setCharacterEncoding("UTF-8");
response.setCharacterEncoding("UTF-8");
response.setContentType("text/html;charset=UTF-8");
filterChain.doFilter(new MyRequest(request), response);
}
/*
* 1.写一个类实现与被增强对象相同的接口
* 2.定义一个变量,记住被增强的对象
* 3.定义一个构造方法,接受被增强对象
* 4.覆盖想增强的方法
* 5.对于不想增强的方法,直接调用被增强对象(目标对象)的方法
*/
class MyRequest extends HttpServletRequestWrapper {
private HttpServletRequest request;
public MyRequest(HttpServletRequest request) {
super(request);
this.request = request;
}
@Override
public String getParameter(String name) {
String value = this.request.getParameter(name);
if (!request.getMethod().equalsIgnoreCase("get")) {
return value;
}
if (value == null) {
return null;
}
try {
return new String(value.getBytes("UTF-8"),
request.getCharacterEncoding());
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
@Override
public void init(FilterConfig filterConfig) throws ServletException {
//System.out.println("---MyCharacterEncordingFilter-----init-------");
}
@Override
public void destroy() {
//System.out.println("---MyCharacterEncordingFilter-----destroy-------");
}
}
spring boot中使用@WebFilter+@ServletComponentScan(可自定义过滤路径)
spring mvc中使用web.xml中配置(可自定义过滤路径)
<filter>
<filter-name>MyCharacterEncodingFilter</filter-name>
<filter-class>com.dancer4code.actuator.filter.MyCharacterEncodingFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>MyCharacterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
- spring mvc中使用@WebFilter注解
2.动态代理
package com.dancer4code.actuator.filter;
import org.springframework.stereotype.Component;
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
/**
* Created with IntelliJ IDEA.
* User: liangqing.zhao(zlq)
* Date: 2019/10/5 15:15
* Description:
*/
@Component
public class MyCharacterEncodingProxyFilter implements Filter {
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
//System.out.println("----------MyCharacterEncodingProxyFilter---doFilter--------------------");
final HttpServletRequest request = (HttpServletRequest) req;
HttpServletResponse response = (HttpServletResponse) res;
//POST的乱码解决方案
request.setCharacterEncoding("utf-8");
//返回数据的乱码解决方案
response.setCharacterEncoding("utf-8");
response.setContentType("text/html;charset=utf-8");
//用动态代理拦截,增强getParameter()后,放行
chain.doFilter((ServletRequest) Proxy.newProxyInstance(MyCharacterEncodingProxyFilter.class.getClassLoader(), request.getClass().getInterfaces(),
new InvocationHandler() { //直接实现接口
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
//如果请求方式是POST,则不用增强,直接调用目标对象的方法
if (request.getMethod().equalsIgnoreCase("POST")) {
return method.invoke(request, args);
}
String methodName = method.getName();
//如果传递进来的方法不是getParameter(),则不用增强
if (!methodName.equals("getParameter")) {
return method.invoke(request, args);
}
//为GET,并且是getParameter(),...
String value = (String) method.invoke(request, args);
if (value != null) {
value = new String(value.getBytes("iso8859-1"), "utf-8");
}
return value;
}
}), response);
}
public void destroy() {
//System.out.println("----------MyCharacterEncodingProxyFilter---destroy--------------------");
}
public void init(FilterConfig fConfig) throws ServletException {
//System.out.println("----------MyCharacterEncodingProxyFilter---init--------------------");
}
}
其他配置方式与上面相同