装饰者设计模式简介
- 定义:动态给对象添加一个额外的职责,扩充其功能,使用装饰者设计模式相比生成的子类显得更为灵活。
- 设计初衷:Java中通常使用继承来达到扩充功能的目的,如果需要实现的功能种类繁多,势必会扩充出很多子类,这增加了系统的复杂性,而且如果要使用继承来扩充功能,那么这些功能在编译时候就已经确定了,我们必须预见这些功能,是静态的。
乱码问题分析
- 在从前端表单提交数据时,采用GET方法和POST方法在后端进行的解决乱码的方式有所区别。Tomcat内部传输数据是默认使用的编码方式为ISO-8859-1,不支持中文。
- 假如是GET方法提交,则要在后台先进行先编码再解码的方式,解决乱码问题。
parameter=new String(parameter.getBytes("iso8859-1"),"UTF-8");
,用String对象的getBytes()方法,先将获取到的数据进行ISO-8859-1编码,然后再用UTF-8进行解码,来获取中文。 - 假如是POST方法提交,在后台中只需要
request.setCharacterEncoding("UTF-8");
,这句代码就有可以解决POST方法提交表单时产生的中文乱码问题。
Filter的引入
- 假如我们一个项目要定义很多的Servlet,在每个业务中都要根据表单的提交方式来用响应的代码解决乱码问题,从软件工程的角度来讲,我们的项目中就产生了大量的重复的代码。这个时候我们就需要用Filter过滤器来实现全局编码的过滤。在我们的Web应用服务器中,访问资源的流程一般为(假如配置了全局的过滤器),前端的request请求先经过实现的Filter类,然后经过doFilter()方法放行后在找到相应的servlet进行资源的访问。我们就可以在个全局的Filter中对前端发送过来的数据进行编码处理,以结局乱码问题,这样就减少了大量的重复的代码。
- Filter的实现过程一般为这样,实现一个Java类,实现Filter借口,并实现其中的doFilter()方法,doFilter()方法中有三个参数,
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
request和response是前端传来的请求和响应,由于是ServletRequest所以在使用时要进行强制类型转换,转换成HttpRequest类型,第三个参数chain负责过滤完毕后执行doFilter()方法,实现类之后要在web.xml中配置,配置规则一般如下,
<filter>
配置完成后就实现了全局编码的功能。
<filter-name>EncodingFilter</filter-name>
<filter-class>com.web.filter.EncodingFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>EncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
在过滤类的内部实现细节中,用到了装饰着设计模式,
public class EncodingFilter implements Filter{
@Override
public void destroy() {
// TODO Auto-generated method stub
}
@Override
public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2)
throws IOException, ServletException {
// TODO Auto-generated method stub
arg0.setCharacterEncoding("UTF-8");
//在传递request之前对request的getparameter方法进行增强
/*
* 装饰着模式(包装)
* 1.增强类与被增强的类要实现同一个接口
* 2.在增强类中传入被增强的类
* 3.需要增强的方法重写,不需要增强的方法调用父类
* */
//被增强的对象
HttpServletRequest request=(HttpServletRequest)arg0;
//增强的对象
EnhanceRequest enhanrequest=new EnhanceRequest(request);
arg2.doFilter(enhanrequest, arg1);
}
@Override
public void init(FilterConfig arg0) throws ServletException {
// TODO Auto-generated method stub
}
}
class EnhanceRequest extends HttpServletRequestWrapper {
private HttpServletRequest request;
public EnhanceRequest(HttpServletRequest request) {
super(request);
this.request=request;
}
//重写getparameter
@Override
public String getParameter(String name) {
String parameter = request.getParameter(name);//乱码
try {
parameter=new String(parameter.getBytes("iso8859-1"),"UTF-8");
} catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return parameter;
}
}
在使用装饰着设计模式中有三个必须注意的地方:1.实现一个增强类,增强类和被增强类要实现同一个接口2.在增强类中要传入被增强的类3.对需要的方法进行重写,对不需要增强的方法直接调用父类的方法。
这样我们就解决了全局编码的乱码问题。