(1)目的
为了获取正确编码的数据,我们会在逻辑代码中执行setCharsetEncoding、getBytes编码等操作,这样做显得十分混乱。所以最好的方式就是将这些操作提取出来,在Filter中进行统一处理
(2)装饰模式
1.简介
当某个对象的方法不适应业务需求时,通常有2种方式可以对方法进行增强:
1)编写子类,覆盖需要增强的方法
2)使用Decorator设计模式对方法进行增强
那么在实际应用中遇到需要增强对象的方法时,到底选用哪种方式呢?这个没有确定的答案,只能根据具体需求确定。但是有一种情况必须使用装饰模式:即被增强的对象,开发人员只能得到它的对象,无法得到它的class文件。比如request、response对象,开发人员之所以在servlet中通过Sun公司定义的HttpServletRequest/Response接口去操作这些对象,是因为Tomcat服务器厂商编写了Request、Response接口的实现类。在web服务器在调用servlet的时候,会用这些接口的实现类创建出对象,然后作为入参传递给servlet程序。在这种情况下,开发人员根本不知道服务器厂商编写的Request、Response接口的实现类是哪个。在程序中只能拿到服务器厂商提供的对象,因此就只能采用装饰模式去对这些对象进行增强。
2.实现
1)首先看需要被增强的对象继承了什么父类或者接口,编写一个类也去继承这个接口或父类
2)在类中定义一个变量,变量类型就是需要增强对象的类型3)在类中定义一个构造函数,接收需要增强的对象
4)覆盖需要增强的方法,编写增强代码
(3)使用装饰模式增强Request对象
Servlet API中提供了一个Request对象的装饰模式的默认实现类HttpServletRequestWrapper,HttpServletRequestWrapper类实现了Request接口中的方法,但这些方法内部都是仅仅调用了一下所包装的Request对象的对应方法,以避免用户在对Request对象进行增强时需要实现Request接口中的所有方法
1.编写Filter
package com.learn.filter;配置filter,拦截所有请求
import java.io.IOException;
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;
public class CharsetFilter implements Filter {
private String defaultCharset = "UTF-8";
public CharsetFilter() {
}
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
request.setCharacterEncoding(defaultCharset);
response.setCharacterEncoding(defaultCharset);
response.setContentType("text/htmll;charset="+defaultCharset);
MyRequestWrapper myRequest = new MyRequestWrapper((HttpServletRequest) request);
chain.doFilter(myRequest, response);
}
public void init(FilterConfig fConfig) throws ServletException {
}
@Override
public void destroy() {
}
}
<filter>
<filter-name>CharsetFilter</filter-name>
<filter-class>com.learn.filter.CharsetFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>CharsetFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
2.包装类
package com.learn.filter;import java.io.UnsupportedEncodingException;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletRequestWrapper;public class MyRequestWrapper extends HttpServletRequestWrapper { private HttpServletRequest request; public MyRequestWrapper(HttpServletRequest request) { super(request); this.request = request; } @Override public String getParameter(String name) { String method = getMethod(); if ("GET".equals(method)) { String param = request.getParameter(name); if (param==null) { return null; }else { String result; try { result = new String(param.getBytes("ISO8859-1"),request.getCharacterEncoding()); } catch (UnsupportedEncodingException e) { result = ""; } return result; } }else{ return request.getParameter(name); } }}
<!DOCTYPE html><html>
<head>
<meta HTTP-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<a href="/LearnServlet/CharsetServlet?name=test">测试get参数是否乱码</a>
<fieldset>
<form action="/LearnServlet/CharsetServlet" method="post">
编 号(文本框):
<input type="text" name="name"><br>
<input type="submit" value="提交(提交按钮)">
</form>
</fieldset>
</body>
</html>
</body>
</html>
4.响应servlet
package com.learn.filter;import java.io.IOException;import java.io.OutputStream;import javax.servlet.ServletException;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;public class CharsetServlet extends HttpServlet { private static final long serialVersionUID = 1L; protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String name = request.getParameter("name"); System.out.println(name); OutputStream out = response.getOutputStream(); out.write(name.getBytes("UTF-8")); } protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String name = request.getParameter("name"); System.out.println(name); OutputStream out = response.getOutputStream(); out.write(name.getBytes("UTF-8")); }}web.xml中的配置为:
<servlet>
<servlet-name>CharsetServlet</servlet-name>
<servlet-class>com.learn.filter.CharsetServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>CharsetServlet</servlet-name>
<url-pattern>/CharsetServlet</url-pattern>
</servlet-mapping>