Spring MVC Несколько сервлетов с аннотацией Java - PullRequest
1 голос
/ 16 апреля 2019

При попытке настроить несколько сервлетов и переходе от конфигурации на основе 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.

...