使用Filter解决乱码问题

时间:2021-06-09 18:30:32

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


           3.测试页面charset.html
<!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>