方式一
使用装饰着模式重新包装HttpServletRequest类。只修改Request的getParameter和getParameterValues方法
package com.omp.comm.getEncoding;
import org.springframework.http.client.support.HttpRequestWrapper;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
public class GetRequestEncoding extends HttpServletRequestWrapper {
HttpServletRequest request = null;
public GetRequestEncoding(HttpServletRequest request) {
super(request);
this.request = request;
}
@Override
public String getParameter(String name) {
String method = request.getMethod();
String value=null;
try {
request.setCharacterEncoding("utf-8");
value = request.getParameter(name);
if("get".equalsIgnoreCase(method)){
value = new String(value.getBytes("iso-8859-1"),"utf-8");
}
} catch (Exception e) {
e.printStackTrace();
}
return value;
}
@Override
public String[] getParameterValues(String name) {
String method = request.getMethod();
String[] values=null;
try {
request.setCharacterEncoding("utf-8");
values = request.getParameterValues(name);
if("get".equalsIgnoreCase(method)){
int i=0;
for (String str : values) {
values[i++] = new String(str.getBytes("iso-8859-1"),"utf-8");
}
}
} catch (Exception e) {
e.printStackTrace();
}
return values;
}
}
编写过滤器GetRequestFilterEncoding用于替换Reuqest
package com.omp.comm.getEncoding;
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
public class GetRequestFilterEncoding implements Filter {
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) servletRequest;
HttpServletResponse response = (HttpServletResponse) servletResponse;
GetRequestEncoding myRrequest = new GetRequestEncoding(request);
filterChain.doFilter(myRrequest, response);
}
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void destroy() {
}
}
配置web.xml文件
<!--配置post请求方式携带中文时的编码格式-->
<filter>
<filter-name>characterEncodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
<init-param>
<param-name>forceEncoding</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>characterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!--配置get请求方式携带中文时的编码格式-->
<filter>
<filter-name>getEncoding</filter-name>
<filter-class>com.omp.comm.getEncoding.GetRequestFilterEncoding</filter-class>
</filter>
<filter-mapping>
<filter-name>getEncoding</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
方式二
解决思路,springmvc有自带配置处理post乱码问题,查看源码可以看出也是使用Filter处理的,则可以复制一份源码,通过判断请求类型是get/post来区分编码处理方式。get还是使用装饰着模式来重新包装Request
post提交处理乱码的过滤器源码
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//
package org.springframework.web.filter;
import java.io.IOException;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
public class CharacterEncodingFilter extends OncePerRequestFilter {
@Nullable
private String encoding;
private boolean forceRequestEncoding;
private boolean forceResponseEncoding;
public CharacterEncodingFilter() {
this.forceRequestEncoding = false;
this.forceResponseEncoding = false;
}
public CharacterEncodingFilter(String encoding) {
this(encoding, false);
}
public CharacterEncodingFilter(String encoding, boolean forceEncoding) {
this(encoding, forceEncoding, forceEncoding);
}
public CharacterEncodingFilter(String encoding, boolean forceRequestEncoding, boolean forceResponseEncoding) {
this.forceRequestEncoding = false;
this.forceResponseEncoding = false;
Assert.hasLength(encoding, "Encoding must not be empty");
this.encoding = encoding;
this.forceRequestEncoding = forceRequestEncoding;
this.forceResponseEncoding = forceResponseEncoding;
}
public void setEncoding(@Nullable String encoding) {
this.encoding = encoding;
}
@Nullable
public String getEncoding() {
return this.encoding;
}
public void setForceEncoding(boolean forceEncoding) {
this.forceRequestEncoding = forceEncoding;
this.forceResponseEncoding = forceEncoding;
}
public void setForceRequestEncoding(boolean forceRequestEncoding) {
this.forceRequestEncoding = forceRequestEncoding;
}
public boolean isForceRequestEncoding() {
return this.forceRequestEncoding;
}
public void setForceResponseEncoding(boolean forceResponseEncoding) {
this.forceResponseEncoding = forceResponseEncoding;
}
public boolean isForceResponseEncoding() {
return this.forceResponseEncoding;
}
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
String encoding = this.getEncoding();
if (encoding != null) {
if (this.isForceRequestEncoding() || request.getCharacterEncoding() == null) {
request.setCharacterEncoding(encoding);
}
if (this.isForceResponseEncoding()) {
response.setCharacterEncoding(encoding);
}
}
filterChain.doFilter(request, response);
}
}
仿写一份MyRequestEncodingFilter
package com.omp.comm.getEncoding;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
import org.springframework.web.filter.OncePerRequestFilter;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
public class MyRequestEncodingFilter extends OncePerRequestFilter {
@Nullable
private String encoding;
private boolean forceRequestEncoding;
private boolean forceResponseEncoding;
public MyRequestEncodingFilter() {
this.forceRequestEncoding = false;
this.forceResponseEncoding = false;
}
public MyRequestEncodingFilter(String encoding) {
this(encoding, false);
}
public MyRequestEncodingFilter(String encoding, boolean forceEncoding) {
this(encoding, forceEncoding, forceEncoding);
}
public MyRequestEncodingFilter(String encoding, boolean forceRequestEncoding, boolean forceResponseEncoding) {
this.forceRequestEncoding = false;
this.forceResponseEncoding = false;
Assert.hasLength(encoding, "Encoding must not be empty");
this.encoding = encoding;
this.forceRequestEncoding = forceRequestEncoding;
this.forceResponseEncoding = forceResponseEncoding;
}
public void setEncoding(@Nullable String encoding) {
this.encoding = encoding;
}
@Nullable
public String getEncoding() {
return this.encoding;
}
public void setForceEncoding(boolean forceEncoding) {
this.forceRequestEncoding = forceEncoding;
this.forceResponseEncoding = forceEncoding;
}
public void setForceRequestEncoding(boolean forceRequestEncoding) {
this.forceRequestEncoding = forceRequestEncoding;
}
public boolean isForceRequestEncoding() {
return this.forceRequestEncoding;
}
public void setForceResponseEncoding(boolean forceResponseEncoding) {
this.forceResponseEncoding = forceResponseEncoding;
}
public boolean isForceResponseEncoding() {
return this.forceResponseEncoding;
}
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
String encoding = this.getEncoding();
String method = request.getMethod();
if (encoding != null) {
if (this.isForceResponseEncoding()) {
response.setCharacterEncoding(encoding);
}
if("get".equalsIgnoreCase(method)){
GetRequestEncoding myRrequest = new GetRequestEncoding(request);
filterChain.doFilter(myRrequest, response);
}else{
if (this.isForceRequestEncoding() || request.getCharacterEncoding() == null) {
request.setCharacterEncoding(encoding);
}
filterChain.doFilter(request, response);
}
}
}
}
web.xml配置
<filter>
<filter-name>characterEncodingFilter</filter-name>
<filter-class>com.omp.comm.getEncoding.MyRequestEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
<init-param>
<param-name>forceEncoding</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>characterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
方式三:
处理post请求还是和方式一的一样,但是处理get请求有两个方式
一, 我们需要把request.getParameter(“参数名”)获取到的字符串先用ISO-8859-1编码成字节流,然后再将其用utf-8解码成字符流,代码如下:
String str = new String(request.getParameter("参数名").getBytes("iso-8859-1"), "utf-8");
二, 我们也可以通过Tomcat配置文件,设置URL编码集(URIEncoding)设置编码.
在tomcat的server.xml配置文件中,添加 URIEncoding=“UTF-8”
在这里要特别注意:当你用eclipse运行项目文件时,如果改了tomcat安装目录下的server.xml文件依旧不起作用,就要改eclipse自身配置的servers底下的server.xml文件.因为eclipse运行项目时用的是这个server.
如下图所示:
添加 URIEncoding=“UTF-8”
<Connector connectionTimeout="20000" port="8080" protocol="HTTP/1.1" redirectPort="8443"/>
修改为:
<Connector URIEncoding="UTF-8" connectionTimeout="20000" port="8080" protocol="HTTP/1.1" redirectPort="8443"/>
备注:
下面来解释一下这两个属性的意义:
useBodyEncodingForURI参数表示是否用request.setCharacterEncoding参数对URL提交的数据和表单中GET方式提交的数据进行重新编码,在默认情况下,该参数为false。
URIEncoding参数指定对所有GET方式请求进行统一的重新编码(解码)的编码。
URIEncoding和useBodyEncodingForURI区别是:
URIEncoding是对所有GET方式的请求的数据进行统一的重新编码,
而useBodyEncodingForURI则是根据响应该请求的页面的request.setCharacterEncoding参数对数据进行的重新编码,不同的页面可以有不同的重新编码的编码
配置useBodyEncodingForURI="true"后,可以解决普通get请求的中文乱码问题,但是对于通过ajax发起的get请求中文依然会乱码,把useBodyEncodingForURI="true"改为URIEncoding="UTF-8"即可。