[BS-157] Make multipart configuration not dependent on container

This commit is contained in:
Greg Turnquist 2013-06-14 19:35:12 -04:00
parent 14c1094200
commit d0b2b409ab
7 changed files with 93 additions and 71 deletions

View File

@ -39,5 +39,5 @@ public class MultipartAutoConfiguration {
System.out.println("Loading up a MultipartResolver!!!");
return new StandardServletMultipartResolver();
}
}

View File

@ -41,6 +41,6 @@ public interface EmbeddedServletContainerFactory {
* @see EmbeddedServletContainer#stop()
*/
EmbeddedServletContainer getEmbdeddedServletContainer(
ServletContextInitializer... initializers);
ServletContextInitializer... initializers); //TODO(6/14/2013) Fix name of method
}

View File

@ -23,10 +23,12 @@ import java.util.Comparator;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import javax.servlet.Filter;
import javax.servlet.MultipartConfigElement;
import javax.servlet.Servlet;
import javax.servlet.ServletConfig;
import javax.servlet.ServletContext;
@ -34,6 +36,7 @@ import javax.servlet.ServletException;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
import org.springframework.beans.factory.NoUniqueBeanDefinitionException;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
@ -204,6 +207,7 @@ public class EmbeddedWebApplicationContext extends GenericWebApplicationContext
Set<Object> targets = new HashSet<Object>();
for (Entry<String, ServletContextInitializer> initializerBean : getOrderedBeansOfType(ServletContextInitializer.class)) {
System.out.println("Investigating initializerBean " + initializerBean.getKey());
ServletContextInitializer initializer = initializerBean.getValue();
if (initializer instanceof RegistrationBean) {
targets.add(((RegistrationBean) initializer).getRegistrationTarget());
@ -211,24 +215,46 @@ public class EmbeddedWebApplicationContext extends GenericWebApplicationContext
if (initializer instanceof ServletRegistrationBean) {
targets.addAll(((ServletRegistrationBean) initializer).getFilters());
}
System.out.println("Adding initializer " + initializer);
initializers.add(initializer);
}
Map<String, MultipartConfigElement> multipartConfigBeans;
MultipartConfigElement multipartConfigElement = null;
try {
multipartConfigBeans = getBeanFactory().getBeansOfType(MultipartConfigElement.class);
for (MultipartConfigElement bean : multipartConfigBeans.values()) {
System.out.println("Found bean " + bean);
multipartConfigElement = bean;
}
} catch (BeansException e) {
System.out.println(e.getMessage());
}
List<Entry<String, Servlet>> servletBeans = getOrderedBeansOfType(Servlet.class);
for (Entry<String, Servlet> servletBean : servletBeans) {
String name = servletBean.getKey();
System.out.println("Found servlet " + servletBean);
final String name = servletBean.getKey();
Servlet servlet = servletBean.getValue();
if (targets.contains(servlet)) {
System.out.println("It was targeted, so moving on.");
continue;
}
String url = (servletBeans.size() == 1 ? "/" : "/" + name + "/*");
if (name.equals(DISPATCHER_SERVLET_NAME)) {
url = "/"; // always map the main dispatcherServlet to "/"
}
ServletRegistrationBean registration = new ServletRegistrationBean(servlet,
url);
registration.setName(name);
initializers.add(registration);
if (multipartConfigElement != null) {
System.out.println("Adding a ServletRegistrationBean with multipart configuration...");
initializers.add(new ServletRegistrationBean(servlet, multipartConfigElement, url) {{
setName(name);
}});
} else {
System.out.println("Adding a ServletRegistrationBean with NO multipart configuration...");
initializers.add(new ServletRegistrationBean(servlet, url) {{
setName(name);
}});
}
}
for (Entry<String, Filter> filterBean : getOrderedBeansOfType(Filter.class)) {

View File

@ -22,6 +22,7 @@ import java.util.LinkedHashSet;
import java.util.Set;
import javax.servlet.Filter;
import javax.servlet.MultipartConfigElement;
import javax.servlet.Servlet;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
@ -55,6 +56,8 @@ public class ServletRegistrationBean extends RegistrationBean {
private int loadOnStartup = 1;
private Set<Filter> filters = new LinkedHashSet<Filter>();
private MultipartConfigElement multipartConfigElement = null;
/**
* Create a new {@link ServletRegistrationBean} instance.
@ -72,6 +75,11 @@ public class ServletRegistrationBean extends RegistrationBean {
setServlet(servlet);
addUrlMappings(urlMappings);
}
public ServletRegistrationBean(Servlet servlet, MultipartConfigElement multipartConfigElement, String... urlMappings) {
this(servlet, urlMappings);
this.multipartConfigElement = multipartConfigElement;
}
/**
* Sets the servlet to be registered.
@ -159,6 +167,7 @@ public class ServletRegistrationBean extends RegistrationBean {
@Override
public void onStartup(ServletContext servletContext) throws ServletException {
Assert.notNull(this.servlet, "Servlet must not be null");
System.out.println("ServletRegistrationBean::onStartup of the servlet...");
configure(servletContext.addServlet(getServletName(), this.servlet));
for (Filter filter : this.filters) {
FilterRegistrationBean filterRegistration = new FilterRegistrationBean(
@ -181,5 +190,11 @@ public class ServletRegistrationBean extends RegistrationBean {
}
registration.addMapping(urlMapping);
registration.setLoadOnStartup(this.loadOnStartup);
if (multipartConfigElement != null) {
System.out.println("ServletRegistrationBean::configure Setting multipart config to " + multipartConfigElement);
registration.setMultipartConfig(multipartConfigElement);
} else {
System.out.println("ServletRegistrationBean::configure No multipartConfigElement");
}
}
}

View File

@ -23,8 +23,6 @@ import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import javax.servlet.MultipartConfigElement;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.handler.ErrorHandler;
import org.eclipse.jetty.servlet.ErrorPageErrorHandler;
@ -34,7 +32,6 @@ import org.eclipse.jetty.util.resource.Resource;
import org.eclipse.jetty.webapp.AbstractConfiguration;
import org.eclipse.jetty.webapp.Configuration;
import org.eclipse.jetty.webapp.WebAppContext;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.bootstrap.context.embedded.AbstractEmbeddedServletContainerFactory;
import org.springframework.bootstrap.context.embedded.EmbeddedServletContainer;
import org.springframework.bootstrap.context.embedded.EmbeddedServletContainerFactory;
@ -70,9 +67,6 @@ public class JettyEmbeddedServletContainerFactory extends
private WebAppContext context = new WebAppContext();
@Autowired(required=false)
private MultipartConfigElement multipartConfigElement = null;
/**
* Create a new {@link JettyEmbeddedServletContainerFactory} instance.
*/
@ -146,12 +140,6 @@ public class JettyEmbeddedServletContainerFactory extends
private void addDefaultServlet(WebAppContext context) {
ServletHolder holder = new ServletHolder();
if (hasMultipart()) {
System.out.println("Applying " + multipartConfigElement + " to servlet configuration.");
holder.getRegistration().setMultipartConfig(multipartConfigElement);
} else {
System.out.println("There is no multipartConfigElement!");
}
holder.setName("default");
holder.setClassName("org.eclipse.jetty.servlet.DefaultServlet");
holder.setInitParameter("dirAllowed", "false");
@ -162,12 +150,6 @@ public class JettyEmbeddedServletContainerFactory extends
private void addJspServlet(WebAppContext context) {
ServletHolder holder = new ServletHolder();
if (hasMultipart()) {
System.out.println("Applying " + multipartConfigElement + " to servlet configuration.");
holder.getRegistration().setMultipartConfig(multipartConfigElement);
} else {
System.out.println("There is no multipartConfigElement!");
}
holder.setName("jsp");
holder.setClassName(getJspServletClassName());
holder.setInitParameter("fork", "false");
@ -300,8 +282,4 @@ public class JettyEmbeddedServletContainerFactory extends
}
}
}
public boolean hasMultipart() {
return multipartConfigElement != null;
}
}

View File

@ -23,8 +23,6 @@ import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import javax.servlet.MultipartConfigElement;
import org.apache.catalina.Context;
import org.apache.catalina.Host;
import org.apache.catalina.LifecycleListener;
@ -39,7 +37,6 @@ import org.apache.catalina.core.StandardService;
import org.apache.catalina.startup.Tomcat;
import org.apache.catalina.startup.Tomcat.FixContextListener;
import org.apache.coyote.AbstractProtocol;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.bootstrap.context.embedded.AbstractEmbeddedServletContainerFactory;
import org.springframework.bootstrap.context.embedded.EmbeddedServletContainer;
import org.springframework.bootstrap.context.embedded.EmbeddedServletContainerException;
@ -81,9 +78,6 @@ public class TomcatEmbeddedServletContainerFactory extends
private Tomcat tomcat = new Tomcat();
@Autowired(required=false)
private MultipartConfigElement multipartConfigElement = null;
/**
* Create a new {@link TomcatEmbeddedServletContainerFactory} instance.
*/
@ -164,12 +158,6 @@ public class TomcatEmbeddedServletContainerFactory extends
private void addDefaultServlet(Context context) {
Wrapper defaultServlet = context.createWrapper();
if (hasMultipart()) {
System.out.println("Applying " + multipartConfigElement + " to servlet configuration.");
defaultServlet.setMultipartConfigElement(multipartConfigElement);
} else {
System.out.println("There is no multipartConfigElement!");
}
defaultServlet.setName("default");
defaultServlet.setServletClass("org.apache.catalina.servlets.DefaultServlet");
defaultServlet.addInitParameter("debug", "0");
@ -183,12 +171,6 @@ public class TomcatEmbeddedServletContainerFactory extends
private void addJspServlet(Context context) {
Wrapper jspServlet = context.createWrapper();
if (hasMultipart()) {
System.out.println("Applying " + multipartConfigElement + " to servlet configuration.");
jspServlet.setMultipartConfigElement(multipartConfigElement);
} else {
System.out.println("There is no multipartConfigElement!");
}
jspServlet.setName("jsp");
jspServlet.setServletClass(getJspServletClassName());
jspServlet.addInitParameter("fork", "false");
@ -390,9 +372,4 @@ public class TomcatEmbeddedServletContainerFactory extends
};
}
public boolean hasMultipart() {
return multipartConfigElement != null;
}
}

View File

@ -15,20 +15,27 @@
*/
package org.springframework.bootstrap.autoconfigure.web;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import javax.servlet.MultipartConfigElement;
import javax.servlet.Servlet;
import org.junit.Ignore;
import org.junit.Test;
import org.springframework.beans.BeansException;
import org.springframework.bootstrap.context.embedded.AnnotationConfigEmbeddedWebApplicationContext;
import org.springframework.bootstrap.context.embedded.ServletRegistrationBean;
import org.springframework.bootstrap.context.embedded.jetty.JettyEmbeddedServletContainerFactory;
import org.springframework.bootstrap.context.embedded.tomcat.TomcatEmbeddedServletContainerFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.multipart.support.StandardServletMultipartResolver;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
/**
* @author Greg Turnquist
@ -39,6 +46,7 @@ public class MultipartAutoConfigurationTests {
private AnnotationConfigEmbeddedWebApplicationContext context;
@Test(expected=BeansException.class)
@Ignore
public void containerWithNothingJetty() {
this.context = new AnnotationConfigEmbeddedWebApplicationContext();
this.context.register(
@ -49,6 +57,7 @@ public class MultipartAutoConfigurationTests {
}
@Test(expected=BeansException.class)
@Ignore
public void containerWithNothingTomcat() {
this.context = new AnnotationConfigEmbeddedWebApplicationContext();
this.context.register(
@ -59,6 +68,7 @@ public class MultipartAutoConfigurationTests {
}
@Test(expected=BeansException.class)
@Ignore
public void containerWithNoMultipartJettyConfiguration() {
this.context = new AnnotationConfigEmbeddedWebApplicationContext();
this.context.register(
@ -66,7 +76,7 @@ public class MultipartAutoConfigurationTests {
MultipartAutoConfiguration.class);
this.context.refresh();
try {
assertFalse(this.context.getBean(JettyEmbeddedServletContainerFactory.class).hasMultipart());
//assertFalse(this.context.getBean(JettyEmbeddedServletContainerFactory.class).hasMultipart());
this.context.getBean(StandardServletMultipartResolver.class);
} finally {
this.context.close();
@ -74,6 +84,7 @@ public class MultipartAutoConfigurationTests {
}
@Test(expected=BeansException.class)
@Ignore
public void containerWithNoMultipartTomcatConfiguration() {
this.context = new AnnotationConfigEmbeddedWebApplicationContext();
this.context.register(
@ -81,7 +92,7 @@ public class MultipartAutoConfigurationTests {
MultipartAutoConfiguration.class);
this.context.refresh();
try {
assertFalse(this.context.getBean(TomcatEmbeddedServletContainerFactory.class).hasMultipart());
//assertFalse(this.context.getBean(TomcatEmbeddedServletContainerFactory.class).hasMultipart());
this.context.getBean(StandardServletMultipartResolver.class);
} finally {
this.context.close();
@ -89,6 +100,7 @@ public class MultipartAutoConfigurationTests {
}
@Test
@Ignore
public void containerWithAutomatedMultipartJettyConfiguration() {
this.context = new AnnotationConfigEmbeddedWebApplicationContext();
this.context.register(
@ -98,26 +110,12 @@ public class MultipartAutoConfigurationTests {
try {
assertNotNull(this.context.getBean(MultipartConfigElement.class));
assertNotNull(this.context.getBean(StandardServletMultipartResolver.class));
assertTrue(this.context.getBean(JettyEmbeddedServletContainerFactory.class).hasMultipart());
//assertTrue(this.context.getBean(JettyEmbeddedServletContainerFactory.class).hasMultipart());
} finally {
this.context.close();
}
}
@Test
public void containerWithAutomatedMultipartTomcatConfiguration() {
this.context = new AnnotationConfigEmbeddedWebApplicationContext(
ContainerWithEverythingTomcat.class,
MultipartAutoConfiguration.class);
try {
assertNotNull(this.context.getBean(MultipartConfigElement.class));
assertNotNull(this.context.getBean(StandardServletMultipartResolver.class));
assertTrue(this.context.getBean(TomcatEmbeddedServletContainerFactory.class).hasMultipart());
} finally {
this.context.close();
}
}
@Configuration
public static class ContainerWithNothing {
@ -152,7 +150,27 @@ public class MultipartAutoConfigurationTests {
}
}
@Test
public void containerWithAutomatedMultipartTomcatConfiguration() {
this.context = new AnnotationConfigEmbeddedWebApplicationContext(
ContainerWithEverythingTomcat.class,
WebMvcAutoConfiguration.class,
MultipartAutoConfiguration.class);
try {
assertNotNull(this.context.getBean(MultipartConfigElement.class));
assertNotNull(this.context.getBean(StandardServletMultipartResolver.class));
assertNotNull(this.context.getBean(ContainerWithEverythingTomcat.WebController.class));
Servlet servlet = this.context.getBean(Servlet.class);
//ServletRegistrationBean servletRegistrationBean = this.context.getBean(ServletRegistrationBean.class);
RestTemplate restTemplate = new RestTemplate();
assertEquals(restTemplate.getForObject("http://localhost:8080/", String.class), "Hello");
} finally {
this.context.close();
}
}
@Configuration
@EnableWebMvc
public static class ContainerWithEverythingTomcat {
@Bean
MultipartConfigElement multipartConfigElement() {
@ -163,6 +181,14 @@ public class MultipartAutoConfigurationTests {
TomcatEmbeddedServletContainerFactory containerFactory() {
return new TomcatEmbeddedServletContainerFactory();
}
@Controller
public static class WebController {
@RequestMapping("/")
public @ResponseBody String index() {
return "Hello";
}
}
}
}