模拟请求
一个Request类来模拟请求对象、一个Response类来模拟响应对象、一个APP类用来模拟请求处理的过程,可以认为是Servlet请求处理的一个简版
package com.seven.filter;
public class Request {
/**
* 请求数据
*/
private String data;
public String getData() {
return data;
}
public void setData(String data) {
this.data = data;
}
}
package com.seven.filter;
public class Response {
/**
* 响应数据
*/
private String data;
public String getData() {
return data;
}
public void setData(String data) {
this.data = data;
}
}
package com.seven.filter;
public class App {
public static void main(String[] args) {
Request request = new Request();
Response response = process(request);
System.out.println(response.getData());
}
/**
* 模拟请求处理全过程
*
* @param request 请求对象【模拟HttpServletRequest对象】
* @return Response 返回对象【模拟HttpServletResponse对象】
*/
private static Response process(Request request) {
Response response = new Response();
response.setData("处理成功");
return response;
}
}
添加功能
- 新增参数校验,判断请求参数中是否包含test字符串,不包含的话直接处理失败
package com.seven.filter;
public class App {
public static void main(String[] args) {
Request request = new Request();
Response response = process(request);
System.out.println(response.getData());
}
/**
* 模拟请求处理全过程
*
* @param request 请求对象【模拟HttpServletRequest对象】
* @return Response 返回对象【模拟HttpServletResponse对象】
*/
private static Response process(Request request) {
Response response = new Response();
if (request != null && request.getData() != null && request.getData().contains("test")) {
response.setData("处理成功");
}
response.setData("处理失败");
return response;
}
}
- 新增日志功能,在请求处理前后添加日志
package com.seven.filter;
public class App {
public static void main(String[] args) {
Request request = new Request();
Response response = process(request);
}
/**
* 模拟请求处理全过程
*
* @param request 请求对象【模拟HttpServletRequest对象】
* @return Response 返回对象【模拟HttpServletResponse对象】
*/
private static Response process(Request request) {
Response response = new Response();
if (request != null && request.getData() != null && request.getData().contains("test")) {
System.out.println("————————开始处理——————————");//模拟日志
response.setData("处理成功");
System.out.println("————————处理结束——————————");//模拟日志
}
response.setData("处理失败");
return response;
}
}
缺点
- 每次新加功能需要改动主方法,违反开闭原则,不易扩展
- 新增的参数校验、日志都不是主要业务逻辑,而却和主要业务代码耦合在一起,经常改动,风险较大
Filter 模式
先回忆下我们使用Filter的情况,Filter是针对请求的,一般是在请求处理前进行拦截,做一些比如统一编码、权限校验、日志记录等功能,我们下面就模拟权限校验(这里用参数检验代替)、日志记录这两项功能,使用Filter模式来模拟上面的功能实现,同时根据FilterChain,我们体会下责任链模式
package com.seven.filter;
public interface Filter {
/**
* 过滤器
* @param request 请求对象
* @param response 返回对象
*/
void doFilter(Request request, Response response,FilterChain chain);
}
package com.seven.filter;
/**
* 参数校验过滤器
*/
public class ParameterValidateFilter implements Filter {
@Override
public void doFilter(Request request, Response response,FilterChain chain) {
if (request != null && request.getData() != null && request.getData().contains("test")) {
chain.doFilter(request,response,chain);
}else {
response.setData("处理失败");
}
}
}
package com.seven.filter;
/**
* 日志过滤器
*/
public class LogFilter implements Filter {
@Override
public void doFilter(Request request, Response response, FilterChain chain) {
System.out.println("————————开始处理——————————");//模拟日志
chain.doFilter(request, response, chain);
System.out.println("————————处理结束——————————");//模拟日志
}
}
package com.seven.filter;
import java.util.ArrayList;
import java.util.List;
/**
* 过滤器链【执行责任链模式的主要成员】
*/
public class FilterChain implements Filter{
/**
* 过滤器列表
*/
private List<Filter> filters = new ArrayList<>();
private int index=;
/**
* 添加过滤器
* @param filter
*/
public void addFilter(Filter filter) {
filters.add(filter);
}
@Override
public void doFilter(Request request, Response response,FilterChain chain) {
if(index==filters.size()){
/**
* 真正处理请求
*/
response.setData("处理成功");
return;
}
Filter filter = filters.get(index);
index++;
filter.doFilter(request,response,chain);
}
}
package com.seven.filter;
public class App {
public static void main(String[] args) {
Request request = new Request();
request.setData("test");
process(request);
}
/**
* 模拟请求处理全过程
*
* @param request 请求对象【模拟HttpServletRequest对象】
* @return Response 返回对象【模拟HttpServletResponse对象】
*/
private static Response process(Request request) {
Response response = new Response();
FilterChain chain = new FilterChain();
chain.addFilter(new ParameterValidateFilter());
chain.addFilter(new LogFilter());
chain.doFilter(request, response, chain);
return response;
}
}
————————开始处理——————————
处理成功
————————处理结束——————————
总结
- Filter是针对请求进行拦截、意在请求前进行一些过滤、权限校验、日志记录、统一编码等
- 所有Filter统一在FilterChain中组成一个链条,然后调用也统一由FilterChain来协调,确保以链条的模式执行
- 责任链模式是一种重要的设计模式,如Servlet中的Filter模式、Mybatis中的Plugin模式等都是责任链模式的体现
微信公众号:宋坤明
下面的是我的公众号二维码图片,欢迎关注。