直接上在工作中遇到的问题吧:
在springmvc的项目中 前台表单通过get请求发送的中文在后台接收后出现乱码
于是我配置了一个spring的过滤器
org.springframework.web.filter.CharacterEncodingFilter
但是仅仅处理了post请求的中文乱码问题,网上说有一种简单的方法就是修改tomcat的server.xml文件,但是这个方法也太部靠谱了吧,还是另想他发吧!
于是我就着手写一个Filter去处理乱码问题 通过包装
javax.servlet.http.HttpServletRequestWrapper
类 重写request中获取参数的方法并对参数进行重编码来解决问题,应该没问题吧,可是搞了半天竟然还没起作用,我在Filtter中
chain.doFilter(...)
前后各打印请求参数,显示转码成功了呀, 怎么回事?。。。
经过一时思考,原来是处理逻辑有问题,在程序中没有做是否转过码的判断,导致有可能在springmvc的自动装载请求参数的过程中可能把我已经转过码的参数再次转码 这样肯定不行啦!!
下面把代码贴出,注意的地方标红吧:
/** * 对请求和响应的数据进行编码 * * @author aracwong * */ public class CharacterEncodingFilter implements Filter { public static final String PARAM_ENCODING_NAME = "encoding"; public static final String UTF_8 = "UTF-8"; public static final String ISO_8859_1 = "ISO-8859-1"; private String encoding = CharacterEncodingFilter.UTF_8; public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { HttpServletRequest requ = (HttpServletRequest) request; HttpServletResponse resp = (HttpServletResponse) response; request.setCharacterEncoding(CharacterEncodingFilter.UTF_8); response.setCharacterEncoding(CharacterEncodingFilter.UTF_8); // 使用包装类 MyHttpServletRequest myrequest = new MyHttpServletRequest(requ); chain.doFilter(myrequest, resp); } public void init(FilterConfig filterConfig) throws ServletException { String _encoding = filterConfig .getInitParameter(CharacterEncodingFilter.PARAM_ENCODING_NAME); if (StringUtils.isNotBlank(_encoding)) { encoding = _encoding; } } private class MyHttpServletRequest extends HttpServletRequestWrapper { private HttpServletRequest request; private boolean flag = false; public MyHttpServletRequest(HttpServletRequest request) { super(request); this.request = request; } @Override public String getParameter(String name) { Map<String, String[]> map = getParameterMap(); if (map != null) { String[] values = map.get(name); if (values != null) { return values[0]; } } return null; } @Override public String[] getParameterValues(String name) { Map<String, String[]> map = getParameterMap(); if (map != null) { String[] values = map.get(name); if (values != null) { return values; } } return null; } @Override public Map<String, String[]> getParameterMap() { if ("post".equalsIgnoreCase(request.getMethod())) { // post方式提交 try { request.setCharacterEncoding(encoding); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } return request.getParameterMap(); } else { // get方式提交 Map<String, String[]> paramMap = request.getParameterMap(); if (!flag) { for (Map.Entry<String, String[]> me : paramMap.entrySet()) { String[] values = me.getValue(); for (int i = 0; i < values.length; i++) { try { values[i] = new String( values[i] .getBytes(CharacterEncodingFilter.ISO_8859_1), encoding); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } } } flag = true; } return paramMap; } } } public void destroy() { } }
一下这个代码非常有必要:如果这个请求对象已经被转过码,下次调用取请求参数的时候做个判断,就不再转码了,不然转过码的UTF-8数据 再以ISO8859-1取字节 在转换成UTF-8肯定会报错咯,真是个宝贵的错误经验
private boolean flag = false;
时间: 2024-11-01 20:42:08