使用filter和装饰者解决get和post提交乱码问题(增强getParameter, getParameterValues, getParameterMap )
Posted yyhl
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了使用filter和装饰者解决get和post提交乱码问题(增强getParameter, getParameterValues, getParameterMap )相关的知识,希望对你有一定的参考价值。
2018-06-22
小白的学习总结:希望可以帮助大家,也希望自己可以变得更加美好.
测试代码:
package com.itheima.web.servlet; import java.io.IOException; import java.util.Map; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class RegServlet extends HttpServlet { protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String username = request.getParameter("username"); System.out.println(username); String[] hobbys = request.getParameterValues("hobby"); for (String hobby : hobbys) { System.out.println(hobby); } //刚刚的方法只增强了getParameter方法,为增强getParameterValues方法 // String[] values = request.getParameterValues("username"); // System.out.println(values[0]);//张三, // 下述方法包含getParameterValues和getParameter这两个方法 // Map<String, String[]> map = request.getParameterMap(); // String[] values = map.get("username"); // System.out.println(values[0]); } protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } }
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!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>Insert title here</title> </head> <body> <form action="${pageContext.request.contextPath }/regServlet" method="get"> 用户名:<input type="text" name="username"><br> 爱好1:<input type="text" name="hobby"><br> 爱好2:<input type="text" name="hobby"><br> <input type="submit" value="提交"> </form> </body> </html>
//过滤器和装饰者
package me.gacl.web.filter; import java.io.IOException; import java.io.UnsupportedEncodingException; import java.util.Enumeration; import java.util.Map; import java.util.Map.Entry; import java.util.Set; 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.HttpServletRequestWrapper; /** * Servlet Filter implementation class EncodingFilter */ public class EncodingFilter implements Filter { public void destroy() { } public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { // 1.强转:是为了使其方法增多 HttpServletRequest req = (HttpServletRequest) request; // 2.处理业务 // req.setCharacterEncoding("UTF-8");//处理post提交方式乱码 // 如下方法,虽然可以解决一个提交数据的编码问题,但是不具有通用性 /* * String username = req.getParameter("username"); username = new * String(username.getBytes("ISO-8859-1"),"UTF-8"); */ // 装饰者:增强HttpServletRequest接口的getParameter(String name)方法 MyRequest myReq=new MyRequest(req); // 3.放行 chain.doFilter(myReq, response); } public void init(FilterConfig fConfig) throws ServletException { // TODO Auto-generated method stub } } // HttpServletRequest增强他的方法 // 装饰者 // 1.书写一个类实现被装饰类相同的接口,或者继承被装饰类的一个子类,选中一个类,ctrl+T查看一个类的继承关系 //实现HttpServletRequest,这个接口方法太多了, // 翻译:要增强某个接口的方法,实现这个接口,或者继承这个接口的的实现类 class MyRequest extends HttpServletRequestWrapper { //public class HttpServletRequestWrapper extends ServletRequestWrapper implements HttpServletRequest //2.在类中声明一个被包装类类型的变量 private HttpServletRequest oldRequest; //3.编写一个构造方法,给被包装类类型的变量赋值 public MyRequest(HttpServletRequest request) { //调用父类的有参构造 super(request); this.oldRequest=request; } //4.对于不需要修改的方法,调用被包装类原来的方法 //5.对于需要修改的方法,编写自己的代码 /*@Override public String getParameter(String name) { //name,是uesrname,也是hobby,借助原来的类的方法,获取乱码的张三 //使用原来的API方法获取请求参数 String username = oldRequest.getParameter(name);//username,就是乱码的张三 try { username=new String(username.getBytes("ISO-8859-1"), "UTF-8"); } catch (Exception e) { e.printStackTrace(); } return username; }*/ /*@Override //xxx 使用xxx,代替uesrname或者hobby或者其他的 public String getParameter(String xxx) { //name,是uesrname,也是hobby,借助原来的类的方法,获取乱码的张三 //使用原来的API方法获取请求参数,以二进制也可以解决post提交方式乱码 String XXX = oldRequest.getParameter(xxx);//username,就是乱码的张三 try { XXX=new String(XXX.getBytes("ISO-8859-1"), "UTF-8"); } catch (Exception e) { e.printStackTrace(); } return XXX; }*/ //增强getParameterMap方法 /** * 为何做个标记boolean flag=false; * request里边有个全局map.第一次从页面取值存到map里,这时map里是utf-8编码的 * 第二次就不会从页面取值了,而是从直接从map里取值 * utf-8->ISO-8859-1->utf-8,这样必然会乱码 * boolean flag=false,作用就是map只存一次 */ boolean flag=false; @Override public Map<String, String[]> getParameterMap() { Map<String, String[]> map = oldRequest.getParameterMap(); try { if(!flag){ Set<Entry<String, String[]>> entrySet = map.entrySet(); for (Entry<String, String[]> entry : entrySet) { //key不可能乱码,只需解决value的乱码 String[] values = entry.getValue(); for (int i = 0; i < values.length; i++) { values[i]=new String(values[i].getBytes("ISO-8859-1"),"UTF-8"); } } flag=true; } } catch (Exception e) { e.printStackTrace(); } return map;//操作的是引用地址,不用放回 } @Override //一个name对应多个值 public String[] getParameterValues(String name) { //调用上边的getParameterMap方法 Map<String, String[]> map = getParameterMap(); return map.get(name); } @Override //一个name对应一个值 public String getParameter(String name) { Map<String, String[]> map = getParameterMap(); String[] values = map.get(name); return values==null?null:values[0]; } }
以上是关于使用filter和装饰者解决get和post提交乱码问题(增强getParameter, getParameterValues, getParameterMap )的主要内容,如果未能解决你的问题,请参考以下文章