Add DelegatingFilterProxyRegistrationBean

Add a RegistrationBean that can be used to create DelegatingFilterProxy
filters that don't cause early initialization.

Fixes gh-4165
This commit is contained in:
Phillip Webb 2015-10-13 23:09:09 -07:00
parent a7bdef61de
commit a3f978793e
9 changed files with 794 additions and 431 deletions

View File

@ -0,0 +1,278 @@
/*
* Copyright 2012-2015 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.boot.context.embedded;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.EnumSet;
import java.util.LinkedHashSet;
import java.util.Set;
import javax.servlet.DispatcherType;
import javax.servlet.Filter;
import javax.servlet.FilterRegistration;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.util.Assert;
/**
* Abstract base {@link ServletContextInitializer} to register {@link Filter}s in a
* Servlet 3.0+ container.
*
* @author Phillip Webb
*/
abstract class AbstractFilterRegistrationBean extends RegistrationBean {
/**
* Filters that wrap the servlet request should be ordered less than or equal to this.
*/
protected static final int REQUEST_WRAPPER_FILTER_MAX_ORDER = 0;
private final Log logger = LogFactory.getLog(getClass());
static final EnumSet<DispatcherType> ASYNC_DISPATCHER_TYPES = EnumSet.of(
DispatcherType.FORWARD, DispatcherType.INCLUDE, DispatcherType.REQUEST,
DispatcherType.ASYNC);
static final EnumSet<DispatcherType> NON_ASYNC_DISPATCHER_TYPES = EnumSet
.of(DispatcherType.FORWARD, DispatcherType.INCLUDE, DispatcherType.REQUEST);
private static final String[] DEFAULT_URL_MAPPINGS = { "/*" };
private Set<ServletRegistrationBean> servletRegistrationBeans = new LinkedHashSet<ServletRegistrationBean>();
private Set<String> servletNames = new LinkedHashSet<String>();
private Set<String> urlPatterns = new LinkedHashSet<String>();
private EnumSet<DispatcherType> dispatcherTypes;
private boolean matchAfter = false;
/**
* Create a new instance to be registered with the specified
* {@link ServletRegistrationBean}s.
* @param servletRegistrationBeans associate {@link ServletRegistrationBean}s
*/
AbstractFilterRegistrationBean(ServletRegistrationBean... servletRegistrationBeans) {
Assert.notNull(servletRegistrationBeans,
"ServletRegistrationBeans must not be null");
Collections.addAll(this.servletRegistrationBeans, servletRegistrationBeans);
}
/**
* Set {@link ServletRegistrationBean}s that the filter will be registered against.
* @param servletRegistrationBeans the Servlet registration beans
*/
public void setServletRegistrationBeans(
Collection<? extends ServletRegistrationBean> servletRegistrationBeans) {
Assert.notNull(servletRegistrationBeans,
"ServletRegistrationBeans must not be null");
this.servletRegistrationBeans = new LinkedHashSet<ServletRegistrationBean>(
servletRegistrationBeans);
}
/**
* Return a mutable collection of the {@link ServletRegistrationBean} that the filter
* will be registered against. {@link ServletRegistrationBean}s.
* @return the Servlet registration beans
* @see #setServletNames
* @see #setUrlPatterns
*/
public Collection<ServletRegistrationBean> getServletRegistrationBeans() {
return this.servletRegistrationBeans;
}
/**
* Add {@link ServletRegistrationBean}s for the filter.
* @param servletRegistrationBeans the servlet registration beans to add
* @see #setServletRegistrationBeans
*/
public void addServletRegistrationBeans(
ServletRegistrationBean... servletRegistrationBeans) {
Assert.notNull(servletRegistrationBeans,
"ServletRegistrationBeans must not be null");
Collections.addAll(this.servletRegistrationBeans, servletRegistrationBeans);
}
/**
* Set servlet names that the filter will be registered against. This will replace any
* previously specified servlet names.
* @param servletNames the servlet names
* @see #setServletRegistrationBeans
* @see #setUrlPatterns
*/
public void setServletNames(Collection<String> servletNames) {
Assert.notNull(servletNames, "ServletNames must not be null");
this.servletNames = new LinkedHashSet<String>(servletNames);
}
/**
* Return a mutable collection of servlet names that the filter will be registered
* against.
* @return the servlet names
*/
public Collection<String> getServletNames() {
return this.servletNames;
}
/**
* Add servlet names for the filter.
* @param servletNames the servlet names to add
*/
public void addServletNames(String... servletNames) {
Assert.notNull(servletNames, "ServletNames must not be null");
this.servletNames.addAll(Arrays.asList(servletNames));
}
/**
* Set the URL patterns that the filter will be registered against. This will replace
* any previously specified URL patterns.
* @param urlPatterns the URL patterns
* @see #setServletRegistrationBeans
* @see #setServletNames
*/
public void setUrlPatterns(Collection<String> urlPatterns) {
Assert.notNull(urlPatterns, "UrlPatterns must not be null");
this.urlPatterns = new LinkedHashSet<String>(urlPatterns);
}
/**
* Return a mutable collection of URL patterns that the filter will be registered
* against.
* @return the URL patterns
*/
public Collection<String> getUrlPatterns() {
return this.urlPatterns;
}
/**
* Add URL patterns that the filter will be registered against.
* @param urlPatterns the URL patterns
*/
public void addUrlPatterns(String... urlPatterns) {
Assert.notNull(urlPatterns, "UrlPatterns must not be null");
Collections.addAll(this.urlPatterns, urlPatterns);
}
/**
* Convenience method to {@link #setDispatcherTypes(EnumSet) set dispatcher types}
* using the specified elements.
* @param first the first dispatcher type
* @param rest additional dispatcher types
*/
public void setDispatcherTypes(DispatcherType first, DispatcherType... rest) {
this.dispatcherTypes = EnumSet.of(first, rest);
}
/**
* Sets the dispatcher types that should be used with the registration. If not
* specified the types will be deduced based on the value of
* {@link #isAsyncSupported()}.
* @param dispatcherTypes the dispatcher types
*/
public void setDispatcherTypes(EnumSet<DispatcherType> dispatcherTypes) {
this.dispatcherTypes = dispatcherTypes;
}
/**
* Set if the filter mappings should be matched after any declared filter mappings of
* the ServletContext. Defaults to {@code false} indicating the filters are supposed
* to be matched before any declared filter mappings of the ServletContext.
* @param matchAfter if filter mappings are matched after
*/
public void setMatchAfter(boolean matchAfter) {
this.matchAfter = matchAfter;
}
/**
* Return if filter mappings should be matched after any declared Filter mappings of
* the ServletContext.
* @return if filter mappings are matched after
*/
public boolean isMatchAfter() {
return this.matchAfter;
}
@Override
public void onStartup(ServletContext servletContext) throws ServletException {
Filter filter = getFilter();
Assert.notNull(filter, "Filter must not be null");
String name = getOrDeduceName(filter);
if (!isEnabled()) {
this.logger.info("Filter " + name + " was not registered (disabled)");
return;
}
FilterRegistration.Dynamic added = servletContext.addFilter(name, filter);
if (added == null) {
this.logger.info("Filter " + name + " was not registered "
+ "(possibly already registered?)");
return;
}
configure(added);
}
/**
* Return the {@link Filter} to be registered.
* @return the filter
*/
protected abstract Filter getFilter();
/**
* Configure registration settings. Subclasses can override this method to perform
* additional configuration if required.
* @param registration the registration
*/
protected void configure(FilterRegistration.Dynamic registration) {
super.configure(registration);
EnumSet<DispatcherType> dispatcherTypes = this.dispatcherTypes;
if (dispatcherTypes == null) {
dispatcherTypes = (isAsyncSupported() ? ASYNC_DISPATCHER_TYPES
: NON_ASYNC_DISPATCHER_TYPES);
}
Set<String> servletNames = new LinkedHashSet<String>();
for (ServletRegistrationBean servletRegistrationBean : this.servletRegistrationBeans) {
servletNames.add(servletRegistrationBean.getServletName());
}
servletNames.addAll(this.servletNames);
if (servletNames.isEmpty() && this.urlPatterns.isEmpty()) {
this.logger.info("Mapping filter: '" + registration.getName() + "' to: "
+ Arrays.asList(DEFAULT_URL_MAPPINGS));
registration.addMappingForUrlPatterns(dispatcherTypes, this.matchAfter,
DEFAULT_URL_MAPPINGS);
}
else {
if (servletNames.size() > 0) {
this.logger.info("Mapping filter: '" + registration.getName()
+ "' to servlets: " + servletNames);
registration.addMappingForServletNames(dispatcherTypes, this.matchAfter,
servletNames.toArray(new String[servletNames.size()]));
}
if (this.urlPatterns.size() > 0) {
this.logger.info("Mapping filter: '" + registration.getName()
+ "' to urls: " + this.urlPatterns);
registration.addMappingForUrlPatterns(dispatcherTypes, this.matchAfter,
this.urlPatterns.toArray(new String[this.urlPatterns.size()]));
}
}
}
}

View File

@ -0,0 +1,96 @@
/*
* Copyright 2012-2015 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.boot.context.embedded;
import javax.servlet.Filter;
import javax.servlet.ServletContext;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.util.Assert;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.filter.DelegatingFilterProxy;
/**
* A {@link ServletContextInitializer} to register {@link DelegatingFilterProxy}s in a
* Servlet 3.0+ container. Similar to the {@link ServletContext#addFilter(String, Filter)
* registration} features provided by {@link ServletContext} but with a Spring Bean
* friendly design.
* <p>
* The bean name of the actual delegate {@link Filter} should be specified using the
* {@code targetBeanName} constructor argument. Unlike the {@link FilterRegistrationBean},
* referenced filters are not instantiated early. In fact, if the delegate filter bean is
* marked {@code @Lazy} it won't be instantiated at all until the filter is called.
* <p>
* Registrations can be associated with {@link #setUrlPatterns URL patterns} and/or
* servlets (either by {@link #setServletNames name} or via a
* {@link #setServletRegistrationBeans ServletRegistrationBean}s. When no URL pattern or
* servlets are specified the filter will be associated to '/*'. The targetBeanName will
* be used as the filter name if not otherwise specified.
*
* @author Phillip Webb
* @since 1.3.0
* @see ServletContextInitializer
* @see ServletContext#addFilter(String, Filter)
* @see FilterRegistrationBean
* @see DelegatingFilterProxy
*/
public class DelegatingFilterProxyRegistrationBean extends AbstractFilterRegistrationBean
implements ApplicationContextAware {
private ApplicationContext applicationContext;
private final String targetBeanName;
/**
* Create a new {@link DelegatingFilterProxyRegistrationBean} instance to be
* registered with the specified {@link ServletRegistrationBean}s.
* @param targetBeanName name of the target filter bean to look up in the Spring
* application context (must not be {@code null}).
* @param servletRegistrationBeans associate {@link ServletRegistrationBean}s
*/
public DelegatingFilterProxyRegistrationBean(String targetBeanName,
ServletRegistrationBean... servletRegistrationBeans) {
super(servletRegistrationBeans);
Assert.hasLength(targetBeanName, "TargetBeanName must not be null or empty");
this.targetBeanName = targetBeanName;
setName(targetBeanName);
}
@Override
public void setApplicationContext(ApplicationContext applicationContext)
throws BeansException {
this.applicationContext = applicationContext;
}
protected String getTargetBeanName() {
return this.targetBeanName;
}
@Override
protected Filter getFilter() {
return new DelegatingFilterProxy(this.targetBeanName, getWebApplicationContext());
}
private WebApplicationContext getWebApplicationContext() {
Assert.notNull(this.applicationContext, "ApplicationContext be injected");
Assert.isInstanceOf(WebApplicationContext.class, this.applicationContext);
return (WebApplicationContext) this.applicationContext;
}
}

View File

@ -16,21 +16,9 @@
package org.springframework.boot.context.embedded;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.EnumSet;
import java.util.LinkedHashSet;
import java.util.Set;
import javax.servlet.DispatcherType;
import javax.servlet.Filter;
import javax.servlet.FilterRegistration;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.util.Assert;
/**
@ -48,37 +36,17 @@ import org.springframework.util.Assert;
* @author Phillip Webb
* @see ServletContextInitializer
* @see ServletContext#addFilter(String, Filter)
* @see DelegatingFilterProxyRegistrationBean
*/
public class FilterRegistrationBean extends RegistrationBean {
public class FilterRegistrationBean extends AbstractFilterRegistrationBean {
/**
* Filters that wrap the servlet request should be ordered less than or equal to this.
*/
public static final int REQUEST_WRAPPER_FILTER_MAX_ORDER = 0;
private static Log logger = LogFactory.getLog(FilterRegistrationBean.class);
static final EnumSet<DispatcherType> ASYNC_DISPATCHER_TYPES = EnumSet.of(
DispatcherType.FORWARD, DispatcherType.INCLUDE, DispatcherType.REQUEST,
DispatcherType.ASYNC);
static final EnumSet<DispatcherType> NON_ASYNC_DISPATCHER_TYPES = EnumSet
.of(DispatcherType.FORWARD, DispatcherType.INCLUDE, DispatcherType.REQUEST);
private static final String[] DEFAULT_URL_MAPPINGS = { "/*" };
public static final int REQUEST_WRAPPER_FILTER_MAX_ORDER = AbstractFilterRegistrationBean.REQUEST_WRAPPER_FILTER_MAX_ORDER;
private Filter filter;
private Set<ServletRegistrationBean> servletRegistrationBeans = new LinkedHashSet<ServletRegistrationBean>();
private Set<String> servletNames = new LinkedHashSet<String>();
private Set<String> urlPatterns = new LinkedHashSet<String>();
private EnumSet<DispatcherType> dispatcherTypes;
private boolean matchAfter = false;
/**
* Create a new {@link FilterRegistrationBean} instance.
*/
@ -93,17 +61,12 @@ public class FilterRegistrationBean extends RegistrationBean {
*/
public FilterRegistrationBean(Filter filter,
ServletRegistrationBean... servletRegistrationBeans) {
super(servletRegistrationBeans);
Assert.notNull(filter, "Filter must not be null");
Assert.notNull(servletRegistrationBeans,
"ServletRegistrationBeans must not be null");
this.filter = filter;
Collections.addAll(this.servletRegistrationBeans, servletRegistrationBeans);
}
/**
* Returns the filter being registered.
* @return the filter
*/
@Override
protected Filter getFilter() {
return this.filter;
}
@ -117,196 +80,4 @@ public class FilterRegistrationBean extends RegistrationBean {
this.filter = filter;
}
/**
* Set {@link ServletRegistrationBean}s that the filter will be registered against.
* @param servletRegistrationBeans the Servlet registration beans
*/
public void setServletRegistrationBeans(
Collection<? extends ServletRegistrationBean> servletRegistrationBeans) {
Assert.notNull(servletRegistrationBeans,
"ServletRegistrationBeans must not be null");
this.servletRegistrationBeans = new LinkedHashSet<ServletRegistrationBean>(
servletRegistrationBeans);
}
/**
* Return a mutable collection of the {@link ServletRegistrationBean} that the filter
* will be registered against. {@link ServletRegistrationBean}s.
* @return the Servlet registration beans
* @see #setServletNames
* @see #setUrlPatterns
*/
public Collection<ServletRegistrationBean> getServletRegistrationBeans() {
return this.servletRegistrationBeans;
}
/**
* Add {@link ServletRegistrationBean}s for the filter.
* @param servletRegistrationBeans the servlet registration beans to add
* @see #setServletRegistrationBeans
*/
public void addServletRegistrationBeans(
ServletRegistrationBean... servletRegistrationBeans) {
Assert.notNull(servletRegistrationBeans,
"ServletRegistrationBeans must not be null");
Collections.addAll(this.servletRegistrationBeans, servletRegistrationBeans);
}
/**
* Set servlet names that the filter will be registered against. This will replace any
* previously specified servlet names.
* @param servletNames the servlet names
* @see #setServletRegistrationBeans
* @see #setUrlPatterns
*/
public void setServletNames(Collection<String> servletNames) {
Assert.notNull(servletNames, "ServletNames must not be null");
this.servletNames = new LinkedHashSet<String>(servletNames);
}
/**
* Return a mutable collection of servlet names that the filter will be registered
* against.
* @return the servlet names
*/
public Collection<String> getServletNames() {
return this.servletNames;
}
/**
* Add servlet names for the filter.
* @param servletNames the servlet names to add
*/
public void addServletNames(String... servletNames) {
Assert.notNull(servletNames, "ServletNames must not be null");
this.servletNames.addAll(Arrays.asList(servletNames));
}
/**
* Set the URL patterns that the filter will be registered against. This will replace
* any previously specified URL patterns.
* @param urlPatterns the URL patterns
* @see #setServletRegistrationBeans
* @see #setServletNames
*/
public void setUrlPatterns(Collection<String> urlPatterns) {
Assert.notNull(urlPatterns, "UrlPatterns must not be null");
this.urlPatterns = new LinkedHashSet<String>(urlPatterns);
}
/**
* Return a mutable collection of URL patterns that the filter will be registered
* against.
* @return the URL patterns
*/
public Collection<String> getUrlPatterns() {
return this.urlPatterns;
}
/**
* Add URL patterns that the filter will be registered against.
* @param urlPatterns the URL patterns
*/
public void addUrlPatterns(String... urlPatterns) {
Assert.notNull(urlPatterns, "UrlPatterns must not be null");
Collections.addAll(this.urlPatterns, urlPatterns);
}
/**
* Convenience method to {@link #setDispatcherTypes(EnumSet) set dispatcher types}
* using the specified elements.
* @param first the first dispatcher type
* @param rest additional dispatcher types
*/
public void setDispatcherTypes(DispatcherType first, DispatcherType... rest) {
this.dispatcherTypes = EnumSet.of(first, rest);
}
/**
* Sets the dispatcher types that should be used with the registration. If not
* specified the types will be deduced based on the value of
* {@link #isAsyncSupported()}.
* @param dispatcherTypes the dispatcher types
*/
public void setDispatcherTypes(EnumSet<DispatcherType> dispatcherTypes) {
this.dispatcherTypes = dispatcherTypes;
}
/**
* Set if the filter mappings should be matched after any declared filter mappings of
* the ServletContext. Defaults to {@code false} indicating the filters are supposed
* to be matched before any declared filter mappings of the ServletContext.
* @param matchAfter if filter mappings are matched after
*/
public void setMatchAfter(boolean matchAfter) {
this.matchAfter = matchAfter;
}
/**
* Return if filter mappings should be matched after any declared Filter mappings of
* the ServletContext.
* @return if filter mappings are matched after
*/
public boolean isMatchAfter() {
return this.matchAfter;
}
@Override
public void onStartup(ServletContext servletContext) throws ServletException {
Assert.notNull(this.filter, "Filter must not be null");
String name = getOrDeduceName(this.filter);
if (!isEnabled()) {
logger.info("Filter " + name + " was not registered (disabled)");
return;
}
FilterRegistration.Dynamic added = servletContext.addFilter(name, this.filter);
if (added == null) {
logger.info("Filter " + name + " was not registered "
+ "(possibly already registered?)");
return;
}
configure(added);
}
/**
* Configure registration settings. Subclasses can override this method to perform
* additional configuration if required.
* @param registration the registration
*/
protected void configure(FilterRegistration.Dynamic registration) {
super.configure(registration);
EnumSet<DispatcherType> dispatcherTypes = this.dispatcherTypes;
if (dispatcherTypes == null) {
dispatcherTypes = (isAsyncSupported() ? ASYNC_DISPATCHER_TYPES
: NON_ASYNC_DISPATCHER_TYPES);
}
Set<String> servletNames = new LinkedHashSet<String>();
for (ServletRegistrationBean servletRegistrationBean : this.servletRegistrationBeans) {
servletNames.add(servletRegistrationBean.getServletName());
}
servletNames.addAll(this.servletNames);
if (servletNames.isEmpty() && this.urlPatterns.isEmpty()) {
logger.info("Mapping filter: '" + registration.getName() + "' to: "
+ Arrays.asList(DEFAULT_URL_MAPPINGS));
registration.addMappingForUrlPatterns(dispatcherTypes, this.matchAfter,
DEFAULT_URL_MAPPINGS);
}
else {
if (servletNames.size() > 0) {
logger.info("Mapping filter: '" + registration.getName()
+ "' to servlets: " + servletNames);
registration.addMappingForServletNames(dispatcherTypes, this.matchAfter,
servletNames.toArray(new String[servletNames.size()]));
}
if (this.urlPatterns.size() > 0) {
logger.info("Mapping filter: '" + registration.getName() + "' to urls: "
+ this.urlPatterns);
registration.addMappingForUrlPatterns(dispatcherTypes, this.matchAfter,
this.urlPatterns.toArray(new String[this.urlPatterns.size()]));
}
}
}
}

View File

@ -31,6 +31,7 @@ import org.springframework.util.Assert;
* @author Phillip Webb
* @see ServletRegistrationBean
* @see FilterRegistrationBean
* @see DelegatingFilterProxyRegistrationBean
* @see ServletListenerRegistrationBean
*/
public abstract class RegistrationBean implements ServletContextInitializer, Ordered {

View File

@ -62,6 +62,9 @@ class ServletContextInitializerBeans
private final Log log = LogFactory.getLog(getClass());
/**
* Seen bean instances or bean names.
*/
private final Set<Object> seen = new HashSet<Object>();
private final MultiValueMap<Class<?>, ServletContextInitializer> initializers;
@ -92,17 +95,26 @@ class ServletContextInitializerBeans
private void addServletContextInitializerBean(String beanName,
ServletContextInitializer initializer, ListableBeanFactory beanFactory) {
if (initializer instanceof ServletRegistrationBean) {
Servlet source = ((ServletRegistrationBean) initializer).getServlet();
addServletContextInitializerBean(Servlet.class, beanName, initializer,
beanFactory, ((ServletRegistrationBean) initializer).getServlet());
beanFactory, source);
}
else if (initializer instanceof FilterRegistrationBean) {
Filter source = ((FilterRegistrationBean) initializer).getFilter();
addServletContextInitializerBean(Filter.class, beanName, initializer,
beanFactory, ((FilterRegistrationBean) initializer).getFilter());
beanFactory, source);
}
else if (initializer instanceof DelegatingFilterProxyRegistrationBean) {
String source = ((DelegatingFilterProxyRegistrationBean) initializer)
.getTargetBeanName();
addServletContextInitializerBean(Filter.class, beanName, initializer,
beanFactory, source);
}
else if (initializer instanceof ServletListenerRegistrationBean) {
EventListener source = ((ServletListenerRegistrationBean<?>) initializer)
.getListener();
addServletContextInitializerBean(EventListener.class, beanName, initializer,
beanFactory,
((ServletListenerRegistrationBean<?>) initializer).getListener());
beanFactory, source);
}
else {
addServletContextInitializerBean(ServletContextInitializer.class, beanName,
@ -164,7 +176,8 @@ class ServletContextInitializerBeans
private <T, B extends T> void addAsRegistrationBean(ListableBeanFactory beanFactory,
Class<T> type, Class<B> beanType, RegistrationBeanAdapter<T> adapter) {
List<Map.Entry<String, B>> beans = getOrderedBeansOfType(beanFactory, beanType);
List<Map.Entry<String, B>> beans = getOrderedBeansOfType(beanFactory, beanType,
this.seen);
for (Entry<String, B> bean : beans) {
if (this.seen.add(bean.getValue())) {
int order = getOrder(bean.getValue());
@ -175,7 +188,6 @@ class ServletContextInitializerBeans
registration.setName(beanName);
registration.setOrder(order);
this.initializers.add(type, registration);
if (this.log.isDebugEnabled()) {
this.log.debug(
"Created " + type.getSimpleName() + " initializer for bean '"
@ -197,18 +209,30 @@ class ServletContextInitializerBeans
private <T> List<Entry<String, T>> getOrderedBeansOfType(
ListableBeanFactory beanFactory, Class<T> type) {
return getOrderedBeansOfType(beanFactory, type, Collections.emptySet());
}
private <T> List<Entry<String, T>> getOrderedBeansOfType(
ListableBeanFactory beanFactory, Class<T> type, Set<?> excludes) {
List<Entry<String, T>> beans = new ArrayList<Entry<String, T>>();
Comparator<Entry<String, T>> comparator = new Comparator<Entry<String, T>>() {
@Override
public int compare(Entry<String, T> o1, Entry<String, T> o2) {
return AnnotationAwareOrderComparator.INSTANCE.compare(o1.getValue(),
o2.getValue());
}
};
String[] names = beanFactory.getBeanNamesForType(type, true, false);
Map<String, T> map = new LinkedHashMap<String, T>();
for (String name : names) {
map.put(name, beanFactory.getBean(name, type));
if (!excludes.contains(name)) {
T bean = beanFactory.getBean(name, type);
if (!excludes.contains(bean)) {
map.put(name, bean);
}
}
}
beans.addAll(map.entrySet());
Collections.sort(beans, comparator);

View File

@ -0,0 +1,230 @@
/*
* Copyright 2012-2015 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.boot.context.embedded;
import java.util.Arrays;
import java.util.Collections;
import java.util.EnumSet;
import java.util.HashMap;
import java.util.LinkedHashSet;
import java.util.Map;
import javax.servlet.DispatcherType;
import javax.servlet.Filter;
import javax.servlet.FilterRegistration;
import javax.servlet.ServletContext;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import static org.mockito.BDDMockito.given;
import static org.mockito.Matchers.anyObject;
import static org.mockito.Matchers.anyString;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
/**
* Abstract base for {@link AbstractFilterRegistrationBean} tests.
*
* @author Phillip Webb
*/
public abstract class AbstractFilterRegistrationBeanTests {
@Rule
public ExpectedException thrown = ExpectedException.none();
@Mock
ServletContext servletContext;
@Mock
FilterRegistration.Dynamic registration;
@Before
public void setupMocks() {
MockitoAnnotations.initMocks(this);
given(this.servletContext.addFilter(anyString(), (Filter) anyObject()))
.willReturn(this.registration);
}
@Test
public void startupWithDefaults() throws Exception {
AbstractFilterRegistrationBean bean = createFilterRegistrationBean();
bean.onStartup(this.servletContext);
verify(this.servletContext).addFilter(eq("mockFilter"), getExpectedFilter());
verify(this.registration).setAsyncSupported(true);
verify(this.registration).addMappingForUrlPatterns(
AbstractFilterRegistrationBean.ASYNC_DISPATCHER_TYPES, false, "/*");
}
@Test
public void startupWithSpecifiedValues() throws Exception {
AbstractFilterRegistrationBean bean = createFilterRegistrationBean();
bean.setName("test");
bean.setAsyncSupported(false);
bean.setInitParameters(Collections.singletonMap("a", "b"));
bean.addInitParameter("c", "d");
bean.setUrlPatterns(new LinkedHashSet<String>(Arrays.asList("/a", "/b")));
bean.addUrlPatterns("/c");
bean.setServletNames(new LinkedHashSet<String>(Arrays.asList("s1", "s2")));
bean.addServletNames("s3");
bean.setServletRegistrationBeans(
Collections.singleton(mockServletRegistation("s4")));
bean.addServletRegistrationBeans(mockServletRegistation("s5"));
bean.setMatchAfter(true);
bean.onStartup(this.servletContext);
verify(this.servletContext).addFilter(eq("test"), getExpectedFilter());
verify(this.registration).setAsyncSupported(false);
Map<String, String> expectedInitParameters = new HashMap<String, String>();
expectedInitParameters.put("a", "b");
expectedInitParameters.put("c", "d");
verify(this.registration).setInitParameters(expectedInitParameters);
verify(this.registration).addMappingForUrlPatterns(
AbstractFilterRegistrationBean.NON_ASYNC_DISPATCHER_TYPES, true, "/a",
"/b", "/c");
verify(this.registration).addMappingForServletNames(
AbstractFilterRegistrationBean.NON_ASYNC_DISPATCHER_TYPES, true, "s4",
"s5", "s1", "s2", "s3");
}
@Test
public void specificName() throws Exception {
AbstractFilterRegistrationBean bean = createFilterRegistrationBean();
bean.setName("specificName");
bean.onStartup(this.servletContext);
verify(this.servletContext).addFilter(eq("specificName"), getExpectedFilter());
}
@Test
public void deducedName() throws Exception {
AbstractFilterRegistrationBean bean = createFilterRegistrationBean();
bean.onStartup(this.servletContext);
verify(this.servletContext).addFilter(eq("mockFilter"), getExpectedFilter());
}
@Test
public void disable() throws Exception {
AbstractFilterRegistrationBean bean = createFilterRegistrationBean();
bean.setEnabled(false);
bean.onStartup(this.servletContext);
verify(this.servletContext, times(0)).addFilter(eq("mockFilter"),
getExpectedFilter());
}
@Test
public void setServletRegistrationBeanMustNotBeNull() throws Exception {
AbstractFilterRegistrationBean bean = createFilterRegistrationBean();
this.thrown.expect(IllegalArgumentException.class);
this.thrown.expectMessage("ServletRegistrationBeans must not be null");
bean.setServletRegistrationBeans(null);
}
@Test
public void addServletRegistrationBeanMustNotBeNull() throws Exception {
AbstractFilterRegistrationBean bean = createFilterRegistrationBean();
this.thrown.expect(IllegalArgumentException.class);
this.thrown.expectMessage("ServletRegistrationBeans must not be null");
bean.addServletRegistrationBeans((ServletRegistrationBean[]) null);
}
@Test
public void setServletRegistrationBeanReplacesValue() throws Exception {
AbstractFilterRegistrationBean bean = createFilterRegistrationBean(
mockServletRegistation("a"));
bean.setServletRegistrationBeans(new LinkedHashSet<ServletRegistrationBean>(
Arrays.asList(mockServletRegistation("b"))));
bean.onStartup(this.servletContext);
verify(this.registration).addMappingForServletNames(
AbstractFilterRegistrationBean.ASYNC_DISPATCHER_TYPES, false, "b");
}
@Test
public void modifyInitParameters() throws Exception {
AbstractFilterRegistrationBean bean = createFilterRegistrationBean();
bean.addInitParameter("a", "b");
bean.getInitParameters().put("a", "c");
bean.onStartup(this.servletContext);
verify(this.registration).setInitParameters(Collections.singletonMap("a", "c"));
}
@Test
public void setUrlPatternMustNotBeNull() throws Exception {
AbstractFilterRegistrationBean bean = createFilterRegistrationBean();
this.thrown.expect(IllegalArgumentException.class);
this.thrown.expectMessage("UrlPatterns must not be null");
bean.setUrlPatterns(null);
}
@Test
public void addUrlPatternMustNotBeNull() throws Exception {
AbstractFilterRegistrationBean bean = createFilterRegistrationBean();
this.thrown.expect(IllegalArgumentException.class);
this.thrown.expectMessage("UrlPatterns must not be null");
bean.addUrlPatterns((String[]) null);
}
@Test
public void setServletNameMustNotBeNull() throws Exception {
AbstractFilterRegistrationBean bean = createFilterRegistrationBean();
this.thrown.expect(IllegalArgumentException.class);
this.thrown.expectMessage("ServletNames must not be null");
bean.setServletNames(null);
}
@Test
public void addServletNameMustNotBeNull() throws Exception {
AbstractFilterRegistrationBean bean = createFilterRegistrationBean();
this.thrown.expect(IllegalArgumentException.class);
this.thrown.expectMessage("ServletNames must not be null");
bean.addServletNames((String[]) null);
}
@Test
public void withSpecificDispatcherTypes() throws Exception {
AbstractFilterRegistrationBean bean = createFilterRegistrationBean();
bean.setDispatcherTypes(DispatcherType.INCLUDE, DispatcherType.FORWARD);
bean.onStartup(this.servletContext);
verify(this.registration).addMappingForUrlPatterns(
EnumSet.of(DispatcherType.INCLUDE, DispatcherType.FORWARD), false, "/*");
}
@Test
public void withSpecificDispatcherTypesEnumSet() throws Exception {
AbstractFilterRegistrationBean bean = createFilterRegistrationBean();
EnumSet<DispatcherType> types = EnumSet.of(DispatcherType.INCLUDE,
DispatcherType.FORWARD);
bean.setDispatcherTypes(types);
bean.onStartup(this.servletContext);
verify(this.registration).addMappingForUrlPatterns(types, false, "/*");
}
protected abstract Filter getExpectedFilter();
protected abstract AbstractFilterRegistrationBean createFilterRegistrationBean(
ServletRegistrationBean... servletRegistrationBeans);
protected final ServletRegistrationBean mockServletRegistation(String name) {
ServletRegistrationBean bean = new ServletRegistrationBean();
bean.setName(name);
return bean;
}
}

View File

@ -0,0 +1,97 @@
/*
* Copyright 2012-2015 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.boot.context.embedded;
import javax.servlet.Filter;
import org.junit.Test;
import org.springframework.mock.web.MockServletContext;
import org.springframework.test.util.ReflectionTestUtils;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.GenericWebApplicationContext;
import org.springframework.web.filter.DelegatingFilterProxy;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.instanceOf;
import static org.junit.Assert.assertThat;
import static org.mockito.Matchers.isA;
/**
* Tests for {@link DelegatingFilterProxyRegistrationBean}.
*
* @author Phillip Webb
*/
public class DelegatingFilterProxyRegistrationBeanTests
extends AbstractFilterRegistrationBeanTests {
private WebApplicationContext applicationContext = new GenericWebApplicationContext(
new MockServletContext());;
@Test
public void targetBeanNameMustNotBeNull() throws Exception {
this.thrown.expect(IllegalArgumentException.class);
this.thrown.expectMessage("TargetBeanName must not be null or empty");
new DelegatingFilterProxyRegistrationBean(null);
}
@Test
public void targetBeanNameMustNotBeEmpty() throws Exception {
this.thrown.expect(IllegalArgumentException.class);
this.thrown.expectMessage("TargetBeanName must not be null or empty");
new DelegatingFilterProxyRegistrationBean("");
}
@Test
public void nameDefaultsToTargetBeanName() throws Exception {
assertThat(new DelegatingFilterProxyRegistrationBean("myFilter")
.getOrDeduceName(null), equalTo("myFilter"));
}
@Test
public void getFilterUsesDelegatingFilterProxy() throws Exception {
AbstractFilterRegistrationBean registrationBean = createFilterRegistrationBean();
Filter filter = registrationBean.getFilter();
assertThat(filter, instanceOf(DelegatingFilterProxy.class));
assertThat(ReflectionTestUtils.getField(filter, "webApplicationContext"),
equalTo((Object) this.applicationContext));
assertThat(ReflectionTestUtils.getField(filter, "targetBeanName"),
equalTo((Object) "mockFilter"));
}
@Test
public void createServletRegistrationBeanMustNotBeNull() throws Exception {
this.thrown.expect(IllegalArgumentException.class);
this.thrown.expectMessage("ServletRegistrationBeans must not be null");
new DelegatingFilterProxyRegistrationBean("mockFilter",
(ServletRegistrationBean[]) null);
}
@Override
protected AbstractFilterRegistrationBean createFilterRegistrationBean(
ServletRegistrationBean... servletRegistrationBeans) {
DelegatingFilterProxyRegistrationBean bean = new DelegatingFilterProxyRegistrationBean(
"mockFilter", servletRegistrationBeans);
bean.setApplicationContext(this.applicationContext);
return bean;
}
@Override
protected Filter getExpectedFilter() {
return isA(DelegatingFilterProxy.class);
}
}

View File

@ -29,13 +29,19 @@ import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import org.apache.struts.mock.MockHttpServletRequest;
import org.apache.struts.mock.MockHttpServletResponse;
import org.junit.After;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.mockito.ArgumentCaptor;
import org.mockito.Captor;
import org.mockito.InOrder;
import org.mockito.MockitoAnnotations;
import org.springframework.beans.MutablePropertyValues;
import org.springframework.beans.factory.BeanCreationException;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
@ -52,6 +58,8 @@ import org.springframework.context.support.PropertySourcesPlaceholderConfigurer;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.mock.web.MockFilterChain;
import org.springframework.mock.web.MockFilterConfig;
import org.springframework.web.context.ServletContextAware;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.request.SessionScope;
@ -88,8 +96,12 @@ public class EmbeddedWebApplicationContextTests {
private EmbeddedWebApplicationContext context;
@Captor
private ArgumentCaptor<Filter> filterCaptor;
@Before
public void setup() {
MockitoAnnotations.initMocks(this);
this.context = new EmbeddedWebApplicationContext();
}
@ -302,9 +314,9 @@ public class EmbeddedWebApplicationContextTests {
ordered.verify(escf.getServletContext()).addFilter("filterBean1", filter1);
ordered.verify(escf.getServletContext()).addFilter("filterBean2", filter2);
verify(escf.getRegisteredFilter(0).getRegistration()).addMappingForUrlPatterns(
FilterRegistrationBean.ASYNC_DISPATCHER_TYPES, false, "/*");
AbstractFilterRegistrationBean.ASYNC_DISPATCHER_TYPES, false, "/*");
verify(escf.getRegisteredFilter(1).getRegistration()).addMappingForUrlPatterns(
FilterRegistrationBean.ASYNC_DISPATCHER_TYPES, false, "/*");
AbstractFilterRegistrationBean.ASYNC_DISPATCHER_TYPES, false, "/*");
}
@Test
@ -395,7 +407,7 @@ public class EmbeddedWebApplicationContextTests {
}
@Test
public void filterReegistrationBeansSkipsRegisteredFilters() throws Exception {
public void filterRegistrationBeansSkipsRegisteredFilters() throws Exception {
addEmbeddedServletContainerFactoryBean();
Filter filter = mock(Filter.class);
FilterRegistrationBean initializer = new FilterRegistrationBean(filter);
@ -408,6 +420,32 @@ public class EmbeddedWebApplicationContextTests {
verify(servletContext, atMost(1)).addFilter(anyString(), (Filter) anyObject());
}
@Test
public void delegatingFilterProxyRegistrationBeansSkipsTargetBeanNames()
throws Exception {
addEmbeddedServletContainerFactoryBean();
DelegatingFilterProxyRegistrationBean initializer = new DelegatingFilterProxyRegistrationBean(
"filterBean");
this.context.registerBeanDefinition("initializerBean",
beanDefinition(initializer));
BeanDefinition filterBeanDefinition = beanDefinition(
new IllegalStateException("Create FilterBean Failure"));
filterBeanDefinition.setLazyInit(true);
this.context.registerBeanDefinition("filterBean", filterBeanDefinition);
this.context.refresh();
ServletContext servletContext = getEmbeddedServletContainerFactory()
.getServletContext();
verify(servletContext, atMost(1)).addFilter(anyString(),
this.filterCaptor.capture());
// Up to this point the filterBean should not have been created, calling
// the delegate proxy will trigger creation and an exception
this.thrown.expect(BeanCreationException.class);
this.thrown.expectMessage("Create FilterBean Failure");
this.filterCaptor.getValue().init(new MockFilterConfig());
this.filterCaptor.getValue().doFilter(new MockHttpServletRequest(),
new MockHttpServletResponse(), new MockFilterChain());
}
@Test
public void postProcessEmbeddedServletContainerFactory() throws Exception {
RootBeanDefinition bd = new RootBeanDefinition(
@ -459,7 +497,6 @@ public class EmbeddedWebApplicationContextTests {
this.context.close();
assertThat(validator.destroyed, is(true));
assertThat(validator.containerStoppedFirst, is(true));
}
private void addEmbeddedServletContainerFactoryBean() {
@ -482,6 +519,9 @@ public class EmbeddedWebApplicationContextTests {
}
public static <T> T getBean(T object) {
if (object instanceof RuntimeException) {
throw (RuntimeException) object;
}
return object;
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 2012-2013 the original author or authors.
* Copyright 2012-2015 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -16,29 +16,11 @@
package org.springframework.boot.context.embedded;
import java.util.Arrays;
import java.util.Collections;
import java.util.EnumSet;
import java.util.HashMap;
import java.util.LinkedHashSet;
import java.util.Map;
import javax.servlet.DispatcherType;
import javax.servlet.Filter;
import javax.servlet.FilterRegistration;
import javax.servlet.ServletContext;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import static org.mockito.BDDMockito.given;
import static org.mockito.Matchers.anyObject;
import static org.mockito.Matchers.anyString;
import static org.mockito.Mockito.times;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.verify;
/**
@ -46,93 +28,18 @@ import static org.mockito.Mockito.verify;
*
* @author Phillip Webb
*/
public class FilterRegistrationBeanTests {
@Rule
public ExpectedException thrown = ExpectedException.none();
public class FilterRegistrationBeanTests extends AbstractFilterRegistrationBeanTests {
private final MockFilter filter = new MockFilter();
@Mock
private ServletContext servletContext;
@Mock
private FilterRegistration.Dynamic registration;
@Before
public void setupMocks() {
MockitoAnnotations.initMocks(this);
given(this.servletContext.addFilter(anyString(), (Filter) anyObject()))
.willReturn(this.registration);
}
@Test
public void startupWithDefaults() throws Exception {
FilterRegistrationBean bean = new FilterRegistrationBean(this.filter);
bean.onStartup(this.servletContext);
verify(this.servletContext).addFilter("mockFilter", this.filter);
verify(this.registration).setAsyncSupported(true);
verify(this.registration).addMappingForUrlPatterns(
FilterRegistrationBean.ASYNC_DISPATCHER_TYPES, false, "/*");
}
@Test
public void startupWithSpecifiedValues() throws Exception {
FilterRegistrationBean bean = new FilterRegistrationBean();
bean.setName("test");
bean.setFilter(this.filter);
bean.setAsyncSupported(false);
bean.setInitParameters(Collections.singletonMap("a", "b"));
bean.addInitParameter("c", "d");
bean.setUrlPatterns(new LinkedHashSet<String>(Arrays.asList("/a", "/b")));
bean.addUrlPatterns("/c");
bean.setServletNames(new LinkedHashSet<String>(Arrays.asList("s1", "s2")));
bean.addServletNames("s3");
bean.setServletRegistrationBeans(
Collections.singleton(mockServletRegistation("s4")));
bean.addServletRegistrationBeans(mockServletRegistation("s5"));
bean.setMatchAfter(true);
bean.onStartup(this.servletContext);
verify(this.servletContext).addFilter("test", this.filter);
verify(this.registration).setAsyncSupported(false);
Map<String, String> expectedInitParameters = new HashMap<String, String>();
expectedInitParameters.put("a", "b");
expectedInitParameters.put("c", "d");
verify(this.registration).setInitParameters(expectedInitParameters);
verify(this.registration).addMappingForUrlPatterns(
FilterRegistrationBean.NON_ASYNC_DISPATCHER_TYPES, true, "/a", "/b",
"/c");
verify(this.registration).addMappingForServletNames(
FilterRegistrationBean.NON_ASYNC_DISPATCHER_TYPES, true, "s4", "s5", "s1",
"s2", "s3");
}
@Test
public void specificName() throws Exception {
FilterRegistrationBean bean = new FilterRegistrationBean();
bean.setName("specificName");
bean.setFilter(this.filter);
bean.onStartup(this.servletContext);
verify(this.servletContext).addFilter("specificName", this.filter);
}
@Test
public void deducedName() throws Exception {
public void setFilter() throws Exception {
FilterRegistrationBean bean = new FilterRegistrationBean();
bean.setFilter(this.filter);
bean.onStartup(this.servletContext);
verify(this.servletContext).addFilter("mockFilter", this.filter);
}
@Test
public void disable() throws Exception {
FilterRegistrationBean bean = new FilterRegistrationBean();
bean.setFilter(this.filter);
bean.setEnabled(false);
bean.onStartup(this.servletContext);
verify(this.servletContext, times(0)).addFilter("mockFilter", this.filter);
}
@Test
public void setFilterMustNotBeNull() throws Exception {
FilterRegistrationBean bean = new FilterRegistrationBean();
@ -142,20 +49,12 @@ public class FilterRegistrationBeanTests {
}
@Test
public void createServletMustNotBeNull() throws Exception {
public void constructFilterMustNotBeNull() throws Exception {
this.thrown.expect(IllegalArgumentException.class);
this.thrown.expectMessage("Filter must not be null");
new FilterRegistrationBean(null);
}
@Test
public void setServletRegistrationBeanMustNotBeNull() throws Exception {
FilterRegistrationBean bean = new FilterRegistrationBean(this.filter);
this.thrown.expect(IllegalArgumentException.class);
this.thrown.expectMessage("ServletRegistrationBeans must not be null");
bean.setServletRegistrationBeans(null);
}
@Test
public void createServletRegistrationBeanMustNotBeNull() throws Exception {
this.thrown.expect(IllegalArgumentException.class);
@ -163,88 +62,15 @@ public class FilterRegistrationBeanTests {
new FilterRegistrationBean(this.filter, (ServletRegistrationBean[]) null);
}
@Test
public void addServletRegistrationBeanMustNotBeNull() throws Exception {
FilterRegistrationBean bean = new FilterRegistrationBean(this.filter);
this.thrown.expect(IllegalArgumentException.class);
this.thrown.expectMessage("ServletRegistrationBeans must not be null");
bean.addServletRegistrationBeans((ServletRegistrationBean[]) null);
@Override
protected AbstractFilterRegistrationBean createFilterRegistrationBean(
ServletRegistrationBean... servletRegistrationBeans) {
return new FilterRegistrationBean(this.filter, servletRegistrationBeans);
}
@Test
public void setServletRegistrationBeanReplacesValue() throws Exception {
FilterRegistrationBean bean = new FilterRegistrationBean(this.filter,
mockServletRegistation("a"));
bean.setServletRegistrationBeans(new LinkedHashSet<ServletRegistrationBean>(
Arrays.asList(mockServletRegistation("b"))));
bean.onStartup(this.servletContext);
verify(this.registration).addMappingForServletNames(
FilterRegistrationBean.ASYNC_DISPATCHER_TYPES, false, "b");
@Override
protected Filter getExpectedFilter() {
return eq(this.filter);
}
@Test
public void modifyInitParameters() throws Exception {
FilterRegistrationBean bean = new FilterRegistrationBean(this.filter);
bean.addInitParameter("a", "b");
bean.getInitParameters().put("a", "c");
bean.onStartup(this.servletContext);
verify(this.registration).setInitParameters(Collections.singletonMap("a", "c"));
}
@Test
public void setUrlPatternMustNotBeNull() throws Exception {
FilterRegistrationBean bean = new FilterRegistrationBean(this.filter);
this.thrown.expect(IllegalArgumentException.class);
this.thrown.expectMessage("UrlPatterns must not be null");
bean.setUrlPatterns(null);
}
@Test
public void addUrlPatternMustNotBeNull() throws Exception {
FilterRegistrationBean bean = new FilterRegistrationBean(this.filter);
this.thrown.expect(IllegalArgumentException.class);
this.thrown.expectMessage("UrlPatterns must not be null");
bean.addUrlPatterns((String[]) null);
}
@Test
public void setServletNameMustNotBeNull() throws Exception {
FilterRegistrationBean bean = new FilterRegistrationBean(this.filter);
this.thrown.expect(IllegalArgumentException.class);
this.thrown.expectMessage("ServletNames must not be null");
bean.setServletNames(null);
}
@Test
public void addServletNameMustNotBeNull() throws Exception {
FilterRegistrationBean bean = new FilterRegistrationBean(this.filter);
this.thrown.expect(IllegalArgumentException.class);
this.thrown.expectMessage("ServletNames must not be null");
bean.addServletNames((String[]) null);
}
@Test
public void withSpecificDispatcherTypes() throws Exception {
FilterRegistrationBean bean = new FilterRegistrationBean(this.filter);
bean.setDispatcherTypes(DispatcherType.INCLUDE, DispatcherType.FORWARD);
bean.onStartup(this.servletContext);
verify(this.registration).addMappingForUrlPatterns(
EnumSet.of(DispatcherType.INCLUDE, DispatcherType.FORWARD), false, "/*");
}
@Test
public void withSpecificDispatcherTypesEnumSet() throws Exception {
FilterRegistrationBean bean = new FilterRegistrationBean(this.filter);
EnumSet<DispatcherType> types = EnumSet.of(DispatcherType.INCLUDE,
DispatcherType.FORWARD);
bean.setDispatcherTypes(types);
bean.onStartup(this.servletContext);
verify(this.registration).addMappingForUrlPatterns(types, false, "/*");
}
private ServletRegistrationBean mockServletRegistation(String name) {
ServletRegistrationBean bean = new ServletRegistrationBean();
bean.setName(name);
return bean;
}
}