При попытке настроить несколько сервлетов и переходе от конфигурации на основе XML к аннотации Java, аннотация @EnableWebMvc
, похоже, работает по-другому, по сравнению с <mvc:annotation-driven/>
Я перешел и преобразовал xmlконфигурации для аннотированных классов Java.Тем не менее, при регистрации классов Java в моем WebApplicationInitializer конфигурации XML прекрасно загружают мои контроллеры для каждого сервлета, но при использовании аннотации Java, я получаю 404 на моих контроллерах.Если я зарегистрирую только один сервлет с конфигурацией аннотаций, он будет работать нормально, но два или более результата приведут к 404.
web-servlet.xml
<beans...>
<context:component-scan base-package="com.foo.bar" use-default-filters="false">
<context:include-filter expression="org.springframework.stereotype.Controller" type="annotation"/>
<context:exclude-filter type="aspectj" expression="com.foo.bar.server.external.*"/>
</context:component-scan>
<security:global-method-security proxy-target-class="true" secured-annotations="enabled" pre-post-annotations="enabled"/>
<mvc:annotation-driven/>
<mvc:resources location="/, classpath:/META-INF/web-resources/" mapping="/resources/**"/>
<mvc:default-servlet-handler/>
<mvc:interceptors>
...
</mvc:interceptors>
<!-- selects a static view for rendering without the need for an explicit controller -->
<mvc:view-controller path="/login"/>
<bean id="contentNegotiationManager" class="org.springframework.web.accept.ContentNegotiationManagerFactoryBean">
<property name="ignoreAcceptHeader" value="true"/>
<property name="mediaTypes">
<map>
<entry key="json" value="application/json"/>
</map>
</property>
</bean>
<bean class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver">
<property name="contentNegotiationManager" ref="contentNegotiationManager"/>
<property name="defaultViews">
<list>
<bean class="org.springframework.web.servlet.view.json.MappingJackson2JsonView" />
</list>
</property>
<property name="order" value="1" />
</bean>
</beans>
web-servlet.java
@Configuration
@EnableWebMvc
@ComponentScan(basePackages = "com.foo.bar",
useDefaultFilters = false,
includeFilters = @ComponentScan.Filter(type = FilterType.ANNOTATION, value = Controller.class),
excludeFilters = {
@ComponentScan.Filter(type = FilterType.ASPECTJ, pattern = "com.foo.bar.server.external.*"),
@ComponentScan.Filter(type = FilterType.ASPECTJ, pattern = "com.foo.bar.web..*")
}
)
@EnableGlobalMethodSecurity(proxyTargetClass = true, securedEnabled = true, prePostEnabled = true)
public class WebServlet extends WebMvcConfigurerAdapter {
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/resources/**").addResourceLocations("/, classpath:/META-INF/web-resources/");
}
@Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/login");
}
@Override
public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
configurer.enable();
}
@Override
public void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
configurer.ignoreAcceptHeader(true);
configurer.mediaType("json", MediaType.APPLICATION_JSON);
}
@Override
public void addInterceptors(InterceptorRegistry registry) {
...
}
@Bean
public ViewResolver contentNegotiatingViewResolver(ContentNegotiationManager manager) {
ContentNegotiatingViewResolver resolver = new ContentNegotiatingViewResolver();
resolver.setContentNegotiationManager(manager);
// Define all possible view resolvers
List<View> defaultViews = new ArrayList<>();
defaultViews.add(mappingJackson2JsonView());
resolver.setDefaultViews(defaultViews);
return resolver;
}
@Bean
public MappingJackson2JsonView mappingJackson2JsonView() {
MappingJackson2JsonView mappingJackson2JsonView = new MappingJackson2JsonView();
mappingJackson2JsonView.setPrettyPrint(true);
return mappingJackson2JsonView;
}
}
external-servlet
<beans...>
<context:component-scan base-package="com.foo.bar.server.external" use-default-filters="false">
<context:include-filter expression="org.springframework.stereotype.Controller" type="annotation"/>
</context:component-scan>
<mvc:annotation-driven/>
<mvc:interceptors>
<bean class="com.foo.bar.server.external.CheckExtInterceptor"/>
</mvc:interceptors>
</beans>
external-servlet.java
@Configuration
@ComponentScan(basePackages = "com.foo.bar.server.external",
useDefaultFilters = false,
includeFilters = @ComponentScan.Filter(type = FilterType.ANNOTATION, value = Controller.class))
@EnableWebMvc
public class ExtServlet extends WebMvcConfigurerAdapter {
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(checkExtInterceptor());
}
@Bean
public checkExtInterceptor checkExtInterceptor() {
return new CheckExtInterceptor();
}
}
webAppInitializer.java
public class FooWebAppInitializer implements WebApplicationInitializer {
@Override
public void onStartup(ServletContext servletContext) throws ServletException {
servletContext.setInitParameter("defaultHtmlEscape", "true");
servletContext.setInitParameter("spring.profiles.default", "dev");
AnnotationConfigWebApplicationContext rootContext = new AnnotationConfigWebApplicationContext();
rootContext.setDisplayName("Foo Bar");
rootContext.register(FooApplication.class);
rootContext.setServletContext(servletContext);
createFilters(servletContext);
servletContext.addListener(new Log4jConfigListener());
servletContext.addListener(new ContextLoaderListener(rootContext));
// THIS WORKS
// XmlWebApplicationContext webContext = new XmlWebApplicationContext();
// webContext.setConfigLocation("/WEB-INF/spring/web-servlet.xml");
// THIS DOESN'T WHEN 2 SERVLETS ARE REGISTERED
AnnotationConfigWebApplicationContext webContext = new AnnotationConfigWebApplicationContext();
webContext.register(WebServlet.class);
ServletRegistration.Dynamic webServlet = servletContext.addServlet("web", new DispatcherServlet(webContext));
webServlet.setLoadOnStartup(1);
webServlet.addMapping( "/*");
// THIS WORKS
// XmlWebApplicationContext extContext = new XmlWebApplicationContext();
// extContext.setConfigLocation("/WEB-INF/spring/ext-servlet.xml");
// THIS DOESN'T WHEN 2 SERVLETS ARE REGISTERED
AnnotationConfigWebApplicationContext extContext = new AnnotationConfigWebApplicationContext();
extContext.register(ExtServlet.class);
ServletRegistration.Dynamic extServlet = servletContext.addServlet("ext",
new DispatcherServlet(extContext));
extServlet.setLoadOnStartup(2);
extServlet.addMapping("/ext/*");
}
}
Я ожидаюКонфигурация аннотации должна действовать одинаково, но не уверен, что будет лежать в основе разницы.Существует не так много информации о наличии двух сервлетов с @EnableWebMvc
на обоих сервлетах, и контроллеры не должны возвращать 404, если не используются конфигурации XML.