Restructure web related classes

Reorganize web related classes for better separation of concerns.
Mainly this involves moving classes from `o.s.b.context.embedded`
that aren't directly tied to embedded servlet containers to
`o.s.b.web` and relocating everything from `o.s.b.context.web`.

See gh-5822
This commit is contained in:
Phillip Webb 2016-04-27 10:28:34 -07:00
parent a7cb689f95
commit aea18671c1
77 changed files with 2047 additions and 1252 deletions

View File

@ -54,7 +54,7 @@ import org.springframework.boot.bind.RelaxedPropertyResolver;
import org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext;
import org.springframework.boot.context.embedded.EmbeddedServletContainerFactory;
import org.springframework.boot.context.embedded.EmbeddedWebApplicationContext;
import org.springframework.boot.context.web.ApplicationContextHeaderFilter;
import org.springframework.boot.web.filter.ApplicationContextHeaderFilter;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.ApplicationListener;

View File

@ -53,10 +53,10 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnSingleCandi
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
import org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration;
import org.springframework.boot.autoconfigure.web.DispatcherServletAutoConfiguration;
import org.springframework.boot.context.embedded.FilterRegistrationBean;
import org.springframework.boot.context.embedded.RegistrationBean;
import org.springframework.boot.context.embedded.ServletRegistrationBean;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.boot.web.servlet.RegistrationBean;
import org.springframework.boot.web.servlet.ServletRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.Ordered;

View File

@ -40,10 +40,10 @@ import org.mockito.MockitoAnnotations;
import org.springframework.beans.MutablePropertyValues;
import org.springframework.boot.bind.RelaxedDataBinder;
import org.springframework.boot.context.embedded.ConfigurableEmbeddedServletContainer;
import org.springframework.boot.context.embedded.ServletContextInitializer;
import org.springframework.boot.context.embedded.jetty.JettyEmbeddedServletContainerFactory;
import org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedServletContainerFactory;
import org.springframework.boot.context.embedded.undertow.UndertowEmbeddedServletContainerFactory;
import org.springframework.boot.web.servlet.ServletContextInitializer;
import org.springframework.mock.env.MockEnvironment;
import static org.assertj.core.api.Assertions.assertThat;

View File

@ -18,7 +18,6 @@ package sample.hibernate4.service;
import org.junit.Test;
import org.junit.runner.RunWith;
import sample.hibernate4.domain.City;
import sample.hibernate4.service.CityRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

View File

@ -24,8 +24,6 @@ import sample.hibernate4.domain.Hotel;
import sample.hibernate4.domain.HotelSummary;
import sample.hibernate4.domain.Rating;
import sample.hibernate4.domain.RatingCount;
import sample.hibernate4.service.CityRepository;
import sample.hibernate4.service.HotelRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

View File

@ -20,10 +20,10 @@ import java.util.Collection;
import javax.servlet.Filter;
import org.springframework.boot.context.embedded.DelegatingFilterProxyRegistrationBean;
import org.springframework.boot.context.embedded.FilterRegistrationBean;
import org.springframework.boot.context.embedded.ServletContextInitializer;
import org.springframework.boot.context.embedded.ServletContextInitializerBeans;
import org.springframework.boot.web.servlet.DelegatingFilterProxyRegistrationBean;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.boot.web.servlet.ServletContextInitializer;
import org.springframework.boot.web.servlet.ServletContextInitializerBeans;
import org.springframework.test.web.servlet.result.MockMvcResultHandlers;
import org.springframework.test.web.servlet.setup.ConfigurableMockMvcBuilder;
import org.springframework.util.Assert;

View File

@ -25,6 +25,8 @@ import java.util.List;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import org.springframework.boot.web.servlet.ErrorPage;
import org.springframework.boot.web.servlet.ServletContextInitializer;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
@ -234,7 +236,7 @@ public abstract class AbstractConfigurableEmbeddedServletContainer
}
@Override
public void setErrorPages(Set<ErrorPage> errorPages) {
public void setErrorPages(Set<? extends ErrorPage> errorPages) {
Assert.notNull(errorPages, "ErrorPages must not be null");
this.errorPages = new LinkedHashSet<ErrorPage>(errorPages);
}

View File

@ -22,6 +22,9 @@ import java.util.List;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import org.springframework.boot.web.servlet.ErrorPage;
import org.springframework.boot.web.servlet.ServletContextInitializer;
/**
* Simple interface that represents customizations to an
* {@link EmbeddedServletContainerFactory}.
@ -109,7 +112,7 @@ public interface ConfigurableEmbeddedServletContainer {
* Sets the error pages that will be used when handling exceptions.
* @param errorPages the error pages
*/
void setErrorPages(Set<ErrorPage> errorPages);
void setErrorPages(Set<? extends ErrorPage> errorPages);
/**
* Sets the mime-type mappings.

View File

@ -19,11 +19,7 @@ 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.boot.web.servlet.ServletRegistrationBean;
import org.springframework.web.filter.DelegatingFilterProxy;
/**
@ -49,48 +45,17 @@ import org.springframework.web.filter.DelegatingFilterProxy;
* @see ServletContext#addFilter(String, Filter)
* @see FilterRegistrationBean
* @see DelegatingFilterProxy
* @deprecated as of 1.4 in favor of
* org.springframework.boot.web.DelegatingFilterProxyRegistrationBean
*/
public class DelegatingFilterProxyRegistrationBean extends AbstractFilterRegistrationBean
implements ApplicationContextAware {
@Deprecated
public class DelegatingFilterProxyRegistrationBean
extends org.springframework.boot.web.servlet.DelegatingFilterProxyRegistrationBean
implements org.springframework.boot.context.embedded.ServletContextInitializer {
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
public 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;
super(targetBeanName, servletRegistrationBeans);
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 2012-2014 the original author or authors.
* Copyright 2012-2016 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.
@ -20,6 +20,7 @@ import org.apache.catalina.core.ApplicationContext;
import org.springframework.boot.context.embedded.jetty.JettyEmbeddedServletContainerFactory;
import org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedServletContainerFactory;
import org.springframework.boot.web.servlet.ServletContextInitializer;
/**
* Factory interface that can be used to create {@link EmbeddedServletContainer}s.

View File

@ -1,5 +1,5 @@
/*
* Copyright 2012-2015 the original author or authors.
* Copyright 2012-2016 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.
@ -36,6 +36,10 @@ import org.apache.commons.logging.LogFactory;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.config.Scope;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.boot.web.servlet.ServletContextInitializer;
import org.springframework.boot.web.servlet.ServletContextInitializerBeans;
import org.springframework.boot.web.servlet.ServletRegistrationBean;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextException;
import org.springframework.core.io.Resource;
@ -93,7 +97,7 @@ public class EmbeddedWebApplicationContext extends GenericWebApplicationContext
* default. To change the default behaviour you can use a
* {@link ServletRegistrationBean} or a different bean name.
*/
public static final String DISPATCHER_SERVLET_NAME = ServletContextInitializerBeans.DISPATCHER_SERVLET_NAME;
public static final String DISPATCHER_SERVLET_NAME = "dispatcherServlet";
private volatile EmbeddedServletContainer embeddedServletContainer;
@ -202,7 +206,7 @@ public class EmbeddedWebApplicationContext extends GenericWebApplicationContext
* @return the self initializer
* @see #prepareEmbeddedWebApplicationContext(ServletContext)
*/
private ServletContextInitializer getSelfInitializer() {
private org.springframework.boot.web.servlet.ServletContextInitializer getSelfInitializer() {
return new ServletContextInitializer() {
@Override
public void onStartup(ServletContext servletContext) throws ServletException {

View File

@ -1,5 +1,5 @@
/*
* Copyright 2012-2014 the original author or authors.
* Copyright 2012-2016 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.
@ -17,119 +17,27 @@
package org.springframework.boot.context.embedded;
import org.springframework.http.HttpStatus;
import org.springframework.util.ObjectUtils;
/**
* Simple container-independent abstraction for servlet error pages. Roughly equivalent to
* the {@literal &lt;error-page&gt;} element traditionally found in web.xml.
*
* @author Dave Syer
* @deprecated as of 1.4 in favor of org.springframework.boot.web.ErrorPage
*/
public class ErrorPage {
@Deprecated
public class ErrorPage extends org.springframework.boot.web.servlet.ErrorPage {
private final HttpStatus status;
private final Class<? extends Throwable> exception;
private final String path;
public ErrorPage(String path) {
this.status = null;
this.exception = null;
this.path = path;
public ErrorPage(Class<? extends Throwable> exception, String path) {
super(exception, path);
}
public ErrorPage(HttpStatus status, String path) {
this.status = status;
this.exception = null;
this.path = path;
super(status, path);
}
public ErrorPage(Class<? extends Throwable> exception, String path) {
this.status = null;
this.exception = exception;
this.path = path;
}
/**
* The path to render (usually implemented as a forward), starting with "/". A custom
* controller or servlet path can be used, or if the container supports it, a template
* path (e.g. "/error.jsp").
* @return the path that will be rendered for this error
*/
public String getPath() {
return this.path;
}
/**
* Returns the exception type (or {@code null} for a page that matches by status).
* @return the exception type or {@code null}
*/
public Class<? extends Throwable> getException() {
return this.exception;
}
/**
* The HTTP status value that this error page matches (or {@code null} for a page that
* matches by exception).
* @return the status or {@code null}
*/
public HttpStatus getStatus() {
return this.status;
}
/**
* The HTTP status value that this error page matches.
* @return the status value (or 0 for a page that matches any status)
*/
public int getStatusCode() {
return (this.status == null ? 0 : this.status.value());
}
/**
* The exception type name.
* @return the exception type name (or {@code null} if there is none)
*/
public String getExceptionName() {
return (this.exception == null ? null : this.exception.getName());
}
/**
* Return if this error page is a global one (matches all unmatched status and
* exception types).
* @return if this is a global error page
*/
public boolean isGlobal() {
return (this.status == null && this.exception == null);
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ObjectUtils.nullSafeHashCode(getExceptionName());
result = prime * result + ObjectUtils.nullSafeHashCode(this.path);
result = prime * result + this.getStatusCode();
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
ErrorPage other = (ErrorPage) obj;
boolean rtn = true;
rtn &= ObjectUtils.nullSafeEquals(getExceptionName(), other.getExceptionName());
rtn &= ObjectUtils.nullSafeEquals(this.path, other.path);
rtn &= this.status == other.status;
return rtn;
public ErrorPage(String path) {
super(path);
}
}

View File

@ -19,7 +19,9 @@ package org.springframework.boot.context.embedded;
import javax.servlet.Filter;
import javax.servlet.ServletContext;
import org.springframework.util.Assert;
import org.springframework.boot.web.servlet.DelegatingFilterProxyRegistrationBean;
import org.springframework.boot.web.servlet.ServletContextInitializer;
import org.springframework.boot.web.servlet.ServletRegistrationBean;
/**
* A {@link ServletContextInitializer} to register {@link Filter}s in a Servlet 3.0+
@ -37,47 +39,20 @@ import org.springframework.util.Assert;
* @see ServletContextInitializer
* @see ServletContext#addFilter(String, Filter)
* @see DelegatingFilterProxyRegistrationBean
* @deprecated as of 1.4 in favor of org.springframework.boot.web.FilterRegistrationBean
*/
public class FilterRegistrationBean extends AbstractFilterRegistrationBean {
@Deprecated
public class FilterRegistrationBean
extends org.springframework.boot.web.servlet.FilterRegistrationBean
implements org.springframework.boot.context.embedded.ServletContextInitializer {
/**
* Filters that wrap the servlet request should be ordered less than or equal to this.
*/
public static final int REQUEST_WRAPPER_FILTER_MAX_ORDER = AbstractFilterRegistrationBean.REQUEST_WRAPPER_FILTER_MAX_ORDER;
private Filter filter;
/**
* Create a new {@link FilterRegistrationBean} instance.
*/
public FilterRegistrationBean() {
super();
}
/**
* Create a new {@link FilterRegistrationBean} instance to be registered with the
* specified {@link ServletRegistrationBean}s.
* @param filter the filter to register
* @param servletRegistrationBeans associate {@link ServletRegistrationBean}s
*/
public FilterRegistrationBean(Filter filter,
ServletRegistrationBean... servletRegistrationBeans) {
super(servletRegistrationBeans);
Assert.notNull(filter, "Filter must not be null");
this.filter = filter;
}
@Override
public Filter getFilter() {
return this.filter;
}
/**
* Set the filter to be registered.
* @param filter the filter
*/
public void setFilter(Filter filter) {
Assert.notNull(filter, "Filter must not be null");
this.filter = filter;
super(filter, servletRegistrationBeans);
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 2012-2014 the original author or authors.
* Copyright 2012-2016 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.
@ -22,6 +22,8 @@ import java.util.Map.Entry;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import org.springframework.boot.web.servlet.ServletContextInitializer;
/**
* A {@code ServletContextInitializer} that configures init parameters on the
* {@code ServletContext}.

View File

@ -1,5 +1,5 @@
/*
* Copyright 2012-2015 the original author or authors.
* Copyright 2012-2016 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.
@ -18,8 +18,6 @@ package org.springframework.boot.context.embedded;
import javax.servlet.MultipartConfigElement;
import org.springframework.util.Assert;
/**
* Factory that can be used to create a {@link MultipartConfigElement}. Size values can be
* set using traditional {@literal long} values which are set in bytes or using more
@ -31,101 +29,10 @@ import org.springframework.util.Assert;
* </pre>
*
* @author Phillip Webb
* @deprecated as of 1.4 in favor of org.springframework.boot.web.MultipartConfigFactory
*/
public class MultipartConfigFactory {
private String location;
private long maxFileSize = -1;
private long maxRequestSize = -1;
private int fileSizeThreshold = 0;
/**
* Sets the directory location where files will be stored.
* @param location the location
*/
public void setLocation(String location) {
this.location = location;
}
/**
* Sets the maximum size in bytes allowed for uploaded files.
* @param maxFileSize the maximum file size
* @see #setMaxFileSize(String)
*/
public void setMaxFileSize(long maxFileSize) {
this.maxFileSize = maxFileSize;
}
/**
* Sets the maximum size allowed for uploaded files. Values can use the suffixed "MB"
* or "KB" to indicate a Megabyte or Kilobyte size.
* @param maxFileSize the maximum file size
* @see #setMaxFileSize(long)
*/
public void setMaxFileSize(String maxFileSize) {
this.maxFileSize = parseSize(maxFileSize);
}
/**
* Sets the maximum size allowed in bytes for multipart/form-data requests.
* @param maxRequestSize the maximum request size
* @see #setMaxRequestSize(String)
*/
public void setMaxRequestSize(long maxRequestSize) {
this.maxRequestSize = maxRequestSize;
}
/**
* Sets the maximum size allowed for multipart/form-data requests. Values can use the
* suffixed "MB" or "KB" to indicate a Megabyte or Kilobyte size.
* @param maxRequestSize the maximum request size
* @see #setMaxRequestSize(long)
*/
public void setMaxRequestSize(String maxRequestSize) {
this.maxRequestSize = parseSize(maxRequestSize);
}
/**
* Sets the size threshold in bytes after which files will be written to disk.
* @param fileSizeThreshold the file size threshold
* @see #setFileSizeThreshold(String)
*/
public void setFileSizeThreshold(int fileSizeThreshold) {
this.fileSizeThreshold = fileSizeThreshold;
}
/**
* Sets the size threshold after which files will be written to disk. Values can use
* the suffixed "MB" or "KB" to indicate a Megabyte or Kilobyte size.
* @param fileSizeThreshold the file size threshold
* @see #setFileSizeThreshold(int)
*/
public void setFileSizeThreshold(String fileSizeThreshold) {
this.fileSizeThreshold = (int) parseSize(fileSizeThreshold);
}
private long parseSize(String size) {
Assert.hasLength(size, "Size must not be empty");
size = size.toUpperCase();
if (size.endsWith("KB")) {
return Long.valueOf(size.substring(0, size.length() - 2)) * 1024;
}
if (size.endsWith("MB")) {
return Long.valueOf(size.substring(0, size.length() - 2)) * 1024 * 1024;
}
return Long.valueOf(size);
}
/**
* Create a new {@link MultipartConfigElement} instance.
* @return the multipart config element
*/
public MultipartConfigElement createMultipartConfig() {
return new MultipartConfigElement(this.location, this.maxFileSize,
this.maxRequestSize, this.fileSizeThreshold);
}
@Deprecated
public class MultipartConfigFactory
extends org.springframework.boot.web.servlet.MultipartConfigFactory {
}

View File

@ -0,0 +1,106 @@
/*
* Copyright 2012-2016 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.HashMap;
import java.util.Map;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextInitializer;
import org.springframework.context.ApplicationListener;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.core.env.Environment;
import org.springframework.core.env.MapPropertySource;
import org.springframework.core.env.MutablePropertySources;
import org.springframework.core.env.PropertySource;
import org.springframework.util.StringUtils;
/**
* {@link ApplicationContextInitializer} that sets {@link Environment} properties for the
* ports that {@link EmbeddedServletContainer} servers are actually listening on. The
* property {@literal "local.server.port"} can be injected directly into tests using
* {@link Value @Value} or obtained via the {@link Environment}.
* <p>
* If the {@link EmbeddedWebApplicationContext} has a
* {@link EmbeddedWebApplicationContext#setNamespace(String) namespace} set, it will be
* used to construct the property name. For example, the "management" actuator context
* will have the property name {@literal "local.management.port"}.
* <p>
* Properties are automatically propagated up to any parent context.
*
* @author Dave Syer
* @author Phillip Webb
* @since 1.4.0
*/
public class ServerPortInfoApplicationContextInitializer
implements ApplicationContextInitializer<ConfigurableApplicationContext> {
@Override
public void initialize(ConfigurableApplicationContext applicationContext) {
applicationContext.addApplicationListener(
new ApplicationListener<EmbeddedServletContainerInitializedEvent>() {
@Override
public void onApplicationEvent(
EmbeddedServletContainerInitializedEvent event) {
ServerPortInfoApplicationContextInitializer.this
.onApplicationEvent(event);
}
});
}
protected void onApplicationEvent(EmbeddedServletContainerInitializedEvent event) {
String propertyName = getPropertyName(event.getApplicationContext());
setPortProperty(event.getApplicationContext(), propertyName,
event.getEmbeddedServletContainer().getPort());
}
protected String getPropertyName(EmbeddedWebApplicationContext context) {
String name = context.getNamespace();
if (StringUtils.isEmpty(name)) {
name = "server";
}
return "local." + name + ".port";
}
private void setPortProperty(ApplicationContext context, String propertyName,
int port) {
if (context instanceof ConfigurableApplicationContext) {
setPortProperty(((ConfigurableApplicationContext) context).getEnvironment(),
propertyName, port);
}
if (context.getParent() != null) {
setPortProperty(context.getParent(), propertyName, port);
}
}
@SuppressWarnings("unchecked")
private void setPortProperty(ConfigurableEnvironment environment, String propertyName,
int port) {
MutablePropertySources sources = environment.getPropertySources();
PropertySource<?> source = sources.get("server.ports");
if (source == null) {
source = new MapPropertySource("server.ports", new HashMap<String, Object>());
sources.addFirst(source);
}
((Map<String, Object>) source.getSource()).put(propertyName, port);
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 2012-2013 the original author or authors.
* Copyright 2012-2016 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.
@ -17,7 +17,6 @@
package org.springframework.boot.context.embedded;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import org.springframework.web.SpringServletContainerInitializer;
import org.springframework.web.WebApplicationInitializer;
@ -36,16 +35,11 @@ import org.springframework.web.WebApplicationInitializer;
*
* @author Phillip Webb
* @see WebApplicationInitializer
* @deprecated as of 1.4 in favor of
* org.springframework.boot.web.ServletContextInitializer
*/
public interface ServletContextInitializer {
/**
* Configure the given {@link ServletContext} with any servlets, filters, listeners
* context-params and attributes necessary for initialization.
* @param servletContext the {@code ServletContext} to initialize
* @throws ServletException if any call against the given {@code ServletContext}
* throws a {@code ServletException}
*/
void onStartup(ServletContext servletContext) throws ServletException;
@Deprecated
public interface ServletContextInitializer
extends org.springframework.boot.web.servlet.ServletContextInitializer {
}

View File

@ -16,25 +16,17 @@
package org.springframework.boot.context.embedded;
import java.util.Collections;
import java.util.EventListener;
import java.util.HashSet;
import java.util.Set;
import javax.servlet.ServletContext;
import javax.servlet.ServletContextAttributeListener;
import javax.servlet.ServletContextListener;
import javax.servlet.ServletException;
import javax.servlet.ServletRequestAttributeListener;
import javax.servlet.ServletRequestListener;
import javax.servlet.http.HttpSessionAttributeListener;
import javax.servlet.http.HttpSessionListener;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
import org.springframework.boot.web.servlet.ServletContextInitializer;
/**
* A {@link ServletContextInitializer} to register {@link EventListener}s in a Servlet
@ -55,94 +47,20 @@ import org.springframework.util.ClassUtils;
* @param <T> the type of listener
* @author Dave Syer
* @author Phillip Webb
* @deprecated as of 1.4 in favor of
* org.springframework.boot.web.ServletListenerRegistrationBean
*/
@Deprecated
public class ServletListenerRegistrationBean<T extends EventListener>
extends RegistrationBean {
extends org.springframework.boot.web.servlet.ServletListenerRegistrationBean<T>
implements org.springframework.boot.context.embedded.ServletContextInitializer {
private static final Log logger = LogFactory
.getLog(ServletListenerRegistrationBean.class);
private static final Set<Class<?>> SUPPORTED_TYPES;
static {
Set<Class<?>> types = new HashSet<Class<?>>();
types.add(ServletContextAttributeListener.class);
types.add(ServletRequestListener.class);
types.add(ServletRequestAttributeListener.class);
types.add(HttpSessionAttributeListener.class);
types.add(HttpSessionListener.class);
types.add(ServletContextListener.class);
SUPPORTED_TYPES = Collections.unmodifiableSet(types);
}
private T listener;
/**
* Create a new {@link ServletListenerRegistrationBean} instance.
*/
public ServletListenerRegistrationBean() {
super();
}
/**
* Create a new {@link ServletListenerRegistrationBean} instance.
* @param listener the listener to register
*/
public ServletListenerRegistrationBean(T listener) {
Assert.notNull(listener, "Listener must not be null");
Assert.isTrue(isSupportedType(listener), "Listener is not of a supported type");
this.listener = listener;
}
/**
* Set the listener that will be registered.
* @param listener the listener to register
*/
public void setListener(T listener) {
Assert.notNull(listener, "Listener must not be null");
Assert.isTrue(isSupportedType(listener), "Listener is not of a supported type");
this.listener = listener;
}
@Override
public void onStartup(ServletContext servletContext) throws ServletException {
if (!isEnabled()) {
logger.info("Listener " + this.listener + " was not registered (disabled)");
return;
}
try {
servletContext.addListener(this.listener);
}
catch (RuntimeException ex) {
throw new IllegalStateException(
"Failed to add listener '" + this.listener + "' to servlet context",
ex);
}
}
public T getListener() {
return this.listener;
}
/**
* Returns {@code true} if the specified listener is one of the supported types.
* @param listener the listener to test
* @return if the listener is of a supported type
*/
public static boolean isSupportedType(EventListener listener) {
for (Class<?> type : SUPPORTED_TYPES) {
if (ClassUtils.isAssignableValue(type, listener)) {
return true;
}
}
return false;
}
/**
* Return the supported types for this registration.
* @return the supported types
*/
public static Set<Class<?>> getSupportedTypes() {
return SUPPORTED_TYPES;
super(listener);
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 2012-2015 the original author or authors.
* Copyright 2012-2016 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,23 +16,10 @@
package org.springframework.boot.context.embedded;
import java.util.Arrays;
import java.util.Collection;
import java.util.LinkedHashSet;
import java.util.Set;
import javax.servlet.MultipartConfigElement;
import javax.servlet.Servlet;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRegistration;
import javax.servlet.ServletRegistration.Dynamic;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.util.Assert;
import org.springframework.util.ObjectUtils;
import org.springframework.boot.web.servlet.ServletContextInitializer;
/**
* A {@link ServletContextInitializer} to register {@link Servlet}s in a Servlet 3.0+
@ -49,172 +36,24 @@ import org.springframework.util.ObjectUtils;
* @author Phillip Webb
* @see ServletContextInitializer
* @see ServletContext#addServlet(String, Servlet)
* @deprecated as of 1.4 in favor of org.springframework.boot.web.ServletRegistrationBean
*/
public class ServletRegistrationBean extends RegistrationBean {
@Deprecated
public class ServletRegistrationBean
extends org.springframework.boot.web.servlet.ServletRegistrationBean
implements org.springframework.boot.context.embedded.ServletContextInitializer {
private static final Log logger = LogFactory.getLog(ServletRegistrationBean.class);
private static final String[] DEFAULT_MAPPINGS = { "/*" };
private Servlet servlet;
private Set<String> urlMappings = new LinkedHashSet<String>();
private boolean alwaysMapUrl = true;
private int loadOnStartup = -1;
private MultipartConfigElement multipartConfig;
/**
* Create a new {@link ServletRegistrationBean} instance.
*/
public ServletRegistrationBean() {
super();
}
/**
* Create a new {@link ServletRegistrationBean} instance with the specified
* {@link Servlet} and URL mappings.
* @param servlet the servlet being mapped
* @param urlMappings the URLs being mapped
*/
public ServletRegistrationBean(Servlet servlet, String... urlMappings) {
this(servlet, true, urlMappings);
}
/**
* Create a new {@link ServletRegistrationBean} instance with the specified
* {@link Servlet} and URL mappings.
* @param servlet the servlet being mapped
* @param alwaysMapUrl if omitted URL mappings should be replaced with '/*'
* @param urlMappings the URLs being mapped
*/
public ServletRegistrationBean(Servlet servlet, boolean alwaysMapUrl,
String... urlMappings) {
Assert.notNull(servlet, "Servlet must not be null");
Assert.notNull(urlMappings, "UrlMappings must not be null");
this.servlet = servlet;
this.alwaysMapUrl = alwaysMapUrl;
this.urlMappings.addAll(Arrays.asList(urlMappings));
super(servlet, alwaysMapUrl, urlMappings);
}
/**
* Returns the servlet being registered.
* @return the servlet
*/
protected Servlet getServlet() {
return this.servlet;
}
/**
* Sets the servlet to be registered.
* @param servlet the servlet
*/
public void setServlet(Servlet servlet) {
Assert.notNull(servlet, "Servlet must not be null");
this.servlet = servlet;
}
/**
* Set the URL mappings for the servlet. If not specified the mapping will default to
* '/'. This will replace any previously specified mappings.
* @param urlMappings the mappings to set
* @see #addUrlMappings(String...)
*/
public void setUrlMappings(Collection<String> urlMappings) {
Assert.notNull(urlMappings, "UrlMappings must not be null");
this.urlMappings = new LinkedHashSet<String>(urlMappings);
}
/**
* Return a mutable collection of the URL mappings for the servlet.
* @return the urlMappings
*/
public Collection<String> getUrlMappings() {
return this.urlMappings;
}
/**
* Add URL mappings for the servlet.
* @param urlMappings the mappings to add
* @see #setUrlMappings(Collection)
*/
public void addUrlMappings(String... urlMappings) {
Assert.notNull(urlMappings, "UrlMappings must not be null");
this.urlMappings.addAll(Arrays.asList(urlMappings));
}
/**
* Sets the {@code loadOnStartup} priority. See
* {@link ServletRegistration.Dynamic#setLoadOnStartup} for details.
* @param loadOnStartup if load on startup is enabled
*/
public void setLoadOnStartup(int loadOnStartup) {
this.loadOnStartup = loadOnStartup;
}
/**
* Set the {@link MultipartConfigElement multi-part configuration}.
* @param multipartConfig the multi-part configuration to set or {@code null}
*/
public void setMultipartConfig(MultipartConfigElement multipartConfig) {
this.multipartConfig = multipartConfig;
}
/**
* Returns the {@link MultipartConfigElement multi-part configuration} to be applied
* or {@code null}.
* @return the multipart config
*/
public MultipartConfigElement getMultipartConfig() {
return this.multipartConfig;
}
/**
* Returns the servlet name that will be registered.
* @return the servlet name
*/
public String getServletName() {
return getOrDeduceName(this.servlet);
}
@Override
public void onStartup(ServletContext servletContext) throws ServletException {
Assert.notNull(this.servlet, "Servlet must not be null");
String name = getServletName();
if (!isEnabled()) {
logger.info("Servlet " + name + " was not registered (disabled)");
return;
}
logger.info("Mapping servlet: '" + name + "' to " + this.urlMappings);
Dynamic added = servletContext.addServlet(name, this.servlet);
if (added == null) {
logger.info("Servlet " + 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(ServletRegistration.Dynamic registration) {
super.configure(registration);
String[] urlMapping = this.urlMappings
.toArray(new String[this.urlMappings.size()]);
if (urlMapping.length == 0 && this.alwaysMapUrl) {
urlMapping = DEFAULT_MAPPINGS;
}
if (!ObjectUtils.isEmpty(urlMapping)) {
registration.addMapping(urlMapping);
}
registration.setLoadOnStartup(this.loadOnStartup);
if (this.multipartConfig != null) {
registration.setMultipartConfig(this.multipartConfig);
}
public ServletRegistrationBean(Servlet servlet, String... urlMappings) {
super(servlet, urlMappings);
}
}

View File

@ -66,11 +66,11 @@ import org.springframework.boot.context.embedded.Compression;
import org.springframework.boot.context.embedded.EmbeddedServletContainer;
import org.springframework.boot.context.embedded.EmbeddedServletContainerException;
import org.springframework.boot.context.embedded.EmbeddedServletContainerFactory;
import org.springframework.boot.context.embedded.ErrorPage;
import org.springframework.boot.context.embedded.MimeMappings;
import org.springframework.boot.context.embedded.ServletContextInitializer;
import org.springframework.boot.context.embedded.Ssl;
import org.springframework.boot.context.embedded.Ssl.ClientAuth;
import org.springframework.boot.web.servlet.ErrorPage;
import org.springframework.boot.web.servlet.ServletContextInitializer;
import org.springframework.context.ResourceLoaderAware;
import org.springframework.core.io.ResourceLoader;
import org.springframework.util.Assert;

View File

@ -1,5 +1,5 @@
/*
* Copyright 2012-2015 the original author or authors.
* Copyright 2012-2016 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.
@ -23,7 +23,7 @@ import org.eclipse.jetty.webapp.AbstractConfiguration;
import org.eclipse.jetty.webapp.Configuration;
import org.eclipse.jetty.webapp.WebAppContext;
import org.springframework.boot.context.embedded.ServletContextInitializer;
import org.springframework.boot.web.servlet.ServletContextInitializer;
import org.springframework.util.Assert;
/**

View File

@ -1,5 +1,5 @@
/*
* Copyright 2012-2013 the original author or authors.
* Copyright 2012-2016 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.
@ -15,7 +15,8 @@
*/
/**
* Support for embedded servlet containers.
* Specialized {@link org.springframework.context.ApplicationContext} that supports
* embedded servlet containers.
*
* @see org.springframework.boot.context.embedded.EmbeddedServletContainerFactory
* @see org.springframework.boot.context.embedded.EmbeddedWebApplicationContext

View File

@ -59,12 +59,12 @@ import org.springframework.boot.context.embedded.Compression;
import org.springframework.boot.context.embedded.EmbeddedServletContainer;
import org.springframework.boot.context.embedded.EmbeddedServletContainerException;
import org.springframework.boot.context.embedded.EmbeddedServletContainerFactory;
import org.springframework.boot.context.embedded.ErrorPage;
import org.springframework.boot.context.embedded.MimeMappings;
import org.springframework.boot.context.embedded.ServletContextInitializer;
import org.springframework.boot.context.embedded.Ssl;
import org.springframework.boot.context.embedded.Ssl.ClientAuth;
import org.springframework.boot.context.embedded.SslStoreProvider;
import org.springframework.boot.web.servlet.ErrorPage;
import org.springframework.boot.web.servlet.ServletContextInitializer;
import org.springframework.context.ResourceLoaderAware;
import org.springframework.core.io.ResourceLoader;
import org.springframework.util.Assert;

View File

@ -1,5 +1,5 @@
/*
* Copyright 2012-2014 the original author or authors.
* Copyright 2012-2016 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.
@ -25,7 +25,7 @@ import javax.servlet.ServletException;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.boot.context.embedded.ServletContextInitializer;
import org.springframework.boot.web.servlet.ServletContextInitializer;
/**
* {@link ServletContainerInitializer} used to trigger {@link ServletContextInitializer

View File

@ -70,11 +70,11 @@ import org.xnio.XnioWorker;
import org.springframework.boot.context.embedded.AbstractEmbeddedServletContainerFactory;
import org.springframework.boot.context.embedded.EmbeddedServletContainer;
import org.springframework.boot.context.embedded.EmbeddedServletContainerFactory;
import org.springframework.boot.context.embedded.ErrorPage;
import org.springframework.boot.context.embedded.MimeMappings.Mapping;
import org.springframework.boot.context.embedded.ServletContextInitializer;
import org.springframework.boot.context.embedded.Ssl;
import org.springframework.boot.context.embedded.Ssl.ClientAuth;
import org.springframework.boot.web.servlet.ErrorPage;
import org.springframework.boot.web.servlet.ServletContextInitializer;
import org.springframework.context.ResourceLoaderAware;
import org.springframework.core.io.ResourceLoader;
import org.springframework.util.Assert;

View File

@ -1,5 +1,5 @@
/*
* Copyright 2012-2015 the original author or authors.
* Copyright 2012-2016 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,31 +16,11 @@
package org.springframework.boot.context.web;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpServletResponseWrapper;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.boot.context.embedded.AbstractConfigurableEmbeddedServletContainer;
import org.springframework.boot.context.embedded.EmbeddedServletContainerCustomizer;
import org.springframework.boot.context.embedded.ErrorPage;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;
import org.springframework.web.util.NestedServletException;
/**
* A special {@link AbstractConfigurableEmbeddedServletContainer} for non-embedded
@ -55,280 +35,13 @@ import org.springframework.web.util.NestedServletException;
* @author Dave Syer
* @author Phillip Webb
* @author Andy Wilkinson
* @since 1.4.0
* @deprecated as of 1.4 in favor of org.springframework.boot.web.support.ErrorPageFilter
*/
@Component
@Order(Ordered.HIGHEST_PRECEDENCE)
public class ErrorPageFilter extends AbstractConfigurableEmbeddedServletContainer
implements Filter, NonEmbeddedServletContainerFactory {
private static final Log logger = LogFactory.getLog(ErrorPageFilter.class);
// From RequestDispatcher but not referenced to remain compatible with Servlet 2.5
private static final String ERROR_EXCEPTION = "javax.servlet.error.exception";
private static final String ERROR_EXCEPTION_TYPE = "javax.servlet.error.exception_type";
private static final String ERROR_MESSAGE = "javax.servlet.error.message";
/**
* The name of the servlet attribute containing request URI.
*/
public static final String ERROR_REQUEST_URI = "javax.servlet.error.request_uri";
private static final String ERROR_STATUS_CODE = "javax.servlet.error.status_code";
private String global;
private final Map<Integer, String> statuses = new HashMap<Integer, String>();
private final Map<Class<?>, String> exceptions = new HashMap<Class<?>, String>();
private final Map<Class<?>, Class<?>> subtypes = new HashMap<Class<?>, Class<?>>();
private final OncePerRequestFilter delegate = new OncePerRequestFilter() {
@Override
protected void doFilterInternal(HttpServletRequest request,
HttpServletResponse response, FilterChain chain)
throws ServletException, IOException {
ErrorPageFilter.this.doFilter(request, response, chain);
}
@Override
protected boolean shouldNotFilterAsyncDispatch() {
return false;
}
};
@Override
public void init(FilterConfig filterConfig) throws ServletException {
this.delegate.init(filterConfig);
}
@Override
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
this.delegate.doFilter(request, response, chain);
}
private void doFilter(HttpServletRequest request, HttpServletResponse response,
FilterChain chain) throws IOException, ServletException {
ErrorWrapperResponse wrapped = new ErrorWrapperResponse(response);
try {
chain.doFilter(request, wrapped);
if (wrapped.hasErrorToSend()) {
handleErrorStatus(request, response, wrapped.getStatus(),
wrapped.getMessage());
response.flushBuffer();
}
else if (!request.isAsyncStarted() && !response.isCommitted()) {
response.flushBuffer();
}
}
catch (Throwable ex) {
Throwable exceptionToHandle = ex;
if (ex instanceof NestedServletException) {
exceptionToHandle = ((NestedServletException) ex).getRootCause();
}
handleException(request, response, wrapped, exceptionToHandle);
response.flushBuffer();
}
}
private void handleErrorStatus(HttpServletRequest request,
HttpServletResponse response, int status, String message)
throws ServletException, IOException {
if (response.isCommitted()) {
handleCommittedResponse(request, null);
return;
}
String errorPath = getErrorPath(this.statuses, status);
if (errorPath == null) {
response.sendError(status, message);
return;
}
response.setStatus(status);
setErrorAttributes(request, status, message);
request.getRequestDispatcher(errorPath).forward(request, response);
}
private void handleException(HttpServletRequest request, HttpServletResponse response,
ErrorWrapperResponse wrapped, Throwable ex)
throws IOException, ServletException {
Class<?> type = ex.getClass();
String errorPath = getErrorPath(type);
if (errorPath == null) {
rethrow(ex);
return;
}
if (response.isCommitted()) {
handleCommittedResponse(request, ex);
return;
}
forwardToErrorPage(errorPath, request, wrapped, ex);
}
private void forwardToErrorPage(String path, HttpServletRequest request,
HttpServletResponse response, Throwable ex)
throws ServletException, IOException {
if (logger.isErrorEnabled()) {
String message = "Forwarding to error page from request "
+ getDescription(request) + " due to exception [" + ex.getMessage()
+ "]";
logger.error(message, ex);
}
setErrorAttributes(request, 500, ex.getMessage());
request.setAttribute(ERROR_EXCEPTION, ex);
request.setAttribute(ERROR_EXCEPTION_TYPE, ex.getClass().getName());
response.reset();
response.sendError(500, ex.getMessage());
request.getRequestDispatcher(path).forward(request, response);
}
private String getDescription(HttpServletRequest request) {
return "[" + request.getServletPath()
+ (request.getPathInfo() == null ? "" : request.getPathInfo()) + "]";
}
private void handleCommittedResponse(HttpServletRequest request, Throwable ex) {
String message = "Cannot forward to error page for request "
+ getDescription(request) + " as the response has already been"
+ " committed. As a result, the response may have the wrong status"
+ " code. If your application is running on WebSphere Application"
+ " Server you may be able to resolve this problem by setting"
+ " com.ibm.ws.webcontainer.invokeFlushAfterService to false";
if (ex == null) {
logger.error(message);
}
else {
// User might see the error page without all the data here but throwing the
// exception isn't going to help anyone (we'll log it to be on the safe side)
logger.error(message, ex);
}
}
private String getErrorPath(Map<Integer, String> map, Integer status) {
if (map.containsKey(status)) {
return map.get(status);
}
return this.global;
}
private String getErrorPath(Class<?> type) {
if (this.exceptions.containsKey(type)) {
return this.exceptions.get(type);
}
if (this.subtypes.containsKey(type)) {
return this.exceptions.get(this.subtypes.get(type));
}
Class<?> subtype = type;
while (subtype != Object.class) {
subtype = subtype.getSuperclass();
if (this.exceptions.containsKey(subtype)) {
this.subtypes.put(subtype, type);
return this.exceptions.get(subtype);
}
}
return this.global;
}
private void setErrorAttributes(HttpServletRequest request, int status,
String message) {
request.setAttribute(ERROR_STATUS_CODE, status);
request.setAttribute(ERROR_MESSAGE, message);
request.setAttribute(ERROR_REQUEST_URI, request.getRequestURI());
}
private void rethrow(Throwable ex) throws IOException, ServletException {
if (ex instanceof RuntimeException) {
throw (RuntimeException) ex;
}
if (ex instanceof Error) {
throw (Error) ex;
}
if (ex instanceof IOException) {
throw (IOException) ex;
}
if (ex instanceof ServletException) {
throw (ServletException) ex;
}
throw new IllegalStateException(ex);
}
@Override
public void addErrorPages(ErrorPage... errorPages) {
for (ErrorPage errorPage : errorPages) {
if (errorPage.isGlobal()) {
this.global = errorPage.getPath();
}
else if (errorPage.getStatus() != null) {
this.statuses.put(errorPage.getStatus().value(), errorPage.getPath());
}
else {
this.exceptions.put(errorPage.getException(), errorPage.getPath());
}
}
}
@Override
public void destroy() {
}
private static class ErrorWrapperResponse extends HttpServletResponseWrapper {
private int status;
private String message;
private boolean hasErrorToSend = false;
ErrorWrapperResponse(HttpServletResponse response) {
super(response);
}
@Override
public void sendError(int status) throws IOException {
sendError(status, null);
}
@Override
public void sendError(int status, String message) throws IOException {
this.status = status;
this.message = message;
this.hasErrorToSend = true;
// Do not call super because the container may prevent us from handling the
// error ourselves
}
@Override
public int getStatus() {
if (this.hasErrorToSend) {
return this.status;
}
// If there was no error we need to trust the wrapped response
return super.getStatus();
}
@Override
public void flushBuffer() throws IOException {
if (this.hasErrorToSend && !isCommitted()) {
((HttpServletResponse) getResponse()).sendError(this.status,
this.message);
}
super.flushBuffer();
}
public String getMessage() {
return this.message;
}
public boolean hasErrorToSend() {
return this.hasErrorToSend;
}
}
@Deprecated
public class ErrorPageFilter
extends org.springframework.boot.web.support.ErrorPageFilter {
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 2012-2014 the original author or authors.
* Copyright 2012-2016 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.
@ -24,23 +24,11 @@ import org.springframework.web.filter.CharacterEncodingFilter;
*
* @author Phillip Webb
* @since 1.2.1
* @deprecated as of 1.4 in favor of
* org.springframework.boot.web.filter.OrderedCharacterEncodingFilter
*/
public class OrderedCharacterEncodingFilter extends CharacterEncodingFilter
implements Ordered {
private int order = Ordered.HIGHEST_PRECEDENCE;
@Override
public int getOrder() {
return this.order;
}
/**
* Set the order for this filter.
* @param order the order to set
*/
public void setOrder(int order) {
this.order = order;
}
@Deprecated
public class OrderedCharacterEncodingFilter
extends org.springframework.boot.web.filter.OrderedCharacterEncodingFilter {
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 2012-2015 the original author or authors.
* Copyright 2012-2016 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,7 +16,6 @@
package org.springframework.boot.context.web;
import org.springframework.boot.context.embedded.FilterRegistrationBean;
import org.springframework.core.Ordered;
import org.springframework.web.filter.HiddenHttpMethodFilter;
@ -25,29 +24,16 @@ import org.springframework.web.filter.HiddenHttpMethodFilter;
*
* @author Phillip Webb
* @since 1.2.4
* @deprecated as of 1.4 in favor of
* org.springframework.boot.web.filter.OrderedHiddenHttpMethodFilter
*/
public class OrderedHiddenHttpMethodFilter extends HiddenHttpMethodFilter
implements Ordered {
@Deprecated
public class OrderedHiddenHttpMethodFilter
extends org.springframework.boot.web.filter.OrderedHiddenHttpMethodFilter {
/**
* The default order is high to ensure the filter is applied before Spring Security.
*/
public static final int DEFAULT_ORDER = FilterRegistrationBean.REQUEST_WRAPPER_FILTER_MAX_ORDER
- 10000;
private int order = DEFAULT_ORDER;
@Override
public int getOrder() {
return this.order;
}
/**
* Set the order for this filter.
* @param order the order to set
*/
public void setOrder(int order) {
this.order = order;
}
public static final int DEFAULT_ORDER = org.springframework.boot.web.filter.OrderedHiddenHttpMethodFilter.DEFAULT_ORDER;
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 2012-2015 the original author or authors.
* Copyright 2012-2016 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,7 +16,6 @@
package org.springframework.boot.context.web;
import org.springframework.boot.context.embedded.FilterRegistrationBean;
import org.springframework.core.Ordered;
import org.springframework.web.filter.HttpPutFormContentFilter;
@ -25,29 +24,16 @@ import org.springframework.web.filter.HttpPutFormContentFilter;
*
* @author Joao Pedro Evangelista
* @since 1.3.0
* @deprecated as of 1.4 in favor of
* org.springframework.boot.web.filter.OrderedHttpPutFormContentFilter
*/
public class OrderedHttpPutFormContentFilter extends HttpPutFormContentFilter
implements Ordered {
@Deprecated
public class OrderedHttpPutFormContentFilter
extends org.springframework.boot.web.filter.OrderedHttpPutFormContentFilter {
/**
* Higher order to ensure the filter is applied before Spring Security.
*/
public static final int DEFAULT_ORDER = FilterRegistrationBean.REQUEST_WRAPPER_FILTER_MAX_ORDER
- 9900;
private int order = DEFAULT_ORDER;
@Override
public int getOrder() {
return this.order;
}
/**
* Set the order for this filter.
* @param order the order to set
*/
public void setOrder(int order) {
this.order = order;
}
public static final int DEFAULT_ORDER = org.springframework.boot.web.filter.OrderedHttpPutFormContentFilter.DEFAULT_ORDER;
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 2012-2015 the original author or authors.
* Copyright 2012-2016 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,7 +16,6 @@
package org.springframework.boot.context.web;
import org.springframework.boot.context.embedded.FilterRegistrationBean;
import org.springframework.core.Ordered;
import org.springframework.web.filter.RequestContextFilter;
@ -25,23 +24,11 @@ import org.springframework.web.filter.RequestContextFilter;
*
* @author Phillip Webb
* @since 1.3.0
* @deprecated as of 1.4 in favor of
* org.springframework.boot.web.filter.OrderedRequestContextFilter
*/
public class OrderedRequestContextFilter extends RequestContextFilter implements Ordered {
// Order defaults to after Spring Session filter
private int order = FilterRegistrationBean.REQUEST_WRAPPER_FILTER_MAX_ORDER - 105;
@Override
public int getOrder() {
return this.order;
}
/**
* Set the order for this filter.
* @param order the order to set
*/
public void setOrder(int order) {
this.order = order;
}
@Deprecated
public class OrderedRequestContextFilter
extends org.springframework.boot.web.filter.OrderedRequestContextFilter {
}

View File

@ -16,23 +16,11 @@
package org.springframework.boot.context.web;
import java.util.HashMap;
import java.util.Map;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.embedded.EmbeddedServletContainer;
import org.springframework.boot.context.embedded.EmbeddedServletContainerInitializedEvent;
import org.springframework.boot.context.embedded.EmbeddedWebApplicationContext;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextInitializer;
import org.springframework.context.ApplicationListener;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.core.env.Environment;
import org.springframework.core.env.MapPropertySource;
import org.springframework.core.env.MutablePropertySources;
import org.springframework.core.env.PropertySource;
import org.springframework.util.StringUtils;
/**
* {@link ApplicationContextInitializer} that sets {@link Environment} properties for the
@ -50,60 +38,11 @@ import org.springframework.util.StringUtils;
* @author Dave Syer
* @author Phillip Webb
* @since 1.3.0
* @deprecated as of 1.4 in favor of
* org.springframework.boot.context.embedded.ServerPortInfoApplicationContextInitializer
*/
public class ServerPortInfoApplicationContextInitializer
implements ApplicationContextInitializer<ConfigurableApplicationContext> {
@Override
public void initialize(ConfigurableApplicationContext applicationContext) {
applicationContext.addApplicationListener(
new ApplicationListener<EmbeddedServletContainerInitializedEvent>() {
@Override
public void onApplicationEvent(
EmbeddedServletContainerInitializedEvent event) {
ServerPortInfoApplicationContextInitializer.this
.onApplicationEvent(event);
}
});
}
protected void onApplicationEvent(EmbeddedServletContainerInitializedEvent event) {
String propertyName = getPropertyName(event.getApplicationContext());
setPortProperty(event.getApplicationContext(), propertyName,
event.getEmbeddedServletContainer().getPort());
}
protected String getPropertyName(EmbeddedWebApplicationContext context) {
String name = context.getNamespace();
if (StringUtils.isEmpty(name)) {
name = "server";
}
return "local." + name + ".port";
}
private void setPortProperty(ApplicationContext context, String propertyName,
int port) {
if (context instanceof ConfigurableApplicationContext) {
setPortProperty(((ConfigurableApplicationContext) context).getEnvironment(),
propertyName, port);
}
if (context.getParent() != null) {
setPortProperty(context.getParent(), propertyName, port);
}
}
@SuppressWarnings("unchecked")
private void setPortProperty(ConfigurableEnvironment environment, String propertyName,
int port) {
MutablePropertySources sources = environment.getPropertySources();
PropertySource<?> source = sources.get("server.ports");
if (source == null) {
source = new MapPropertySource("server.ports", new HashMap<String, Object>());
sources.addFirst(source);
}
((Map<String, Object>) source.getSource()).put(propertyName, port);
}
@Deprecated
public class ServerPortInfoApplicationContextInitializer extends
org.springframework.boot.context.embedded.ServerPortInfoApplicationContextInitializer {
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 2010-2016 the original author or authors.
* Copyright 2012-2016 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.
@ -18,66 +18,27 @@ package org.springframework.boot.context.web;
import javax.servlet.ServletContext;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextInitializer;
import org.springframework.core.Ordered;
import org.springframework.web.context.ConfigurableWebApplicationContext;
import org.springframework.web.context.WebApplicationContext;
/**
* {@link ApplicationContextInitializer} for setting the servlet context.
*
* @author Dave Syer
* @author Phillip Webb
* @deprecated as of 1.4 in favor of
* org.springframework.boot.web.support.ServletContextApplicationContextInitializer
*/
public class ServletContextApplicationContextInitializer implements
ApplicationContextInitializer<ConfigurableWebApplicationContext>, Ordered {
@Deprecated
public class ServletContextApplicationContextInitializer extends
org.springframework.boot.web.support.ServletContextApplicationContextInitializer {
private int order = Ordered.HIGHEST_PRECEDENCE;
private final ServletContext servletContext;
private final boolean addApplicationContextAttribute;
/**
* Create a new {@link ServletContextApplicationContextInitializer} instance.
* @param servletContext the servlet that should be ultimately set.
*/
public ServletContextApplicationContextInitializer(ServletContext servletContext) {
this(servletContext, false);
}
/**
* Create a new {@link ServletContextApplicationContextInitializer} instance.
* @param servletContext the servlet that should be ultimately set.
* @param addApplicationContextAttribute if the {@link ApplicationContext} should be
* stored as an attribute in the {@link ServletContext}
* @since 1.3.4
*/
public ServletContextApplicationContextInitializer(ServletContext servletContext,
boolean addApplicationContextAttribute) {
this.servletContext = servletContext;
this.addApplicationContextAttribute = addApplicationContextAttribute;
super(servletContext, addApplicationContextAttribute);
}
public void setOrder(int order) {
this.order = order;
}
@Override
public int getOrder() {
return this.order;
}
@Override
public void initialize(ConfigurableWebApplicationContext applicationContext) {
applicationContext.setServletContext(this.servletContext);
if (this.addApplicationContextAttribute) {
this.servletContext.setAttribute(
WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE,
applicationContext);
}
public ServletContextApplicationContextInitializer(ServletContext servletContext) {
super(servletContext);
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 2012-2015 the original author or authors.
* Copyright 2012-2016 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.
@ -18,25 +18,11 @@ package org.springframework.boot.context.web;
import javax.servlet.Filter;
import javax.servlet.Servlet;
import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletException;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.builder.ParentContextApplicationContextInitializer;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext;
import org.springframework.boot.context.embedded.ServletContextInitializer;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.util.Assert;
import org.springframework.boot.web.servlet.ServletContextInitializer;
import org.springframework.web.WebApplicationInitializer;
import org.springframework.web.context.ContextLoaderListener;
import org.springframework.web.context.WebApplicationContext;
/**
* An opinionated {@link WebApplicationInitializer} to run a {@link SpringApplication}
@ -60,116 +46,11 @@ import org.springframework.web.context.WebApplicationContext;
* @author Phillip Webb
* @author Andy Wilkinson
* @see #configure(SpringApplicationBuilder)
* @deprecated as of 1.4 in favor of
* org.springframework.boot.web.support.SpringBootServletInitializer
*/
public abstract class SpringBootServletInitializer implements WebApplicationInitializer {
protected Log logger; // Don't initialize early
private boolean registerErrorPageFilter = true;
/**
* Set if the {@link ErrorPageFilter} should be registered. Set to {@code false} if
* error page mappings should be handled via the Servlet container and not Spring
* Boot.
* @param registerErrorPageFilter if the {@link ErrorPageFilter} should be registered.
*/
protected final void setRegisterErrorPageFilter(boolean registerErrorPageFilter) {
this.registerErrorPageFilter = registerErrorPageFilter;
}
@Override
public void onStartup(ServletContext servletContext) throws ServletException {
// Logger initialization is deferred in case a ordered
// LogServletContextInitializer is being used
this.logger = LogFactory.getLog(getClass());
WebApplicationContext rootAppContext = createRootApplicationContext(
servletContext);
if (rootAppContext != null) {
servletContext.addListener(new ContextLoaderListener(rootAppContext) {
@Override
public void contextInitialized(ServletContextEvent event) {
// no-op because the application context is already initialized
}
});
}
else {
this.logger.debug("No ContextLoaderListener registered, as "
+ "createRootApplicationContext() did not "
+ "return an application context");
}
}
protected WebApplicationContext createRootApplicationContext(
ServletContext servletContext) {
SpringApplicationBuilder builder = createSpringApplicationBuilder();
builder.main(getClass());
ApplicationContext parent = getExistingRootWebApplicationContext(servletContext);
if (parent != null) {
this.logger.info("Root context already created (using as parent).");
servletContext.setAttribute(
WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, null);
builder.initializers(new ParentContextApplicationContextInitializer(parent));
}
builder.initializers(
new ServletContextApplicationContextInitializer(servletContext));
builder.contextClass(AnnotationConfigEmbeddedWebApplicationContext.class);
builder = configure(builder);
SpringApplication application = builder.build();
if (application.getSources().isEmpty() && AnnotationUtils
.findAnnotation(getClass(), Configuration.class) != null) {
application.getSources().add(getClass());
}
Assert.state(!application.getSources().isEmpty(),
"No SpringApplication sources have been defined. Either override the "
+ "configure method or add an @Configuration annotation");
// Ensure error pages are registered
if (this.registerErrorPageFilter) {
application.getSources().add(ErrorPageFilter.class);
}
return run(application);
}
/**
* Returns the {@code SpringApplicationBuilder} that is used to configure and create
* the {@link SpringApplication}. The default implementation returns a new
* {@code SpringApplicationBuilder} in its default state.
* @return the {@code SpringApplicationBuilder}.
* @since 1.3.0
*/
protected SpringApplicationBuilder createSpringApplicationBuilder() {
return new SpringApplicationBuilder();
}
/**
* Called to run a fully configured {@link SpringApplication}.
* @param application the application to run
* @return the {@link WebApplicationContext}
*/
protected WebApplicationContext run(SpringApplication application) {
return (WebApplicationContext) application.run();
}
private ApplicationContext getExistingRootWebApplicationContext(
ServletContext servletContext) {
Object context = servletContext.getAttribute(
WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE);
if (context instanceof ApplicationContext) {
return (ApplicationContext) context;
}
return null;
}
/**
* Configure the application. Normally all you would need to do it add sources (e.g.
* config classes) because other settings have sensible defaults. You might choose
* (for instance) to add default command line arguments, or set an active Spring
* profile.
* @param builder a builder for the application context
* @return the application builder
* @see SpringApplicationBuilder
*/
protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {
return builder;
}
@Deprecated
public abstract class SpringBootServletInitializer
extends org.springframework.boot.web.support.SpringBootServletInitializer {
}

View File

@ -14,7 +14,7 @@
* limitations under the License.
*/
package org.springframework.boot.context.web;
package org.springframework.boot.web.filter;
import java.io.IOException;

View File

@ -0,0 +1,46 @@
/*
* Copyright 2012-2016 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.web.filter;
import org.springframework.core.Ordered;
import org.springframework.web.filter.CharacterEncodingFilter;
/**
* {@link CharacterEncodingFilter} that also implements {@link Ordered}.
*
* @author Phillip Webb
* @since 1.4.0
*/
public class OrderedCharacterEncodingFilter extends CharacterEncodingFilter
implements Ordered {
private int order = Ordered.HIGHEST_PRECEDENCE;
@Override
public int getOrder() {
return this.order;
}
/**
* Set the order for this filter.
* @param order the order to set
*/
public void setOrder(int order) {
this.order = order;
}
}

View File

@ -0,0 +1,53 @@
/*
* Copyright 2012-2016 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.web.filter;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.core.Ordered;
import org.springframework.web.filter.HiddenHttpMethodFilter;
/**
* {@link HiddenHttpMethodFilter} that also implements {@link Ordered}.
*
* @author Phillip Webb
* @since 1.4.0
*/
public class OrderedHiddenHttpMethodFilter extends HiddenHttpMethodFilter
implements Ordered {
/**
* The default order is high to ensure the filter is applied before Spring Security.
*/
public static final int DEFAULT_ORDER = FilterRegistrationBean.REQUEST_WRAPPER_FILTER_MAX_ORDER
- 10000;
private int order = DEFAULT_ORDER;
@Override
public int getOrder() {
return this.order;
}
/**
* Set the order for this filter.
* @param order the order to set
*/
public void setOrder(int order) {
this.order = order;
}
}

View File

@ -0,0 +1,53 @@
/*
* Copyright 2012-2016 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.web.filter;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.core.Ordered;
import org.springframework.web.filter.HttpPutFormContentFilter;
/**
* {@link HttpPutFormContentFilter} that also implements {@link Ordered}.
*
* @author Joao Pedro Evangelista
* @since 1.4.0
*/
public class OrderedHttpPutFormContentFilter extends HttpPutFormContentFilter
implements Ordered {
/**
* Higher order to ensure the filter is applied before Spring Security.
*/
public static final int DEFAULT_ORDER = FilterRegistrationBean.REQUEST_WRAPPER_FILTER_MAX_ORDER
- 9900;
private int order = DEFAULT_ORDER;
@Override
public int getOrder() {
return this.order;
}
/**
* Set the order for this filter.
* @param order the order to set
*/
public void setOrder(int order) {
this.order = order;
}
}

View File

@ -0,0 +1,47 @@
/*
* Copyright 2012-2016 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.web.filter;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.core.Ordered;
import org.springframework.web.filter.RequestContextFilter;
/**
* {@link RequestContextFilter} that also implements {@link Ordered}.
*
* @author Phillip Webb
* @since 1.4.0
*/
public class OrderedRequestContextFilter extends RequestContextFilter implements Ordered {
// Order defaults to after Spring Session filter
private int order = FilterRegistrationBean.REQUEST_WRAPPER_FILTER_MAX_ORDER - 105;
@Override
public int getOrder() {
return this.order;
}
/**
* Set the order for this filter.
* @param order the order to set
*/
public void setOrder(int order) {
this.order = order;
}
}

View File

@ -0,0 +1,20 @@
/*
* Copyright 2012-2016 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.
*/
/**
* Spring Boot specific {@link javax.servlet.Filter} implementations.
*/
package org.springframework.boot.web.filter;

View File

@ -14,7 +14,7 @@
* limitations under the License.
*/
package org.springframework.boot.context.embedded;
package org.springframework.boot.web.servlet;
import java.util.Arrays;
import java.util.Collection;
@ -49,11 +49,11 @@ abstract class AbstractFilterRegistrationBean extends RegistrationBean {
private final Log logger = LogFactory.getLog(getClass());
static final EnumSet<DispatcherType> ASYNC_DISPATCHER_TYPES = EnumSet.of(
private 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
private static final EnumSet<DispatcherType> NON_ASYNC_DISPATCHER_TYPES = EnumSet
.of(DispatcherType.FORWARD, DispatcherType.INCLUDE, DispatcherType.REQUEST);
private static final String[] DEFAULT_URL_MAPPINGS = { "/*" };

View File

@ -0,0 +1,96 @@
/*
* Copyright 2012-2016 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.web.servlet;
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.4.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
public 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

@ -0,0 +1,137 @@
/*
* Copyright 2012-2016 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.web.servlet;
import org.springframework.http.HttpStatus;
import org.springframework.util.ObjectUtils;
/**
* Simple container-independent abstraction for servlet error pages. Roughly equivalent to
* the {@literal &lt;error-page&gt;} element traditionally found in web.xml.
*
* @author Dave Syer
* @since 1.4.0
*/
public class ErrorPage {
private final HttpStatus status;
private final Class<? extends Throwable> exception;
private final String path;
public ErrorPage(String path) {
this.status = null;
this.exception = null;
this.path = path;
}
public ErrorPage(HttpStatus status, String path) {
this.status = status;
this.exception = null;
this.path = path;
}
public ErrorPage(Class<? extends Throwable> exception, String path) {
this.status = null;
this.exception = exception;
this.path = path;
}
/**
* The path to render (usually implemented as a forward), starting with "/". A custom
* controller or servlet path can be used, or if the container supports it, a template
* path (e.g. "/error.jsp").
* @return the path that will be rendered for this error
*/
public String getPath() {
return this.path;
}
/**
* Returns the exception type (or {@code null} for a page that matches by status).
* @return the exception type or {@code null}
*/
public Class<? extends Throwable> getException() {
return this.exception;
}
/**
* The HTTP status value that this error page matches (or {@code null} for a page that
* matches by exception).
* @return the status or {@code null}
*/
public HttpStatus getStatus() {
return this.status;
}
/**
* The HTTP status value that this error page matches.
* @return the status value (or 0 for a page that matches any status)
*/
public int getStatusCode() {
return (this.status == null ? 0 : this.status.value());
}
/**
* The exception type name.
* @return the exception type name (or {@code null} if there is none)
*/
public String getExceptionName() {
return (this.exception == null ? null : this.exception.getName());
}
/**
* Return if this error page is a global one (matches all unmatched status and
* exception types).
* @return if this is a global error page
*/
public boolean isGlobal() {
return (this.status == null && this.exception == null);
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ObjectUtils.nullSafeHashCode(getExceptionName());
result = prime * result + ObjectUtils.nullSafeHashCode(this.path);
result = prime * result + this.getStatusCode();
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (obj instanceof ErrorPage) {
ErrorPage other = (ErrorPage) obj;
boolean rtn = true;
rtn &= ObjectUtils.nullSafeEquals(getExceptionName(),
other.getExceptionName());
rtn &= ObjectUtils.nullSafeEquals(this.path, other.path);
rtn &= this.status == other.status;
return rtn;
}
return false;
}
}

View File

@ -0,0 +1,84 @@
/*
* Copyright 2012-2016 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.web.servlet;
import javax.servlet.Filter;
import javax.servlet.ServletContext;
import org.springframework.util.Assert;
/**
* A {@link ServletContextInitializer} to register {@link Filter}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 {@link #setFilter(Filter) Filter} must be specified before calling
* {@link #onStartup(ServletContext)}. 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 filter
* name will be deduced if not specified.
*
* @author Phillip Webb
* @since 1.4.0
* @see ServletContextInitializer
* @see ServletContext#addFilter(String, Filter)
* @see DelegatingFilterProxyRegistrationBean
*/
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 = AbstractFilterRegistrationBean.REQUEST_WRAPPER_FILTER_MAX_ORDER;
private Filter filter;
/**
* Create a new {@link FilterRegistrationBean} instance.
*/
public FilterRegistrationBean() {
}
/**
* Create a new {@link FilterRegistrationBean} instance to be registered with the
* specified {@link ServletRegistrationBean}s.
* @param filter the filter to register
* @param servletRegistrationBeans associate {@link ServletRegistrationBean}s
*/
public FilterRegistrationBean(Filter filter,
ServletRegistrationBean... servletRegistrationBeans) {
super(servletRegistrationBeans);
Assert.notNull(filter, "Filter must not be null");
this.filter = filter;
}
@Override
public Filter getFilter() {
return this.filter;
}
/**
* Set the filter to be registered.
* @param filter the filter
*/
public void setFilter(Filter filter) {
Assert.notNull(filter, "Filter must not be null");
this.filter = filter;
}
}

View File

@ -0,0 +1,132 @@
/*
* Copyright 2012-2016 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.web.servlet;
import javax.servlet.MultipartConfigElement;
import org.springframework.util.Assert;
/**
* Factory that can be used to create a {@link MultipartConfigElement}. Size values can be
* set using traditional {@literal long} values which are set in bytes or using more
* readable {@literal String} variants that accept KB or MB suffixes, for example:
*
* <pre class="code">
* factory.setMaxFileSize(&quot;10Mb&quot;);
* factory.setMaxRequestSize(&quot;100Kb&quot;);
* </pre>
*
* @author Phillip Webb
* @since 1.4.0
*/
public class MultipartConfigFactory {
private String location;
private long maxFileSize = -1;
private long maxRequestSize = -1;
private int fileSizeThreshold = 0;
/**
* Sets the directory location where files will be stored.
* @param location the location
*/
public void setLocation(String location) {
this.location = location;
}
/**
* Sets the maximum size in bytes allowed for uploaded files.
* @param maxFileSize the maximum file size
* @see #setMaxFileSize(String)
*/
public void setMaxFileSize(long maxFileSize) {
this.maxFileSize = maxFileSize;
}
/**
* Sets the maximum size allowed for uploaded files. Values can use the suffixed "MB"
* or "KB" to indicate a Megabyte or Kilobyte size.
* @param maxFileSize the maximum file size
* @see #setMaxFileSize(long)
*/
public void setMaxFileSize(String maxFileSize) {
this.maxFileSize = parseSize(maxFileSize);
}
/**
* Sets the maximum size allowed in bytes for multipart/form-data requests.
* @param maxRequestSize the maximum request size
* @see #setMaxRequestSize(String)
*/
public void setMaxRequestSize(long maxRequestSize) {
this.maxRequestSize = maxRequestSize;
}
/**
* Sets the maximum size allowed for multipart/form-data requests. Values can use the
* suffixed "MB" or "KB" to indicate a Megabyte or Kilobyte size.
* @param maxRequestSize the maximum request size
* @see #setMaxRequestSize(long)
*/
public void setMaxRequestSize(String maxRequestSize) {
this.maxRequestSize = parseSize(maxRequestSize);
}
/**
* Sets the size threshold in bytes after which files will be written to disk.
* @param fileSizeThreshold the file size threshold
* @see #setFileSizeThreshold(String)
*/
public void setFileSizeThreshold(int fileSizeThreshold) {
this.fileSizeThreshold = fileSizeThreshold;
}
/**
* Sets the size threshold after which files will be written to disk. Values can use
* the suffixed "MB" or "KB" to indicate a Megabyte or Kilobyte size.
* @param fileSizeThreshold the file size threshold
* @see #setFileSizeThreshold(int)
*/
public void setFileSizeThreshold(String fileSizeThreshold) {
this.fileSizeThreshold = (int) parseSize(fileSizeThreshold);
}
private long parseSize(String size) {
Assert.hasLength(size, "Size must not be empty");
size = size.toUpperCase();
if (size.endsWith("KB")) {
return Long.valueOf(size.substring(0, size.length() - 2)) * 1024;
}
if (size.endsWith("MB")) {
return Long.valueOf(size.substring(0, size.length() - 2)) * 1024 * 1024;
}
return Long.valueOf(size);
}
/**
* Create a new {@link MultipartConfigElement} instance.
* @return the multipart config element
*/
public MultipartConfigElement createMultipartConfig() {
return new MultipartConfigElement(this.location, this.maxFileSize,
this.maxRequestSize, this.fileSizeThreshold);
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 2012-2015 the original author or authors.
* Copyright 2012-2016 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.
@ -14,7 +14,7 @@
* limitations under the License.
*/
package org.springframework.boot.context.embedded;
package org.springframework.boot.web.servlet;
import java.util.LinkedHashMap;
import java.util.Map;
@ -29,6 +29,7 @@ import org.springframework.util.Assert;
* Base class for Servlet 3.0+ based registration beans.
*
* @author Phillip Webb
* @since 1.4.0
* @see ServletRegistrationBean
* @see FilterRegistrationBean
* @see DelegatingFilterProxyRegistrationBean

View File

@ -0,0 +1,52 @@
/*
* Copyright 2012-2016 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.web.servlet;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import org.springframework.web.SpringServletContainerInitializer;
import org.springframework.web.WebApplicationInitializer;
/**
* Interface used to configure a Servlet 3.0+ {@link ServletContext context}
* programmatically. Unlike {@link WebApplicationInitializer}, classes that implement this
* interface (and do not implement {@link WebApplicationInitializer}) will <b>not</b> be
* detected by {@link SpringServletContainerInitializer} and hence will not be
* automatically bootstrapped by the Servlet container.
* <p>
* This interface is primarily designed to allow {@link ServletContextInitializer}s to be
* managed by Spring and not the Servlet container.
* <p>
* For configuration examples see {@link WebApplicationInitializer}.
*
* @author Phillip Webb
* @since 1.4.0
* @see WebApplicationInitializer
*/
public interface ServletContextInitializer {
/**
* Configure the given {@link ServletContext} with any servlets, filters, listeners
* context-params and attributes necessary for initialization.
* @param servletContext the {@code ServletContext} to initialize
* @throws ServletException if any call against the given {@code ServletContext}
* throws a {@code ServletException}
*/
void onStartup(ServletContext servletContext) throws ServletException;
}

View File

@ -14,7 +14,7 @@
* limitations under the License.
*/
package org.springframework.boot.context.embedded;
package org.springframework.boot.web.servlet;
import java.util.AbstractCollection;
import java.util.ArrayList;
@ -59,7 +59,7 @@ import org.springframework.util.MultiValueMap;
public class ServletContextInitializerBeans
extends AbstractCollection<ServletContextInitializer> {
static final String DISPATCHER_SERVLET_NAME = "dispatcherServlet";
private static final String DISPATCHER_SERVLET_NAME = "dispatcherServlet";
private static final Log logger = LogFactory
.getLog(ServletContextInitializerBeans.class);

View File

@ -0,0 +1,149 @@
/*
* Copyright 2012-2016 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.web.servlet;
import java.util.Collections;
import java.util.EventListener;
import java.util.HashSet;
import java.util.Set;
import javax.servlet.ServletContext;
import javax.servlet.ServletContextAttributeListener;
import javax.servlet.ServletContextListener;
import javax.servlet.ServletException;
import javax.servlet.ServletRequestAttributeListener;
import javax.servlet.ServletRequestListener;
import javax.servlet.http.HttpSessionAttributeListener;
import javax.servlet.http.HttpSessionListener;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
/**
* A {@link ServletContextInitializer} to register {@link EventListener}s in a Servlet
* 3.0+ container. Similar to the {@link ServletContext#addListener(EventListener)
* registration} features provided by {@link ServletContext} but with a Spring Bean
* friendly design.
*
* This bean can be used to register the following types of listener:
* <ul>
* <li>{@link ServletContextAttributeListener}</li>
* <li>{@link ServletRequestListener}</li>
* <li>{@link ServletRequestAttributeListener}</li>
* <li>{@link HttpSessionAttributeListener}</li>
* <li>{@link HttpSessionListener}</li>
* <li>{@link ServletContextListener}</li>
* </ul>
*
* @param <T> the type of listener
* @author Dave Syer
* @author Phillip Webb
* @since 1.4.0
*/
public class ServletListenerRegistrationBean<T extends EventListener>
extends RegistrationBean {
private static final Log logger = LogFactory
.getLog(ServletListenerRegistrationBean.class);
private static final Set<Class<?>> SUPPORTED_TYPES;
static {
Set<Class<?>> types = new HashSet<Class<?>>();
types.add(ServletContextAttributeListener.class);
types.add(ServletRequestListener.class);
types.add(ServletRequestAttributeListener.class);
types.add(HttpSessionAttributeListener.class);
types.add(HttpSessionListener.class);
types.add(ServletContextListener.class);
SUPPORTED_TYPES = Collections.unmodifiableSet(types);
}
private T listener;
/**
* Create a new {@link ServletListenerRegistrationBean} instance.
*/
public ServletListenerRegistrationBean() {
}
/**
* Create a new {@link ServletListenerRegistrationBean} instance.
* @param listener the listener to register
*/
public ServletListenerRegistrationBean(T listener) {
Assert.notNull(listener, "Listener must not be null");
Assert.isTrue(isSupportedType(listener), "Listener is not of a supported type");
this.listener = listener;
}
/**
* Set the listener that will be registered.
* @param listener the listener to register
*/
public void setListener(T listener) {
Assert.notNull(listener, "Listener must not be null");
Assert.isTrue(isSupportedType(listener), "Listener is not of a supported type");
this.listener = listener;
}
@Override
public void onStartup(ServletContext servletContext) throws ServletException {
if (!isEnabled()) {
logger.info("Listener " + this.listener + " was not registered (disabled)");
return;
}
try {
servletContext.addListener(this.listener);
}
catch (RuntimeException ex) {
throw new IllegalStateException(
"Failed to add listener '" + this.listener + "' to servlet context",
ex);
}
}
public T getListener() {
return this.listener;
}
/**
* Returns {@code true} if the specified listener is one of the supported types.
* @param listener the listener to test
* @return if the listener is of a supported type
*/
public static boolean isSupportedType(EventListener listener) {
for (Class<?> type : SUPPORTED_TYPES) {
if (ClassUtils.isAssignableValue(type, listener)) {
return true;
}
}
return false;
}
/**
* Return the supported types for this registration.
* @return the supported types
*/
public static Set<Class<?>> getSupportedTypes() {
return SUPPORTED_TYPES;
}
}

View File

@ -0,0 +1,221 @@
/*
* Copyright 2012-2016 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.web.servlet;
import java.util.Arrays;
import java.util.Collection;
import java.util.LinkedHashSet;
import java.util.Set;
import javax.servlet.MultipartConfigElement;
import javax.servlet.Servlet;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRegistration;
import javax.servlet.ServletRegistration.Dynamic;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.util.Assert;
import org.springframework.util.ObjectUtils;
/**
* A {@link ServletContextInitializer} to register {@link Servlet}s in a Servlet 3.0+
* container. Similar to the {@link ServletContext#addServlet(String, Servlet)
* registration} features provided by {@link ServletContext} but with a Spring Bean
* friendly design.
* <p>
* The {@link #setServlet(Servlet) servlet} must be specified before calling
* {@link #onStartup}. URL mapping can be configured used {@link #setUrlMappings} or
* omitted when mapping to '/*' (unless
* {@link #ServletRegistrationBean(Servlet, boolean, String...) alwaysMapUrl} is set to
* {@code false}). The servlet name will be deduced if not specified.
*
* @author Phillip Webb
* @since 1.4.0
* @see ServletContextInitializer
* @see ServletContext#addServlet(String, Servlet)
*/
public class ServletRegistrationBean extends RegistrationBean {
private static final Log logger = LogFactory.getLog(ServletRegistrationBean.class);
private static final String[] DEFAULT_MAPPINGS = { "/*" };
private Servlet servlet;
private Set<String> urlMappings = new LinkedHashSet<String>();
private boolean alwaysMapUrl = true;
private int loadOnStartup = -1;
private MultipartConfigElement multipartConfig;
/**
* Create a new {@link ServletRegistrationBean} instance.
*/
public ServletRegistrationBean() {
}
/**
* Create a new {@link ServletRegistrationBean} instance with the specified
* {@link Servlet} and URL mappings.
* @param servlet the servlet being mapped
* @param urlMappings the URLs being mapped
*/
public ServletRegistrationBean(Servlet servlet, String... urlMappings) {
this(servlet, true, urlMappings);
}
/**
* Create a new {@link ServletRegistrationBean} instance with the specified
* {@link Servlet} and URL mappings.
* @param servlet the servlet being mapped
* @param alwaysMapUrl if omitted URL mappings should be replaced with '/*'
* @param urlMappings the URLs being mapped
*/
public ServletRegistrationBean(Servlet servlet, boolean alwaysMapUrl,
String... urlMappings) {
Assert.notNull(servlet, "Servlet must not be null");
Assert.notNull(urlMappings, "UrlMappings must not be null");
this.servlet = servlet;
this.alwaysMapUrl = alwaysMapUrl;
this.urlMappings.addAll(Arrays.asList(urlMappings));
}
/**
* Returns the servlet being registered.
* @return the servlet
*/
protected Servlet getServlet() {
return this.servlet;
}
/**
* Sets the servlet to be registered.
* @param servlet the servlet
*/
public void setServlet(Servlet servlet) {
Assert.notNull(servlet, "Servlet must not be null");
this.servlet = servlet;
}
/**
* Set the URL mappings for the servlet. If not specified the mapping will default to
* '/'. This will replace any previously specified mappings.
* @param urlMappings the mappings to set
* @see #addUrlMappings(String...)
*/
public void setUrlMappings(Collection<String> urlMappings) {
Assert.notNull(urlMappings, "UrlMappings must not be null");
this.urlMappings = new LinkedHashSet<String>(urlMappings);
}
/**
* Return a mutable collection of the URL mappings for the servlet.
* @return the urlMappings
*/
public Collection<String> getUrlMappings() {
return this.urlMappings;
}
/**
* Add URL mappings for the servlet.
* @param urlMappings the mappings to add
* @see #setUrlMappings(Collection)
*/
public void addUrlMappings(String... urlMappings) {
Assert.notNull(urlMappings, "UrlMappings must not be null");
this.urlMappings.addAll(Arrays.asList(urlMappings));
}
/**
* Sets the {@code loadOnStartup} priority. See
* {@link ServletRegistration.Dynamic#setLoadOnStartup} for details.
* @param loadOnStartup if load on startup is enabled
*/
public void setLoadOnStartup(int loadOnStartup) {
this.loadOnStartup = loadOnStartup;
}
/**
* Set the {@link MultipartConfigElement multi-part configuration}.
* @param multipartConfig the multi-part configuration to set or {@code null}
*/
public void setMultipartConfig(MultipartConfigElement multipartConfig) {
this.multipartConfig = multipartConfig;
}
/**
* Returns the {@link MultipartConfigElement multi-part configuration} to be applied
* or {@code null}.
* @return the multipart config
*/
public MultipartConfigElement getMultipartConfig() {
return this.multipartConfig;
}
/**
* Returns the servlet name that will be registered.
* @return the servlet name
*/
public String getServletName() {
return getOrDeduceName(this.servlet);
}
@Override
public void onStartup(ServletContext servletContext) throws ServletException {
Assert.notNull(this.servlet, "Servlet must not be null");
String name = getServletName();
if (!isEnabled()) {
logger.info("Servlet " + name + " was not registered (disabled)");
return;
}
logger.info("Mapping servlet: '" + name + "' to " + this.urlMappings);
Dynamic added = servletContext.addServlet(name, this.servlet);
if (added == null) {
logger.info("Servlet " + 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(ServletRegistration.Dynamic registration) {
super.configure(registration);
String[] urlMapping = this.urlMappings
.toArray(new String[this.urlMappings.size()]);
if (urlMapping.length == 0 && this.alwaysMapUrl) {
urlMapping = DEFAULT_MAPPINGS;
}
if (!ObjectUtils.isEmpty(urlMapping)) {
registration.addMapping(urlMapping);
}
registration.setLoadOnStartup(this.loadOnStartup);
if (this.multipartConfig != null) {
registration.setMultipartConfig(this.multipartConfig);
}
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 2012-2015 the original author or authors.
* Copyright 2012-2016 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.
@ -26,7 +26,6 @@ import javax.servlet.annotation.WebFilter;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.boot.context.embedded.FilterRegistrationBean;
import org.springframework.util.StringUtils;
/**

View File

@ -1,5 +1,5 @@
/*
* Copyright 2012-2015 the original author or authors.
* Copyright 2012-2016 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.
@ -23,7 +23,6 @@ import javax.servlet.annotation.WebListener;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.boot.context.embedded.ServletListenerRegistrationBean;
/**
* Handler for {@link WebListener}-annotated classes.

View File

@ -1,5 +1,5 @@
/*
* Copyright 2012-2015 the original author or authors.
* Copyright 2012-2016 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.
@ -23,7 +23,6 @@ import javax.servlet.annotation.WebServlet;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.boot.context.embedded.ServletRegistrationBean;
import org.springframework.util.StringUtils;
/**

View File

@ -0,0 +1,20 @@
/*
* Copyright 2012-2016 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.
*/
/**
* Classes and utilities designed to work with the `javax.servlet` specification.
*/
package org.springframework.boot.web.servlet;

View File

@ -0,0 +1,336 @@
/*
* Copyright 2012-2016 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.web.support;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpServletResponseWrapper;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.boot.context.embedded.AbstractConfigurableEmbeddedServletContainer;
import org.springframework.boot.context.embedded.EmbeddedServletContainerCustomizer;
import org.springframework.boot.context.web.NonEmbeddedServletContainerFactory;
import org.springframework.boot.web.servlet.ErrorPage;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;
import org.springframework.web.util.NestedServletException;
/**
* A special {@link AbstractConfigurableEmbeddedServletContainer} for non-embedded
* applications (i.e. deployed WAR files). It registers error pages and handles
* application errors by filtering requests and forwarding to the error pages instead of
* letting the container handle them. Error pages are a feature of the servlet spec but
* there is no Java API for registering them in the spec. This filter works around that by
* accepting error page registrations from Spring Boot's
* {@link EmbeddedServletContainerCustomizer} (any beans of that type in the context will
* be applied to this container).
*
* @author Dave Syer
* @author Phillip Webb
* @author Andy Wilkinson
* @since 1.4.0
*/
@Component
@Order(Ordered.HIGHEST_PRECEDENCE)
public class ErrorPageFilter extends AbstractConfigurableEmbeddedServletContainer
implements Filter, NonEmbeddedServletContainerFactory {
private static final Log logger = LogFactory.getLog(ErrorPageFilter.class);
// From RequestDispatcher but not referenced to remain compatible with Servlet 2.5
private static final String ERROR_EXCEPTION = "javax.servlet.error.exception";
private static final String ERROR_EXCEPTION_TYPE = "javax.servlet.error.exception_type";
private static final String ERROR_MESSAGE = "javax.servlet.error.message";
/**
* The name of the servlet attribute containing request URI.
*/
public static final String ERROR_REQUEST_URI = "javax.servlet.error.request_uri";
private static final String ERROR_STATUS_CODE = "javax.servlet.error.status_code";
private String global;
private final Map<Integer, String> statuses = new HashMap<Integer, String>();
private final Map<Class<?>, String> exceptions = new HashMap<Class<?>, String>();
private final Map<Class<?>, Class<?>> subtypes = new HashMap<Class<?>, Class<?>>();
private final OncePerRequestFilter delegate = new OncePerRequestFilter() {
@Override
protected void doFilterInternal(HttpServletRequest request,
HttpServletResponse response, FilterChain chain)
throws ServletException, IOException {
ErrorPageFilter.this.doFilter(request, response, chain);
}
@Override
protected boolean shouldNotFilterAsyncDispatch() {
return false;
}
};
@Override
public void init(FilterConfig filterConfig) throws ServletException {
this.delegate.init(filterConfig);
}
@Override
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
this.delegate.doFilter(request, response, chain);
}
private void doFilter(HttpServletRequest request, HttpServletResponse response,
FilterChain chain) throws IOException, ServletException {
ErrorWrapperResponse wrapped = new ErrorWrapperResponse(response);
try {
chain.doFilter(request, wrapped);
if (wrapped.hasErrorToSend()) {
handleErrorStatus(request, response, wrapped.getStatus(),
wrapped.getMessage());
response.flushBuffer();
}
else if (!request.isAsyncStarted() && !response.isCommitted()) {
response.flushBuffer();
}
}
catch (Throwable ex) {
Throwable exceptionToHandle = ex;
if (ex instanceof NestedServletException) {
exceptionToHandle = ((NestedServletException) ex).getRootCause();
}
handleException(request, response, wrapped, exceptionToHandle);
response.flushBuffer();
}
}
private void handleErrorStatus(HttpServletRequest request,
HttpServletResponse response, int status, String message)
throws ServletException, IOException {
if (response.isCommitted()) {
handleCommittedResponse(request, null);
return;
}
String errorPath = getErrorPath(this.statuses, status);
if (errorPath == null) {
response.sendError(status, message);
return;
}
response.setStatus(status);
setErrorAttributes(request, status, message);
request.getRequestDispatcher(errorPath).forward(request, response);
}
private void handleException(HttpServletRequest request, HttpServletResponse response,
ErrorWrapperResponse wrapped, Throwable ex)
throws IOException, ServletException {
Class<?> type = ex.getClass();
String errorPath = getErrorPath(type);
if (errorPath == null) {
rethrow(ex);
return;
}
if (response.isCommitted()) {
handleCommittedResponse(request, ex);
return;
}
forwardToErrorPage(errorPath, request, wrapped, ex);
}
private void forwardToErrorPage(String path, HttpServletRequest request,
HttpServletResponse response, Throwable ex)
throws ServletException, IOException {
if (logger.isErrorEnabled()) {
String message = "Forwarding to error page from request "
+ getDescription(request) + " due to exception [" + ex.getMessage()
+ "]";
logger.error(message, ex);
}
setErrorAttributes(request, 500, ex.getMessage());
request.setAttribute(ERROR_EXCEPTION, ex);
request.setAttribute(ERROR_EXCEPTION_TYPE, ex.getClass().getName());
response.reset();
response.sendError(500, ex.getMessage());
request.getRequestDispatcher(path).forward(request, response);
}
private String getDescription(HttpServletRequest request) {
return "[" + request.getServletPath()
+ (request.getPathInfo() == null ? "" : request.getPathInfo()) + "]";
}
private void handleCommittedResponse(HttpServletRequest request, Throwable ex) {
String message = "Cannot forward to error page for request "
+ getDescription(request) + " as the response has already been"
+ " committed. As a result, the response may have the wrong status"
+ " code. If your application is running on WebSphere Application"
+ " Server you may be able to resolve this problem by setting"
+ " com.ibm.ws.webcontainer.invokeFlushAfterService to false";
if (ex == null) {
logger.error(message);
}
else {
// User might see the error page without all the data here but throwing the
// exception isn't going to help anyone (we'll log it to be on the safe side)
logger.error(message, ex);
}
}
private String getErrorPath(Map<Integer, String> map, Integer status) {
if (map.containsKey(status)) {
return map.get(status);
}
return this.global;
}
private String getErrorPath(Class<?> type) {
if (this.exceptions.containsKey(type)) {
return this.exceptions.get(type);
}
if (this.subtypes.containsKey(type)) {
return this.exceptions.get(this.subtypes.get(type));
}
Class<?> subtype = type;
while (subtype != Object.class) {
subtype = subtype.getSuperclass();
if (this.exceptions.containsKey(subtype)) {
this.subtypes.put(subtype, type);
return this.exceptions.get(subtype);
}
}
return this.global;
}
private void setErrorAttributes(HttpServletRequest request, int status,
String message) {
request.setAttribute(ERROR_STATUS_CODE, status);
request.setAttribute(ERROR_MESSAGE, message);
request.setAttribute(ERROR_REQUEST_URI, request.getRequestURI());
}
private void rethrow(Throwable ex) throws IOException, ServletException {
if (ex instanceof RuntimeException) {
throw (RuntimeException) ex;
}
if (ex instanceof Error) {
throw (Error) ex;
}
if (ex instanceof IOException) {
throw (IOException) ex;
}
if (ex instanceof ServletException) {
throw (ServletException) ex;
}
throw new IllegalStateException(ex);
}
@Override
public void addErrorPages(ErrorPage... errorPages) {
for (ErrorPage errorPage : errorPages) {
if (errorPage.isGlobal()) {
this.global = errorPage.getPath();
}
else if (errorPage.getStatus() != null) {
this.statuses.put(errorPage.getStatus().value(), errorPage.getPath());
}
else {
this.exceptions.put(errorPage.getException(), errorPage.getPath());
}
}
}
@Override
public void destroy() {
}
private static class ErrorWrapperResponse extends HttpServletResponseWrapper {
private int status;
private String message;
private boolean hasErrorToSend = false;
ErrorWrapperResponse(HttpServletResponse response) {
super(response);
}
@Override
public void sendError(int status) throws IOException {
sendError(status, null);
}
@Override
public void sendError(int status, String message) throws IOException {
this.status = status;
this.message = message;
this.hasErrorToSend = true;
// Do not call super because the container may prevent us from handling the
// error ourselves
}
@Override
public int getStatus() {
if (this.hasErrorToSend) {
return this.status;
}
// If there was no error we need to trust the wrapped response
return super.getStatus();
}
@Override
public void flushBuffer() throws IOException {
if (this.hasErrorToSend && !isCommitted()) {
((HttpServletResponse) getResponse()).sendError(this.status,
this.message);
}
super.flushBuffer();
}
public String getMessage() {
return this.message;
}
public boolean hasErrorToSend() {
return this.hasErrorToSend;
}
}
}

View File

@ -0,0 +1,84 @@
/*
* Copyright 2010-2016 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.web.support;
import javax.servlet.ServletContext;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextInitializer;
import org.springframework.core.Ordered;
import org.springframework.web.context.ConfigurableWebApplicationContext;
import org.springframework.web.context.WebApplicationContext;
/**
* {@link ApplicationContextInitializer} for setting the servlet context.
*
* @author Dave Syer
* @author Phillip Webb
* @since 1.4.0
*/
public class ServletContextApplicationContextInitializer implements
ApplicationContextInitializer<ConfigurableWebApplicationContext>, Ordered {
private int order = Ordered.HIGHEST_PRECEDENCE;
private final ServletContext servletContext;
private final boolean addApplicationContextAttribute;
/**
* Create a new {@link ServletContextApplicationContextInitializer} instance.
* @param servletContext the servlet that should be ultimately set.
*/
public ServletContextApplicationContextInitializer(ServletContext servletContext) {
this(servletContext, false);
}
/**
* Create a new {@link ServletContextApplicationContextInitializer} instance.
* @param servletContext the servlet that should be ultimately set.
* @param addApplicationContextAttribute if the {@link ApplicationContext} should be
* stored as an attribute in the {@link ServletContext}
* @since 1.3.4
*/
public ServletContextApplicationContextInitializer(ServletContext servletContext,
boolean addApplicationContextAttribute) {
this.servletContext = servletContext;
this.addApplicationContextAttribute = addApplicationContextAttribute;
}
public void setOrder(int order) {
this.order = order;
}
@Override
public int getOrder() {
return this.order;
}
@Override
public void initialize(ConfigurableWebApplicationContext applicationContext) {
applicationContext.setServletContext(this.servletContext);
if (this.addApplicationContextAttribute) {
this.servletContext.setAttribute(
WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE,
applicationContext);
}
}
}

View File

@ -0,0 +1,176 @@
/*
* Copyright 2012-2016 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.web.support;
import javax.servlet.Filter;
import javax.servlet.Servlet;
import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletException;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.builder.ParentContextApplicationContextInitializer;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext;
import org.springframework.boot.web.servlet.ServletContextInitializer;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.util.Assert;
import org.springframework.web.WebApplicationInitializer;
import org.springframework.web.context.ContextLoaderListener;
import org.springframework.web.context.WebApplicationContext;
/**
* An opinionated {@link WebApplicationInitializer} to run a {@link SpringApplication}
* from a traditional WAR deployment. Binds {@link Servlet}, {@link Filter} and
* {@link ServletContextInitializer} beans from the application context to the servlet
* container.
* <p>
* To configure the application either override the
* {@link #configure(SpringApplicationBuilder)} method (calling
* {@link SpringApplicationBuilder#sources(Object...)}) or make the initializer itself a
* {@code @Configuration}. If you are using {@link SpringBootServletInitializer} in
* combination with other {@link WebApplicationInitializer WebApplicationInitializers} you
* might also want to add an {@code @Ordered} annotation to configure a specific startup
* order.
* <p>
* Note that a WebApplicationInitializer is only needed if you are building a war file and
* deploying it. If you prefer to run an embedded container then you won't need this at
* all.
*
* @author Dave Syer
* @author Phillip Webb
* @author Andy Wilkinson
* @since 1.4.0
* @see #configure(SpringApplicationBuilder)
*/
public abstract class SpringBootServletInitializer implements WebApplicationInitializer {
protected Log logger; // Don't initialize early
private boolean registerErrorPageFilter = true;
/**
* Set if the {@link ErrorPageFilter} should be registered. Set to {@code false} if
* error page mappings should be handled via the Servlet container and not Spring
* Boot.
* @param registerErrorPageFilter if the {@link ErrorPageFilter} should be registered.
*/
protected final void setRegisterErrorPageFilter(boolean registerErrorPageFilter) {
this.registerErrorPageFilter = registerErrorPageFilter;
}
@Override
public void onStartup(ServletContext servletContext) throws ServletException {
// Logger initialization is deferred in case a ordered
// LogServletContextInitializer is being used
this.logger = LogFactory.getLog(getClass());
WebApplicationContext rootAppContext = createRootApplicationContext(
servletContext);
if (rootAppContext != null) {
servletContext.addListener(new ContextLoaderListener(rootAppContext) {
@Override
public void contextInitialized(ServletContextEvent event) {
// no-op because the application context is already initialized
}
});
}
else {
this.logger.debug("No ContextLoaderListener registered, as "
+ "createRootApplicationContext() did not "
+ "return an application context");
}
}
protected WebApplicationContext createRootApplicationContext(
ServletContext servletContext) {
SpringApplicationBuilder builder = createSpringApplicationBuilder();
builder.main(getClass());
ApplicationContext parent = getExistingRootWebApplicationContext(servletContext);
if (parent != null) {
this.logger.info("Root context already created (using as parent).");
servletContext.setAttribute(
WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, null);
builder.initializers(new ParentContextApplicationContextInitializer(parent));
}
builder.initializers(
new ServletContextApplicationContextInitializer(servletContext));
builder.contextClass(AnnotationConfigEmbeddedWebApplicationContext.class);
builder = configure(builder);
SpringApplication application = builder.build();
if (application.getSources().isEmpty() && AnnotationUtils
.findAnnotation(getClass(), Configuration.class) != null) {
application.getSources().add(getClass());
}
Assert.state(!application.getSources().isEmpty(),
"No SpringApplication sources have been defined. Either override the "
+ "configure method or add an @Configuration annotation");
// Ensure error pages are registered
if (this.registerErrorPageFilter) {
application.getSources().add(ErrorPageFilter.class);
}
return run(application);
}
/**
* Returns the {@code SpringApplicationBuilder} that is used to configure and create
* the {@link SpringApplication}. The default implementation returns a new
* {@code SpringApplicationBuilder} in its default state.
* @return the {@code SpringApplicationBuilder}.
* @since 1.3.0
*/
protected SpringApplicationBuilder createSpringApplicationBuilder() {
return new SpringApplicationBuilder();
}
/**
* Called to run a fully configured {@link SpringApplication}.
* @param application the application to run
* @return the {@link WebApplicationContext}
*/
protected WebApplicationContext run(SpringApplication application) {
return (WebApplicationContext) application.run();
}
private ApplicationContext getExistingRootWebApplicationContext(
ServletContext servletContext) {
Object context = servletContext.getAttribute(
WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE);
if (context instanceof ApplicationContext) {
return (ApplicationContext) context;
}
return null;
}
/**
* Configure the application. Normally all you would need to do it add sources (e.g.
* config classes) because other settings have sensible defaults. You might choose
* (for instance) to add default command line arguments, or set an active Spring
* profile.
* @param builder a builder for the application context
* @return the application builder
* @see SpringApplicationBuilder
*/
protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {
return builder;
}
}

View File

@ -74,6 +74,10 @@ import org.mockito.InOrder;
import org.springframework.boot.ApplicationHome;
import org.springframework.boot.ApplicationTemp;
import org.springframework.boot.context.embedded.Ssl.ClientAuth;
import org.springframework.boot.web.servlet.ErrorPage;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.boot.web.servlet.ServletContextInitializer;
import org.springframework.boot.web.servlet.ServletRegistrationBean;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.springframework.http.HttpMethod;

View File

@ -29,6 +29,7 @@ import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.embedded.config.ExampleEmbeddedWebApplicationConfiguration;
import org.springframework.boot.testutil.MockServlet;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Scope;

View File

@ -25,6 +25,7 @@ import org.junit.Test;
import org.springframework.boot.context.embedded.jetty.JettyEmbeddedServletContainerFactory;
import org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedServletContainerFactory;
import org.springframework.boot.context.embedded.undertow.UndertowEmbeddedServletContainerFactory;
import org.springframework.boot.web.servlet.ServletRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;

View File

@ -18,8 +18,10 @@ package org.springframework.boot.context.embedded;
import java.io.IOException;
import java.lang.reflect.Field;
import java.util.EnumSet;
import java.util.Properties;
import javax.servlet.DispatcherType;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.Servlet;
@ -48,7 +50,10 @@ import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.config.ConstructorArgumentValues;
import org.springframework.beans.factory.config.Scope;
import org.springframework.beans.factory.support.RootBeanDefinition;
import org.springframework.boot.context.web.ServerPortInfoApplicationContextInitializer;
import org.springframework.boot.web.servlet.DelegatingFilterProxyRegistrationBean;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.boot.web.servlet.ServletContextInitializer;
import org.springframework.boot.web.servlet.ServletRegistrationBean;
import org.springframework.context.ApplicationContextException;
import org.springframework.context.ApplicationListener;
import org.springframework.context.support.AbstractApplicationContext;
@ -81,6 +86,13 @@ import static org.mockito.Mockito.withSettings;
*/
public class EmbeddedWebApplicationContextTests {
private static final EnumSet<DispatcherType> ASYNC_DISPATCHER_TYPES = EnumSet.of(
DispatcherType.FORWARD, DispatcherType.INCLUDE, DispatcherType.REQUEST,
DispatcherType.ASYNC);
private static final EnumSet<DispatcherType> NON_ASYNC_DISPATCHER_TYPES = EnumSet
.of(DispatcherType.FORWARD, DispatcherType.INCLUDE, DispatcherType.REQUEST);
@Rule
public ExpectedException thrown = ExpectedException.none();
@ -302,10 +314,10 @@ public class EmbeddedWebApplicationContextTests {
verify(escf.getRegisteredServlet(0).getRegistration()).addMapping("/");
ordered.verify(escf.getServletContext()).addFilter("filterBean1", filter1);
ordered.verify(escf.getServletContext()).addFilter("filterBean2", filter2);
verify(escf.getRegisteredFilter(0).getRegistration()).addMappingForUrlPatterns(
AbstractFilterRegistrationBean.ASYNC_DISPATCHER_TYPES, false, "/*");
verify(escf.getRegisteredFilter(1).getRegistration()).addMappingForUrlPatterns(
AbstractFilterRegistrationBean.ASYNC_DISPATCHER_TYPES, false, "/*");
verify(escf.getRegisteredFilter(0).getRegistration())
.addMappingForUrlPatterns(ASYNC_DISPATCHER_TYPES, false, "/*");
verify(escf.getRegisteredFilter(1).getRegistration())
.addMappingForUrlPatterns(ASYNC_DISPATCHER_TYPES, false, "/*");
}
@Test

View File

@ -1,5 +1,5 @@
/*
* Copyright 2012-2013 the original author or authors.
* Copyright 2012-2016 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.
@ -35,6 +35,8 @@ import javax.servlet.ServletRegistration;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;
import org.springframework.boot.web.servlet.ServletContextInitializer;
import static org.mockito.BDDMockito.given;
import static org.mockito.Matchers.anyObject;
import static org.mockito.Matchers.anyString;

View File

@ -1,5 +1,5 @@
/*
* Copyright 2012-2013 the original author or authors.
* Copyright 2012-2016 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.
@ -21,7 +21,7 @@ import javax.servlet.Servlet;
import org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContextTests;
import org.springframework.boot.context.embedded.EmbeddedServletContainerFactory;
import org.springframework.boot.context.embedded.MockEmbeddedServletContainerFactory;
import org.springframework.boot.context.embedded.MockServlet;
import org.springframework.boot.testutil.MockServlet;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

View File

@ -43,8 +43,8 @@ import org.mockito.InOrder;
import org.springframework.boot.context.embedded.AbstractEmbeddedServletContainerFactory;
import org.springframework.boot.context.embedded.AbstractEmbeddedServletContainerFactoryTests;
import org.springframework.boot.context.embedded.Compression;
import org.springframework.boot.context.embedded.ServletRegistrationBean;
import org.springframework.boot.context.embedded.Ssl;
import org.springframework.boot.web.servlet.ServletRegistrationBean;
import org.springframework.http.HttpHeaders;
import static org.assertj.core.api.Assertions.assertThat;

View File

@ -37,10 +37,10 @@ import org.mockito.InOrder;
import org.springframework.boot.context.embedded.AbstractEmbeddedServletContainerFactory;
import org.springframework.boot.context.embedded.AbstractEmbeddedServletContainerFactoryTests;
import org.springframework.boot.context.embedded.ErrorPage;
import org.springframework.boot.context.embedded.ExampleServlet;
import org.springframework.boot.context.embedded.MimeMappings.Mapping;
import org.springframework.boot.context.embedded.ServletRegistrationBean;
import org.springframework.boot.web.servlet.ErrorPage;
import org.springframework.boot.web.servlet.ServletRegistrationBean;
import org.springframework.http.HttpStatus;
import org.springframework.test.util.ReflectionTestUtils;

View File

@ -1,5 +1,5 @@
/*
* Copyright 2012-2013 the original author or authors.
* Copyright 2012-2016 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.
@ -14,7 +14,7 @@
* limitations under the License.
*/
package org.springframework.boot.context.embedded;
package org.springframework.boot.testutil;
import java.io.IOException;

View File

@ -1,5 +1,5 @@
/*
* Copyright 2012-2013 the original author or authors.
* Copyright 2012-2016 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.
@ -14,7 +14,7 @@
* limitations under the License.
*/
package org.springframework.boot.context.embedded;
package org.springframework.boot.testutil;
import java.io.IOException;

View File

@ -1,5 +1,5 @@
/*
* Copyright 2012-2015 the original author or authors.
* Copyright 2012-2016 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.
@ -14,7 +14,7 @@
* limitations under the License.
*/
package org.springframework.boot.context.embedded;
package org.springframework.boot.web.servlet;
import java.util.Arrays;
import java.util.Collections;
@ -49,6 +49,13 @@ import static org.mockito.Mockito.verify;
*/
public abstract class AbstractFilterRegistrationBeanTests {
private static final EnumSet<DispatcherType> ASYNC_DISPATCHER_TYPES = EnumSet.of(
DispatcherType.FORWARD, DispatcherType.INCLUDE, DispatcherType.REQUEST,
DispatcherType.ASYNC);
private static final EnumSet<DispatcherType> NON_ASYNC_DISPATCHER_TYPES = EnumSet
.of(DispatcherType.FORWARD, DispatcherType.INCLUDE, DispatcherType.REQUEST);
@Rule
public ExpectedException thrown = ExpectedException.none();
@ -71,8 +78,8 @@ public abstract class AbstractFilterRegistrationBeanTests {
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, "/*");
verify(this.registration).addMappingForUrlPatterns(ASYNC_DISPATCHER_TYPES, false,
"/*");
}
@Test
@ -97,12 +104,10 @@ public abstract class AbstractFilterRegistrationBeanTests {
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");
verify(this.registration).addMappingForUrlPatterns(NON_ASYNC_DISPATCHER_TYPES,
true, "/a", "/b", "/c");
verify(this.registration).addMappingForServletNames(NON_ASYNC_DISPATCHER_TYPES,
true, "s4", "s5", "s1", "s2", "s3");
}
@Test
@ -152,8 +157,8 @@ public abstract class AbstractFilterRegistrationBeanTests {
bean.setServletRegistrationBeans(new LinkedHashSet<ServletRegistrationBean>(
Arrays.asList(mockServletRegistration("b"))));
bean.onStartup(this.servletContext);
verify(this.registration).addMappingForServletNames(
AbstractFilterRegistrationBean.ASYNC_DISPATCHER_TYPES, false, "b");
verify(this.registration).addMappingForServletNames(ASYNC_DISPATCHER_TYPES, false,
"b");
}
@Test

View File

@ -14,7 +14,7 @@
* limitations under the License.
*/
package org.springframework.boot.context.embedded;
package org.springframework.boot.web.servlet;
import javax.servlet.Filter;

View File

@ -1,5 +1,5 @@
/*
* Copyright 2012-2015 the original author or authors.
* Copyright 2012-2016 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.
@ -14,12 +14,14 @@
* limitations under the License.
*/
package org.springframework.boot.context.embedded;
package org.springframework.boot.web.servlet;
import javax.servlet.Filter;
import org.junit.Test;
import org.springframework.boot.testutil.MockFilter;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.verify;

View File

@ -14,7 +14,7 @@
* limitations under the License.
*/
package org.springframework.boot.context.embedded;
package org.springframework.boot.web.servlet;
import javax.servlet.MultipartConfigElement;

View File

@ -20,8 +20,8 @@ import org.junit.After;
import org.junit.Test;
import org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext;
import org.springframework.boot.context.embedded.ServerPortInfoApplicationContextInitializer;
import org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedServletContainerFactory;
import org.springframework.boot.context.web.ServerPortInfoApplicationContextInitializer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;

View File

@ -1,5 +1,5 @@
/*
* Copyright 2012-2014 the original author or authors.
* Copyright 2012-2016 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.
@ -14,7 +14,7 @@
* limitations under the License.
*/
package org.springframework.boot.context.embedded;
package org.springframework.boot.web.servlet;
import java.util.EventListener;

View File

@ -1,5 +1,5 @@
/*
* Copyright 2012-2015 the original author or authors.
* Copyright 2012-2016 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.
@ -14,7 +14,7 @@
* limitations under the License.
*/
package org.springframework.boot.context.embedded;
package org.springframework.boot.web.servlet;
import java.util.Arrays;
import java.util.Collections;
@ -35,6 +35,8 @@ import org.junit.rules.ExpectedException;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.springframework.boot.testutil.MockServlet;
import static org.mockito.BDDMockito.given;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.anyObject;

View File

@ -14,7 +14,7 @@
* limitations under the License.
*/
package org.springframework.boot.context.web;
package org.springframework.boot.web.support;
import java.net.URI;
import java.util.concurrent.CountDownLatch;
@ -32,8 +32,7 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext;
import org.springframework.boot.context.embedded.EmbeddedServletContainerFactory;
import org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedServletContainerFactory;
import org.springframework.boot.context.web.ErrorPageFilterIntegrationTests.EmbeddedWebContextLoader;
import org.springframework.boot.context.web.ErrorPageFilterIntegrationTests.TomcatConfig;
import org.springframework.boot.web.support.ErrorPageFilterIntegrationTests.EmbeddedWebContextLoader;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@ -66,7 +65,7 @@ import static org.assertj.core.api.Assertions.assertThat;
*/
@RunWith(SpringRunner.class)
@DirtiesContext
@ContextConfiguration(classes = TomcatConfig.class, loader = EmbeddedWebContextLoader.class)
@ContextConfiguration(classes = ErrorPageFilterIntegrationTests.TomcatConfig.class, loader = EmbeddedWebContextLoader.class)
public class ErrorPageFilterIntegrationTests {
@Autowired

View File

@ -14,7 +14,7 @@
* limitations under the License.
*/
package org.springframework.boot.context.web;
package org.springframework.boot.web.support;
import java.io.IOException;
@ -28,8 +28,8 @@ import javax.servlet.http.HttpServletResponseWrapper;
import org.junit.Rule;
import org.junit.Test;
import org.springframework.boot.context.embedded.ErrorPage;
import org.springframework.boot.testutil.InternalOutputCapture;
import org.springframework.boot.web.servlet.ErrorPage;
import org.springframework.http.HttpStatus;
import org.springframework.mock.web.MockFilterChain;
import org.springframework.mock.web.MockFilterConfig;

View File

@ -14,7 +14,7 @@
* limitations under the License.
*/
package org.springframework.boot.context.web;
package org.springframework.boot.web.support;
import javax.servlet.ServletContext;

View File

@ -6,6 +6,6 @@
<bean name="servletContainerFactory"
class="org.springframework.boot.context.embedded.MockEmbeddedServletContainerFactory" />
<bean name="servlet" class="org.springframework.boot.context.embedded.MockServlet"/>
<bean name="servlet" class="org.springframework.boot.testutil.MockServlet"/>
</beans>