【问题标题】:Why are WebMvcConfigurer override methods not working?为什么 WebMvcConfigurer 覆盖方法不起作用?
【发布时间】:2019-12-07 13:11:27
【问题描述】:

我用 Spring Boot 创建了一个项目。我正在配置基本配置,但是在实现 WebMvcConfigurer 时出现了问题。

addInterceptors 运行良好,但 addViewControllers 和 addResourceHandlers 不起作用。没有错误,但这两种方法都不适用。

我想我设置好了,但我找不到原因。我能明白为什么吗?

【项目结构】

java
--我
----东辉
------样品
--------控制器
----------SampleController.java
------配置
--------RootContextConfig.java
--------Application.java
--------DispatcherServletConfig.java

[RootContextConfig.java]

@Configuration
@ComponentScan(
        basePackages = {"me.eastglow.*"},
        excludeFilters = {@Filter(Controller.class)}
)
public class RootContextConfig {
}

[Application.java]

@SpringBootApplication
public class Application extends SpringBootServletInitializer {

    protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
        return application.sources(Application.class);
    }

    @Override
    public void onStartup(ServletContext container) throws ServletException {

        // Create the 'root' Spring application context
        AnnotationConfigWebApplicationContext rootContext = new AnnotationConfigWebApplicationContext();
        rootContext.register(RootContextConfig.class);

        // Manage the lifecycle of the root application context
        container.addListener(new ContextLoaderListener(rootContext));

        // Create the dispatcher servlet's Spring application context
        AnnotationConfigWebApplicationContext dispatcherServlet = new AnnotationConfigWebApplicationContext();
        dispatcherServlet.register(DispatcherServletConfig.class);

        // Register and map the dispatcher servlet
        ServletRegistration.Dynamic dispatcher = container.addServlet("appServlet", new DispatcherServlet(dispatcherServlet));
        dispatcher.setLoadOnStartup(1);
        dispatcher.addMapping("*.json");
        dispatcher.addMapping("*.do");
    }

}

[DispatcherServletConfig.java]

@Configuration
@ComponentScan(
        basePackages={"me.eastglow.*"},
        useDefaultFilters = false,
        includeFilters={@Filter(Controller.class)},
        excludeFilters={@Filter(Service.class), @Filter(Repository.class)}
)
@EnableWebMvc
@PropertySource(
        value={"classpath:application-${spring.profiles.active}.properties", "classpath:log4jdbc.log4j2.properties"},
        ignoreResourceNotFound = true)
public class DispatcherServletConfig implements WebMvcConfigurer {

    private final static String[] RESOURCE_HANDLER_PATH = {"/favicon.ico"
            , "/image/**"
            , "/js/**"};
    private final static String[] RESOURCE_HANDLER_LOCATION = {"/resources/favicon.ico"
            , "/resources/image/"
            , "/resources/js/"};

    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        CacheControl cacheControl = CacheControl.empty().cachePrivate();

        registry.addResourceHandler(RESOURCE_HANDLER_PATH).addResourceLocations(RESOURCE_HANDLER_LOCATION).setCacheControl(cacheControl);
    }

    @Override
    public void addViewControllers(ViewControllerRegistry registry) {
        registry.addViewController("/").setViewName("redirect:/member/login.do");
    }

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new BusinessInterceptor()).addPathPatterns("/**");
    }

    @Bean
    public ViewResolver contentNegotiatingViewResolver(ContentNegotiationManager manager) {
        List<ViewResolver> resolvers = new ArrayList<>();

        InternalResourceViewResolver internalResourceViewResolver = new InternalResourceViewResolver();
        internalResourceViewResolver.setViewClass(JstlView.class);
        internalResourceViewResolver.setPrefix("/WEB-INF/views/");
        internalResourceViewResolver.setSuffix(".jsp");
        resolvers.add(internalResourceViewResolver);

        ContentNegotiatingViewResolver resolver = new ContentNegotiatingViewResolver();
        resolver.setViewResolvers(resolvers);
        resolver.setContentNegotiationManager(manager);


        return resolver;
    }
}

[更新]

public class DispatcherServletConfig implements WebMvcConfigurer {

    private final static String[] RESOURCE_HANDLER_PATH = {"/favicon.ico"
            , "/image/**"
            , "/js/**"};
    private final static String[] RESOURCE_HANDLER_LOCATION = {"/resources/favicon.ico"
            , "/resources/image/"
            , "/resources/js/"};

    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        CacheControl cacheControl = CacheControl.empty().cachePrivate();

        registry.addResourceHandler(RESOURCE_HANDLER_PATH).addResourceLocations(RESOURCE_HANDLER_LOCATION).setCacheControl(cacheControl);
    }

    @Override
    public void addViewControllers(ViewControllerRegistry registry) {
        registry.addViewController("/").setViewName("redirect:/member/login.do");
    }

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new BusinessInterceptor()).addPathPatterns("/**");
    }

    @Override
    public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
            configurer.enable();
}

    @Override
    public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
        converters.add(new FormHttpMessageConverter());
        converters.add(jacksonMessageConverter()); //Json Message Converter
        converters.add(new StringHttpMessageConverter());
        converters.add(new ResourceHttpMessageConverter()); // File Transfer Message Converter
    }

    @Bean
    public ViewResolver contentNegotiatingViewResolver(ContentNegotiationManager manager) {
        List<ViewResolver> resolvers = new ArrayList<>();

        InternalResourceViewResolver internalResourceViewResolver = new InternalResourceViewResolver();
        internalResourceViewResolver.setViewClass(JstlView.class);
        internalResourceViewResolver.setPrefix("/WEB-INF/views/");
        internalResourceViewResolver.setSuffix(".jsp");
        internalResourceViewResolver.setOrder(2);
        resolvers.add(internalResourceViewResolver);

        JsonViewResolver jsonViewResolver = new JsonViewResolver();
        resolvers.add(jsonViewResolver);

        resolvers.add(beanNameViewResolver());

        ContentNegotiatingViewResolver resolver = new ContentNegotiatingViewResolver();
        resolver.setViewResolvers(resolvers);
        resolver.setContentNegotiationManager(manager);

        return resolver;
    }

    @Bean
    public TilesConfigurer tilesConfigurer() {
        TilesConfigurer configurer = new TilesConfigurer();

        configurer.setDefinitions(new String[]{"/WEB-INF/tiles/tiles.xml"});
        configurer.setCheckRefresh(true);

        return configurer;
    }

    @Bean
    public TilesViewResolver tilesViewResolver() {
        TilesViewResolver viewResolver = new TilesViewResolver();

        viewResolver.setOrder(1);

        return viewResolver;
    }

    class JsonViewResolver implements ViewResolver {
        @Override
        public View resolveViewName(String viewName, Locale locale) {
            MappingJackson2JsonView view = new MappingJackson2JsonView();
            view.setPrettyPrint(true);
            view.setContentType("application/json;charset=UTF-8");
            view.setDisableCaching(true);
            return view;
        }
    }

    @Bean(name="beanNameViewResolver")
    public BeanNameViewResolver beanNameViewResolver(){
        BeanNameViewResolver beanNameViewResolver = new BeanNameViewResolver();
        beanNameViewResolver.setOrder(0);
        return beanNameViewResolver;
    }

    @Bean(name="jacksonMessageConverter")
    public MappingJackson2HttpMessageConverter jacksonMessageConverter(){
        return new MappingJackson2HttpMessageConverter();
    }

    @Bean
    public static PropertySourcesPlaceholderConfigurer placeholderConfigurer() {
        return new PropertySourcesPlaceholderConfigurer();
    }
}

【问题讨论】:

  • 你正在使用 Spring Boot,那你为什么要在 Spring Boot 周围工作......

标签: java spring spring-boot model-view-controller


【解决方案1】:

您正在使用 Spring Boot 而不是使用它。

对于初学者,请删除 Application 类的 onStartup 方法。 Spring Boot 负责所有这些。

接下来放弃你的RootContextConfig

2 清理你的DispatcherServletConfig

@Configuration
@PropertySource(
        value={"classpath:log4jdbc.log4j2.properties"},
        ignoreResourceNotFound = true)
public class DispatcherServletConfig implements WebMvcConfigurer {

    @Override
    public void addViewControllers(ViewControllerRegistry registry) {
        registry.addViewController("/").setViewName("redirect:/member/login.do");
    }

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new BusinessInterceptor());
    }
}

现在在您的application.properties(或创建一个)中添加以下内容

spring.mvc.view.prefix=/WEB-INF/views/
spring.mvc.view.suffix=.jsp

spring.resources.cache.cache-private=true

默认情况下,映射应该可以工作,否则将您的 jsimages 放在 src/main/resources/staticsrc/main/resources/public 中。

如果您正确使用 Spring Boot(而不是解决它),这就是您所需要的。

【讨论】:

  • 感谢您的回答。我有个问题。我想添加一个BeanNameViewResolver或JsonViewResolver的ViewResolver。 Spring Boot 能处理所有这些事情吗?我已经更新了要添加的代码正文。如果您能告诉我您需要哪些修改后的代码,我将不胜感激。
  • BeanNameViewResolver 默认处于活动状态。 AFAIK 没有JsonViewResolver,你应该很好地使用@RestController 并让其他 Spring 基础设施(HttpMessageConverter s)处理 JSON/XML。否则,只需将其定义为 @Bean
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-10-26
  • 2018-07-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多