天天看点

设计模式 - 责任链模式

概念

将请求的发送和接收解耦,让多个接收对象都有机会处理这个请求。将这些接收对象串成一条链,并沿着这条链传递这个请求,直到链上的某个接收对象能够处理它为止。

常见例子

Servlet Filter、Spring Interceptor均使用此设计模式,

最常见的是javax.servlet.Filter,Servlet Filter 是 Java Servlet 规范中定义的组件,翻译成中文就是过滤器,它可以实现对 HTTP 请求的过滤功能,比如鉴权、限流、记录日志、验证参数等。

假如要实现一个Filter,功能是针对所有的rest接口进行签名验证,签名正确的执行接口逻辑,错误的返回错误信息。我们只需要实现Filter接口即可。

@Component
public class RestSecurityFilter implements Filter {
	private static final Logger logger = LoggerFactory.getLogger(RestSecurityFilter.class);

	@Override
	public void init(FilterConfig filterConfig) throws ServletException {
		// TODO Auto-generated method stub

	}

	@Override
	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
			throws IOException, ServletException {

		if (request instanceof HttpServletRequest) {
			// 校验安全性
			HttpServletRequest httpReq = (HttpServletRequest) request;
			RequestMatcher matcher = new AntPathRequestMatcher("/rest/**");
			if(matcher.matches(httpReq)) {
				String sign = httpReq.getHeader("sign");
				// 具体签名算法略...
				boolean passed = validate(httpReq);
				// 校验不通过,返回错误信息,不再执行下一职责
				if (!passed) {
					HttpServletResponse rp = (HttpServletResponse) response;
					rp.setStatus(HttpStatus.SC_BAD_REQUEST);
					rp.addHeader("restful validate error",
							" 400 , Method Not Allowed,please check restful called paramters ! ");
					rp.getWriter()
							.write("Method Not Allowed,please check restful called paramters !");
					return;
				}
			}
		}
		// 放行,执行下一Filter
		chain.doFilter(request, response);
	}

	@Override
	public void destroy() {
		// TODO Auto-generated method stub

	}

}

           

web.xml中配置

<filter>
	    <filter-name>restSecurityFilter</filter-name>
	    <filter-class>com.xxx.filter.restSecurityFilter</filter-class>
	</filter>
	<filter-mapping>
	    <filter-name>restSecurityFilter</filter-name>
	    <url-pattern>/rest/*</url-pattern>
	</filter-mapping>
           

需求场景

代码示例

public class CalibrateHandlerChain {
    private CalibrateHandler head = null;
    private CalibrateHandler tail = null;

    public void addHandler(CalibrateHandler handler) {
        handler.setNextHandler(null);
        if (head == null) {
            head = handler;
            tail = handler;
            return;
        }
        tail.setNextHandler(handler);
        tail = handler;
    }

    public void process(List<Company> companyList) {
        if (head != null) {
            head.process(companyList);
        }
    }

}
           
@Component
public abstract class CalibrateHandler {

    /**
     * next handler,此处使用链表方式实现,也可使用数组
     */
    protected CalibrateHandler nextHandler = null;

    public void setNextHandler(CalibrateHandler calibrateHandler) {
        this.nextHandler = calibrateHandler;
    }

    /**
     * loop execution the method of calibrateHandlerChain
     */
    public final void process(List<Company> companyList) {
		// 执行当前的handle,执行完成后,进入下一handler
        doHandle(companyList);
        if (nextHandler != null) {
            nextHandler.process(companyList);
        }
    }

    /**
     * abstract method subclass to impl
     *
     * @param companyList
     */
    protected abstract void doHandle(List<Company> companyList);

}

           
@Component
@Order(1)
public class XXXHandler extends CalibrateHandler {

    @Override
    protected void doHandle(List<Company> companyList) {
        // 企业名称匹配

    }
}

@Component
@Order(2)
public class YYYHandler extends CalibrateHandler {

    @Override
    protected void doHandle(List<Company> companyList) {
        // 社会统一信用代码匹配

    }
}

...
           
@Service
public class xxxService {
    @Autowired
    private List<CalibrateHandler> calibrateHandlerList;
	
	public void calibrateCompany(List<Company> companyList) {
		CalibrateHandlerChain chain = new CalibrateHandlerChain();
		// calibrateHandlerList中元素按照@Order排序,依次加入责任链
		calibrateHandlerList.forEach(handler -> chain.addHandler(handler));
		chain.process(companyList);
	}

}