最近在重温JavaWeb基础内容,碰到了之前也时常遇到的中文乱码问题,想着反正是经常要处理的,不如当即就把它整理出来放在博客里,省得遇到时再去到处搜。
1. Post请求乱码的解决方案:
手工创建一个过滤器实现javax.servlet.Filter接口:
public class CharacterEncodingFilter implements Filter { @Override public void init(FilterConfig filterConfig) throws ServletException { } @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { //解决以Post方式提交的中文乱码问题 request.setCharacterEncoding("UTF-8"); response.setCharacterEncoding("UTF-8"); response.setContentType("text/html;charset=UTF-8"); chain.doFilter(request, response); } @Override public void destroy() { } }
在web.xml中配置该过滤器:
<filter> <filter-name>CharacterEncodingFilter</filter-name> <filter-class>cn.lby.filter.CharacterEncodingFilter</filter-class> </filter> <filter-mapping> <filter-name>CharacterEncodingFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
当然,实际开发中一般不会去自己做这个Filter,都是利用框架里封装好的,传参也能通过配置来完成,十分方便,比如spring通常我们会在web.xml中写入下面的代码:
<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> </filter> <filter-mapping> <filter-name>CharacterEncodingFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
2. Get请求乱码的解决方案:
在字符过滤器中使用动态代理解决中文乱码:
public class CharacterEncodingFilter implements Filter { @Override public void init(FilterConfig filterConfig) throws ServletException { } @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { //解决以Post方式提交的中文乱码问题 request.setCharacterEncoding("UTF-8"); response.setCharacterEncoding("UTF-8"); response.setContentType("text/html;charset=UTF-8"); ServletRequest requestProxy = getHttpServletRequestProxy((HttpServletRequest)request); chain.doFilter(requestProxy, response); } @Override public void destroy() { } /** * @Method: getHttpServletRequestProxy * @Description: 获取HttpServletRequest对象的代理对象 * @param request * @return HttpServletRequest对象的代理对象 */ private ServletRequest getHttpServletRequestProxy(final HttpServletRequest request){ ServletRequest proxy = (ServletRequest) Proxy.newProxyInstance( CharacterEncodingFilter.class.getClassLoader(), request.getClass().getInterfaces(), new InvocationHandler(){ @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { //如果请求方式是get并且调用的是getParameter方法 if (request.getMethod().equalsIgnoreCase("get") && method.getName().equals("getParameter")) { //调用getParameter方法获取参数的值 String value = (String) method.invoke(request, args); if(value==null){ return null; } //解决以get方式提交的中文乱码问题 return new String(value.getBytes("iso8859-1"),"UTF-8"); }else { //直接调用相应的方法进行处理 return method.invoke(request, args); } } }); //返回HttpServletRequest对象的代理对象 return proxy; } }
如果觉得上面的方式太繁琐,也可以通过修改 tomcat 的 server.xml 配置文件:
<Connector connectionTimeout="20000" port="8080" protocol="HTTP/1.1" redirectPort="8443"/>
改成:
<Connector connectionTimeout="20000" port="8080" protocol="HTTP/1.1" redirectPort="8443" useBodyEncodingForURI="true"/>
注: 如果是ajax发起的get请求中文依然会乱码,这时候需要把 useBodyEncodingForURI="true" 改为 URIEncoding="UTF-8" 。
下面是测试两种乱码问题解决方案的 demo ,如果懒得写可以参考一下:
首先是jsp页面:
<!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、post请求方式下的中文乱码问题</title> body { text-align: center; padding: 60px 150px; margin-right: 150px; line-height: 2.0em; } </head> <body> <%--使用get的方式访问 --%> <a onclick="myClick()" href="javascript:void(0)">超链接(get方式请求)</a> <hr/> <form action="EncodingServlet" method="post"> 用户名:<input type="text" name="username" value="彬爷" /> <input type="submit" value="post方式提交"> </form> <script type="text/javascript"> function myClick() { window.location.href = "EncodingServlet?username=彬爷"; } </script> </body> </html>
后台服务:
public class EncodingServlet extends HttpServlet { private static final long serialVersionUID = 1L; /** * @see HttpServlet#HttpServlet() */ public EncodingServlet() { super(); } /** * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response) */ protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String username = request.getParameter("username"); String method = request.getMethod(); PrintWriter out = response.getWriter(); System.out.println("请求方式为:" + method); out.write("请求方式为:" + method); out.write("<br/>"); System.out.println("请求参数为:" + username); out.write("请求参数为:" + username); } /** * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response) */ protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } }
web.xml 中的 Servlet 配置我这里就不发了。