译者注:
为什么用DelegatingFilterProxy?窃以为,这样子做可以将DelegatingFilterProxy所代理的filter可以作为spring的bean,受到
spring的管理。而且有一点,我觉得应该注意的是,因为web应用的启动顺序是:listener->filter->servlet的,而spring容器的
启动主要是通过以下两种方式实现的:启动ContextLoaderListener或者ContextLoaderServlet的,所以,要将
将DelegatingFilterProxy所代理的filter可以作为spring的bean的话,就必须使用
启动ContextLoaderListener的方式。
by kaiwii
/**
* Proxy for a standard Servlet 2.3 Filter, delegating to a Spring-managed
* bean that implements the Filter interface. Supports a "targetBeanName"
* filter init-param in <code>web.xml</code>, specifying the name of the
* target bean in the Spring application context.
*翻译:
类DelegatingFilterProxy作为标准的Servlet 2.3 Filter的代理,但是Filter的实际工作是通过将任务
委派给spring管理的而且实现了Filter接口的bean来完成的。通过在web.xml文件的名为"targetBeanName"
的filter的init-param变量来指定到底Spring容器(Spring application context)中哪个bean来作为实际执行
filter任务的bean(target bean)。
* <p><code>web.xml</code> will usually contain a DelegatingFilterProxy definition,
* with the specified <code>filter-name</code> corresponding to a bean name in
* Spring's root application context. All calls to the filter proxy will then
* be delegated to that bean in the Spring context, which is required to implement
* the standard Servlet 2.3 Filter interface.
翻译:
web.xml通常会包括DelegatingFilterProxy的定义,其中的filter-name项会对应spring容器中的一个bean的名字。
所有的调用请求都会首先发送到这个filter代理中去,然后再委派到spring容器中的这个bean,当然,这个bean必须要
实现标准的Servlet 2.3 Filter 接口。
*
* <p>This approach is particularly useful for Filter implementation with complex
* setup needs, allowing to apply the full Spring bean definition machinery to
* Filter instances. Alternatively, consider standard Filter setup in combination
* with looking up service beans from the Spring root application context.
*翻译:
如果需要将Spring的bean命名机制应用到Filter实例上来完成复杂得启动任务,使用类DelegatingFilterProxy
就是一个很好的选择。除此之外,当标准的FIlter启动的时候需要使用到Spring容器里面的service bean的时候,
使用类DelegatingFilterProxy也是一个很好的选择。
* <p><b>NOTE:</b> The lifecycle methods defined by the Servlet Filter interface
* will by default <i>not</i> be delegated to the target bean, relying on the
* Spring application context to manage the lifecycle of that bean. Specifying
* the "targetFilterLifecycle" filter init-param as "true" will enforce invocation
* of the <code>Filter.init</code> and <code>Filter.destroy</code> lifecycle methods
* on the target bean, letting the servlet container manage the filter lifecycle.
*翻译:
注意:Servlet Filter 接口中定义的生命周期函数默认不会被target bean自己执行(指:不是由服务器容器来调用),而是由spring容器(Spring application context )
执行来管理这个bean的生命周期。如果将名为"targetFilterLifecycle"的filter init-param参数设定为"true"的时候,target bean的Filter.init和Filter.destroy的
生命周期函数的调用就可以被执行了,换句话说,服务器容器(servlet container )就可以管理filter的生命周期了。
* <p>This class is inspired by Acegi Security's FilterToBeanProxy class,
* written by Ben Alex.
翻译:
这个类原型是FilterToBeanProxy 类
*
* @author Juergen Hoeller
* @author Sam Brannen
* @author 译者:kaiwii
* @since 1.2
* @see #setTargetBeanName
* @see #setTargetFilterLifecycle
* @see javax.servlet.Filter#doFilter
* @see javax.servlet.Filter#init
* @see javax.servlet.Filter#destroy
*/
public class DelegatingFilterProxy extends GenericFilterBean {
private String contextAttribute;
private String targetBeanName;
private boolean targetFilterLifecycle = false;
private Filter delegate;
private final Object delegateMonitor = new Object();
/**
* Set the name of the ServletContext attribute which should be used to retrieve the
* {@link WebApplicationContext} from which to load the delegate{@link Filter} bean.
*/
public void setContextAttribute(String contextAttribute) {
this.contextAttribute = contextAttribute;
}
/**
* Return the name of the ServletContext attribute which should be used to retrieve the
* {@link WebApplicationContext} from which to load the delegate{@link Filter} bean.
*/
public String getContextAttribute() {
return this.contextAttribute;
}
/**
* Set the name of the target bean in the Spring application context.
* The target bean must implement the standard Servlet 2.3 Filter interface.
* <p>By default, the <code>filter-name</code> as specified for the
* DelegatingFilterProxy in <code>web.xml</code> will be used.
*/
public void setTargetBeanName(String targetBeanName) {
this.targetBeanName = targetBeanName;
}
/**
* Return the name of the target bean in the Spring application context.
*/
protected String getTargetBeanName() {
return this.targetBeanName;
}
/**
* Set whether to invoke the <code>Filter.init</code> and
* <code>Filter.destroy</code> lifecycle methods on the target bean.
* <p>Default is "false"; target beans usually rely on the Spring application
* context for managing their lifecycle. Setting this flag to "true" means
* that the servlet container will control the lifecycle of the target
* Filter, with this proxy delegating the corresponding calls.
*/
public void setTargetFilterLifecycle(boolean targetFilterLifecycle) {
this.targetFilterLifecycle = targetFilterLifecycle;
}
/**
* Return whether to invoke the <code>Filter.init</code> and
* <code>Filter.destroy</code> lifecycle methods on the target bean.
*/
protected boolean isTargetFilterLifecycle() {
return this.targetFilterLifecycle;
}
protected void initFilterBean() throws ServletException {
// If no target bean name specified, use filter name.
if (this.targetBeanName == null) {
this.targetBeanName = getFilterName();
}
// Fetch Spring root application context and initialize the delegate early,
// if possible. If the root application context will be started after this
// filter proxy, we'll have to resort to lazy initialization.
synchronized (this.delegateMonitor) {
WebApplicationContext wac = findWebApplicationContext();
if (wac != null) {
this.delegate = initDelegate(wac);
}
}
}
public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain)
throws ServletException, IOException {
// Lazily initialize the delegate if necessary.
Filter delegateToUse = null;
synchronized (this.delegateMonitor) {
if (this.delegate == null) {
WebApplicationContext wac = findWebApplicationContext();
if (wac == null) {
throw new IllegalStateException("No WebApplicationContext found: no ContextLoaderListener registered?");
}
this.delegate = initDelegate(wac);
}
delegateToUse = this.delegate;
}
// Let the delegate perform the actual doFilter operation.
invokeDelegate(delegateToUse, request, response, filterChain);
}
public void destroy() {
Filter delegateToUse = null;
synchronized (this.delegateMonitor) {
delegateToUse = this.delegate;
}
if (delegateToUse != null) {
destroyDelegate(delegateToUse);
}
}
/**
* Retrieve a <code>WebApplicationContext</code> from the <code>ServletContext</code>
* attribute with the {@link #setContextAttribute configured name}. The
* <code>WebApplicationContext</code> must have already been loaded and stored in the
* <code>ServletContext</code> before this filter gets initialized (or invoked).
* <p>Subclasses may override this method to provide a different
* <code>WebApplicationContext</code> retrieval strategy.
* @return the WebApplicationContext for this proxy, or <code>null</code> if not found
* @see #getContextAttribute()
*/
protected WebApplicationContext findWebApplicationContext() {
String attrName = getContextAttribute();
if (attrName != null) {
return WebApplicationContextUtils.getWebApplicationContext(getServletContext(), attrName);
}
else {
return WebApplicationContextUtils.getWebApplicationContext(getServletContext());
}
}
/**
* Initialize the Filter delegate, defined as bean the given Spring
* application context.
* <p>Default implementation fetches the bean from the application context
* and calls the standard <code>Filter.init</code> method on it, passing
* in the FilterConfig of this Filter proxy.
* @param wac the root application context
* @return the initialized delegate Filter
* @throws ServletException if thrown by the Filter
* @see #getTargetBeanName()
* @see #isTargetFilterLifecycle()
* @see #getFilterConfig()
* @see javax.servlet.Filter#init(javax.servlet.FilterConfig)
*/
protected Filter initDelegate(WebApplicationContext wac) throws ServletException {
Filter delegate = (Filter) wac.getBean(getTargetBeanName(), Filter.class);
if (isTargetFilterLifecycle()) {
delegate.init(getFilterConfig());
}
return delegate;
}
/**
* Actually invoke the delegate Filter with the given request and response.
* @param delegate the delegate Filter
* @param request the current HTTP request
* @param response the current HTTP response
* @param filterChain the current FilterChain
* @throws ServletException if thrown by the Filter
* @throws IOException if thrown by the Filter
*/
protected void invokeDelegate(
Filter delegate, ServletRequest request, ServletResponse response, FilterChain filterChain)
throws ServletException, IOException {
delegate.doFilter(request, response, filterChain);
}
/**
* Destroy the Filter delegate.
* Default implementation simply calls <code>Filter.destroy</code> on it.
* @param delegate the Filter delegate (never <code>null</code>)
* @see #isTargetFilterLifecycle()
* @see javax.servlet.Filter#destroy()
*/
protected void destroyDelegate(Filter delegate) {
if (isTargetFilterLifecycle()) {
delegate.destroy();
}
}
}
相关推荐
4. **拦截器与过滤器**:Spring Security使用一系列自定义的Servlet过滤器,如`DelegatingFilterProxy`、`ChannelProcessingFilter`、`RememberMeAuthenticationFilter`等,这些过滤器在HTTP请求生命周期的不同阶段...
- `DelegatingFilterProxy`:Spring提供的Filter,用于代理Spring的Bean,例如Spring Security的Filter链。 - 编写自定义Filter:扩展`javax.servlet.Filter`类,实现`doFilter`方法,然后在`web.xml`中配置。 3....
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class> <filter-mapping> <filter-name>jcaptchaFilter</filter-name> <url-pattern>/login</url-pattern> </filter-mapping> ...
然后,通过Spring的`DelegatingFilterProxy`将请求转发到Struts2的`FilterDispatcher`,并利用Spring的AOP处理事务。 总的来说,SSH框架的整合涉及大量的配置和依赖管理,但一旦设置完成,可以为开发者提供强大的...
DelegatingFilterProxy DelegatingIntroductionInterceptor DelegatingJob DelegatingMessageSource DelegatingNavigationHandlerProxy DelegatingPhaseListenerMulticaster DelegatingRequestProcessor ...
- Shiro 的 Filter 配置在 Spring MVC 中,可以通过 `DelegatingFilterProxy` 注册到 Web 应用的 Filter 链中。 5. **Spring 集成示例** - 在 Spring XML 配置文件中,创建 `SecurityManager` 实例,并注入自定义...
5. 可能还需要`slf4j-api.jar`和相应的日志实现库(如`logback-classic.jar`或`log4j.jar`),因为这些库用于处理日志输出。 **配置步骤**: 1. **添加jar包**:将以上提到的jar包放入Tomcat7的`lib`目录,这样...
【Spring Security 框架详解】 Spring Security 是一个强大的、...相较于Acegi,Spring Security 提供了更多的特性,如对最新Java版本的支持,更丰富的API和扩展性,使其成为现代Java EE应用开发中首选的安全框架。
在SpringMVC中,过滤器可以通过在web.xml配置文件中声明,或者使用Spring的DelegatingFilterProxy来注册,后者允许我们利用Spring的依赖注入和AOP特性。 现在,让我们关注日志记录。在Java中,常见的日志框架有Log4...
`DelegatingFilterProxy`用于将Spring Security的过滤器注入到Servlet容器中,`FilterSecurityInterceptor`则是执行实际安全检查的关键过滤器。 4. **UserDetailsService**:这是获取用户信息的服务接口,用于从...
7. **工具支持**:Spring Security提供了丰富的工具类和API,如`SecurityContextHolder`用于获取当前安全上下文,`AccessDecisionManager`用于决策访问权限,以及`ExpressionBasedAccessDecisionManager`支持基于...
servlet-api-provision B.1.1.2. path-type B.1.1.3. lowercase-comparisons B.1.1.4. realm B.1.1.5. entry-point-ref B.1.1.6. access-decision-manager-ref B.1.1.7. access-denied-page B.1.1.8. once-...
cannot be cast to javax.servlet.Filter 报错, 原因servlet-api.jar冲突 使用maven开发web应用程序, 启动的时候报错: jar not loaded. See Servlet Spec 2.3, section 9.7.2. Offending class: javax/servlet/...
3. **会话管理(Session Management)**:Shiro可以管理跨请求的用户状态,提供了一套独立于具体容器的会话API。 4. **加密(Cryptography)**:Shiro提供了多种加密工具和服务,用于密码存储、数据加密等。 在...
1. **spring-security-config**:这个模块提供了配置Spring Security的核心API。它包含安全元数据(如`@Secured`和`@PreAuthorize`注解)和XML配置元素,如`<http>`和`<authentication-manager>`,用于定义安全策略...
8. **API和XML配置**:Spring Security 提供了丰富的API供开发者使用,同时也可以通过XML配置进行详细的定制。在3.2.4版本中,XML配置仍然是主流,但已经开始向基于Java的配置过渡。 9. **Web安全**:Spring ...
当配置完成后,开发者可以像往常一样使用标准的Servlet API来获取和设置Session,而底层则会通过Spring-Session将这些信息存储在Redis中。 下面展示了一个简单的示例,该示例演示了如何在控制器中设置Session: ``...
- Spring官方文档:详尽的指南和API参考,是学习Spring Security的重要资料。 - 社区支持:Stack Overflow、GitHub等社区有大量的问题解答和示例代码,有助于解决实际问题。 总的来说,Spring Security 3.1.3....
在处理与数据库交互方面,Spring Security提供了更强大的支持,包括长期的remember-me功能和基于数据库的角色与用户管理API。 24.2. 目标 在原有应用中,用户信息和资源访问控制已经在数据库中管理。目标是将现有...
相比于 Spring Security,Shiro 提供了更加简洁直观的 API 接口,能够很好地与多种应用环境进行集成,包括 Web 应用、Java 应用以及移动应用等。Shiro 的核心特性之一是它的 Native Session 机制,这种机制使得 ...