(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;
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>
<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>