1.统一中文编码分析
tomcat默认esetISO-8859-1编码,在servlet中,可能通过request的setCharacterEncoding(charset)和response.setContentType("text/html;charset=UTF-8");处理post请求编码,但get请求的编码控制不了,所以,如果请求类型是get,则用装饰者模式把request整个调包
2.EncodingFilter.java
1 package cn.itcast.filter; 2 3 import java.io.IOException; 4 5 import javax.servlet.Filter; 6 import javax.servlet.FilterChain; 7 import javax.servlet.FilterConfig; 8 import javax.servlet.ServletException; 9 import javax.servlet.ServletRequest; 10 import javax.servlet.ServletResponse; 11 import javax.servlet.http.HttpServletRequest; 12 13 14 public class EncodingFilter implements Filter { 15 private String charset = "UTF-8"; 16 @Override 17 public void destroy() {} 18 19 @Override 20 public void doFilter(ServletRequest request, ServletResponse response, 21 FilterChain chain) throws IOException, ServletException { 22 HttpServletRequest req = (HttpServletRequest) request; 23 if(req.getMethod().equalsIgnoreCase("GET")) { 24 if(!(req instanceof GetRequest)) { 25 req = new GetRequest(req, charset);//处理get请求编码 26 } 27 } else { 28 req.setCharacterEncoding(charset);//处理post请求编码 29 } 30 chain.doFilter(req, response); 31 } 32 33 @Override 34 public void init(FilterConfig fConfig) throws ServletException { 35 String charset = fConfig.getInitParameter("charset"); 36 if(charset != null && !charset.isEmpty()) { 37 this.charset = charset; 38 } 39 } 40 }
3.GetRequest.java 装饰者模式
1 package cn.itcast.filter; 2 3 import java.io.UnsupportedEncodingException; 4 import java.util.Enumeration; 5 import java.util.Map; 6 import javax.servlet.http.HttpServletRequest; 7 import javax.servlet.http.HttpServletRequestWrapper; 8 9 /** 10 * 对GET请求参数加以处理! 11 * @author qdmmy6 12 * 13 */ 14 public class GetRequest extends HttpServletRequestWrapper { 15 private HttpServletRequest request; 16 private String charset; 17 18 public GetRequest(HttpServletRequest request, String charset) { 19 super(request); 20 this.request = request; 21 this.charset = charset; 22 } 23 24 @Override 25 public String getParameter(String name) { 26 // 获取参数 27 String value = request.getParameter(name); 28 if(value == null) return null;//如果为null,直接返回null 29 try { 30 // 对参数进行编码处理后返回 31 return new String(value.getBytes("ISO-8859-1"), charset); 32 } catch (UnsupportedEncodingException e) { 33 throw new RuntimeException(e); 34 } 35 } 36 37 @SuppressWarnings({ "unchecked", "rawtypes" }) 38 @Override 39 public Map getParameterMap() { 40 Map<String,String[]> map = request.getParameterMap(); 41 if(map == null) return map; 42 // 遍历map,对每个值进行编码处理 43 for(String key : map.keySet()) { 44 String[] values = map.get(key); 45 for(int i = 0; i < values.length; i++) { 46 try { 47 values[i] = new String(values[i].getBytes("ISO-8859-1"), charset); 48 } catch (UnsupportedEncodingException e) { 49 throw new RuntimeException(e); 50 } 51 } 52 } 53 // 处理后返回 54 return map; 55 } 56 57 @Override 58 public String[] getParameterValues(String name) { 59 String[] values = super.getParameterValues(name); 60 for(int i = 0; i < values.length; i++) { 61 try { 62 values[i] = new String(values[i].getBytes("ISO-8859-1"), charset); 63 } catch (UnsupportedEncodingException e) { 64 throw new RuntimeException(e); 65 } 66 } 67 return values; 68 } 69 }
3.BaseServlet.java
1 package cn.itcast.servlet; 2 3 import java.io.IOException; 4 import java.lang.reflect.Method; 5 6 import javax.servlet.ServletException; 7 import javax.servlet.http.HttpServlet; 8 import javax.servlet.http.HttpServletRequest; 9 import javax.servlet.http.HttpServletResponse; 10 11 /** 12 * BaseServlet用来作为其它Servlet的父类 13 * 14 * @author qdmmy6 15 * 16 * 一个类多个请求处理方法,每个请求处理方法的原型与service相同! 原型 = 返回值类型 + 方法名称 + 参数列表 17 */ 18 @SuppressWarnings("serial") 19 public class BaseServlet extends HttpServlet { 20 @Override 21 public void service(HttpServletRequest request, HttpServletResponse response) 22 throws ServletException, IOException { 23 response.setContentType("text/html;charset=UTF-8");//处理响应编码 24 25 /** 26 * 1. 获取method参数,它是用户想调用的方法 2. 把方法名称变成Method类的实例对象 3. 通过invoke()来调用这个方法 27 */ 28 String methodName = request.getParameter("method"); 29 Method method = null; 30 /** 31 * 2. 通过方法名称获取Method对象 32 */ 33 try { 34 method = this.getClass().getMethod(methodName, 35 HttpServletRequest.class, HttpServletResponse.class); 36 } catch (Exception e) { 37 throw new RuntimeException("您要调用的方法:" + methodName + "它不存在!", e); 38 } 39 40 /** 41 * 3. 通过method对象来调用它 42 */ 43 try { 44 String result = (String)method.invoke(this, request, response); 45 if(result != null && !result.trim().isEmpty()) {//如果请求处理方法返回不为空 46 int index = result.indexOf(":");//获取第一个冒号的位置 47 if(index == -1) {//如果没有冒号,使用转发 48 request.getRequestDispatcher(result).forward(request, response); 49 } else {//如果存在冒号 50 String start = result.substring(0, index);//分割出前缀 51 String path = result.substring(index + 1);//分割出路径 52 if(start.equals("f")) {//前缀为f表示转发 53 request.getRequestDispatcher(path).forward(request, response); 54 } else if(start.equals("r")) {//前缀为r表示重定向 55 response.sendRedirect(request.getContextPath() + path); 56 } 57 } 58 } 59 } catch (Exception e) { 60 throw new RuntimeException(e); 61 } 62 } 63 }