A Servlet Filter that enables AOP-style "around" advice for a ServletRequest via
{@link #preHandle(javax.servlet.ServletRequest, javax.servlet.ServletResponse) preHandle},
{@link #postHandle(javax.servlet.ServletRequest, javax.servlet.ServletResponse) postHandle},
and {@link #afterCompletion(javax.servlet.ServletRequest, javax.servlet.ServletResponse, Exception) afterCompletion} hooks.
一个Servlet过滤器,通过{@link #preHandle(javax.servlet。preHandle}, {@link #postHandle(javax.servlet. ServletRequest);ServletRequest, javax.servlet. servletresponse) postHandle}和{@link #afterCompletion(javax.servlet. servletresponse)ServletRequest javax.servlet。ServletResponse, Exception) afterCompletion}钩子,启用aop风格的around
;。
preHandle(ServletRequest request, ServletResponse response) throws Exception
Returns {@code true} if the filter chain should be allowed to continue, {@code false} otherwise. It is called before the chain is actually consulted/executed.
如果允许过滤器链继续,返回{@code true},否则返回{@code false}。它在链真实被查询/执行之前被调用。
protected boolean preHandle(ServletRequest request, ServletResponse response) throws Exception {
return true;
}
postHandle(ServletRequest request, ServletResponse response) throws Exception
Allows ‘post’ advice logic to be called, but only if no exception occurs during filter chain execution. That is, if {@link #executeChain executeChain} throws an exception, this method will never be called. Be aware of this when implementing logic. Most resource ‘cleanup’ behavior is often done in the {@link #afterCompletion(javax.servlet.ServletRequest, javax.servlet.ServletResponse, Exception) afterCompletion(request,response,exception)} implementation, which is guaranteed to be called for every request, even when the chain processing throws an Exception.
允许’post’通知逻辑被调用,但只有在过滤器链执行期间没有异常发生。也就是说,如果{@link #executeChain executeChain}抛出一个异常,这个方法将永远不会被调用。在实现逻辑时要注意这一点。大多数资源“清理”行为通常在{@link #afterCompletion(javax.servlet。ServletRequest javax.servlet。afterCompletion(request,response, Exception)}实现,它保证每个请求都会被调用,即使链处理抛出一个Exception。
@SuppressWarnings({"UnusedDeclaration"})
protected void postHandle(ServletRequest request, ServletResponse response) throws Exception {
}
executeChain(ServletRequest request, ServletResponse response, FilterChain chain) throws Exception
Actually executes the specified filter chain by calling
chain.doFilter(request,response);
. Can be overridden by subclasses for custom logic.
通过调用chain. dofilter (request,response);可以由自定义逻辑的子类覆盖。
实现过滤逻辑的部分
protected void executeChain(ServletRequest request, ServletResponse response, FilterChain chain) throws Exception {
chain.doFilter(request, response);
}
afterCompletion(ServletRequest request, ServletResponse response, Exception exception) throws Exception
Called in all cases in a {@code finally} block even if {@link #preHandle preHandle} returns {@code false} or if an exception is thrown during filter chain processing. Can be used for resource cleanup if so desired. The default implementation does nothing (no-op) and exists as a template method for subclasses.
在所有情况下,在{@code finally}块中调用,即使{@link #preHandle preHandle}返回{@code false},或者在过滤链处理过程中抛出异常。如果需要,可以用于资源清理
。默认实现不执行任何操作(no-op),而是作为子类的模板方法存在。
@SuppressWarnings({"UnusedDeclaration"})
public void afterCompletion(ServletRequest request, ServletResponse response, Exception exception) throws Exception {
}
doFilterInternal(ServletRequest request, ServletResponse response, FilterChain chain) throws ServletException, IOException
实际实现链执行逻辑,利用
{@link #preHandle(javax.servlet.ServletRequest, javax.servlet.ServletResponse) preHandle},
{@link #postHandle(javax.servlet.ServletRequest, javax.servlet.ServletResponse) postHandle},
and {@link #afterCompletion(javax.servlet.ServletRequest, javax.servlet.ServletResponse, Exception) afterCompletion}钩子
public void doFilterInternal(ServletRequest request, ServletResponse response, FilterChain chain)
throws ServletException, IOException {
Exception exception = null;
try {
//过滤器执行前的逻辑处理完,是否还可以继续执行
boolean continueChain = preHandle(request, response);
if (log.isTraceEnabled()) {
log.trace("Invoked preHandle method. Continuing chain?: [" + continueChain + "]");
}
//执行过滤
if (continueChain) {
executeChain(request, response, chain);
}
postHandle(request, response);
if (log.isTraceEnabled()) {
log.trace("Successfully invoked postHandle method");
}
} catch (Exception e) {
exception = e;
} finally {
cleanup(request, response, exception);
}
}
Executes cleanup logic in the {@code finally} code block in the {@link #doFilterInternal(javax.servlet.ServletRequest, javax.servlet.ServletResponse, javax.servlet.FilterChain) doFilterInternal} implementation.
在{@link #doFilterInternal(javax.servlet.)中{@code finally}代码块中执行清理逻辑
。ServletRequest javax.servlet。javax.servlet.FilterChain) doFilterInternal}实现。
protected void cleanup(ServletRequest request, ServletResponse response, Exception existing)
throws ServletException, IOException {
Exception exception = existing;
try {
afterCompletion(request, response, exception);
if (log.isTraceEnabled()) {
log.trace("Successfully invoked afterCompletion method.");
}
} catch (Exception e) {
if (exception == null) {
exception = e;
} else {
log.debug("afterCompletion implementation threw an exception. This will be ignored to " +
"allow the original source exception to be propagated.", e);
}
}
if (exception != null) {
if (exception instanceof ServletException) {
throw (ServletException) exception;
} else if (exception instanceof IOException) {
throw (IOException) exception;
} else {
if (log.isDebugEnabled()) {
String msg = "Filter execution resulted in an unexpected Exception " +
"(not IOException or ServletException as the Filter API recommends). " +
"Wrapping in ServletException and propagating.";
log.debug(msg);
}
throw new ServletException(exception);
}
}
}
总结这个类可以做的事情:
1.使用AOP的around方式来使用过滤器