乐趣区

关于java:SpringMVC-解析五MVC配置

通过后面的介绍,咱们晓得 Spring MVC 是一个以 DispatcherServlet 为核心,泛滥组件协同工作的 Servlet 服务。Spring 中容许用户灵便的配置 MVC 中的各个组件,这就是 Spring MVC 配置的意义。本文会对 Spring 提供的各个 MVC 配置进行具体的介绍,本文次要参考了 Spring 的官网文档。

MVC 配置

启用 MVC 配置

应用 MVC 配置的第一步必定是开启 MVC 配置,Spring 提供了 @EnableWebMvc 注解来启用 MVC 配置,该注解会引入解析 MVC 配置的组件。

@Configuration
@EnableWebMvc
public class WebConfig {}

WebMvcConfigurer

MVC 的组件比拟多,构造比较复杂,用户在不理解源码的状况下很难间接进行配置,所以 Spring 提供了 WebMvcConfigurer 用于通知用户有哪些属性能够配置。下文咱们会一一介绍接口中的办法。

类型转换服务

咱们能够通过 FormatterRegistry 向配置中注册类型转换和格式化等服务,如下就配置了 MVC 日期与 String 类型之间的转换逻辑。

@Configuration
@EnableWebMvc
public class WebConfig implements WebMvcConfigurer {

    @Override
    public void addFormatters(FormatterRegistry registry) {DateTimeFormatterRegistrar registrar = new DateTimeFormatterRegistrar();
        registrar.setUseIsoFormat(true);
        registrar.registerFormatters(registry);
    }
}

校验服务

Spring 容器默认提供了参数校验服务 Validator,Controller 中的参数会由 Validator 进行校验,MVC 配置容许用户自定义校验逻辑,接口定义如下所示:

@Configuration
@EnableWebMvc
public class WebConfig implements WebMvcConfigurer {

    @Override
    public Validator getValidator() {// ...}
}

拦截器

Spring 容许用户对所有的申请进行对立解决,如权限校验、时区参数设置等等,解决逻辑能够放在申请解决前、申请解决后和申请解决实现,配置的逻辑如下所示。

@Configuration
@EnableWebMvc
public class WebConfig implements WebMvcConfigurer {

    @Override
    public void addInterceptors(InterceptorRegistry registry) {registry.addInterceptor(new LocaleChangeInterceptor());
        registry.addInterceptor(new ThemeChangeInterceptor()).addPathPatterns("/**").excludePathPatterns("/admin/**");
        registry.addInterceptor(new SecurityInterceptor()).addPathPatterns("/secure/*");
    }
}

音讯转换服务

下面咱们介绍了 FormatterRegistry,FormatterRegistry 次要提供了简略类型之间的转换,如 String 转 int 等,然而对于简单申请体的转换,如 @RequestBody 中的 JSON 反序列化为对象等操作,就须要 HttpMessageConverter 的参加了。Spring 默认提供了很多常见的转换服务如 Jackson 转换和货币日期等的转换。

@Configuration
@EnableWebMvc
public class WebConfiguration implements WebMvcConfigurer {

    @Override
    public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {Jackson2ObjectMapperBuilder builder = new Jackson2ObjectMapperBuilder()
                .indentOutput(true)
                .dateFormat(new SimpleDateFormat("yyyy-MM-dd"))
                .modulesToInstall(new ParameterNamesModule());
        converters.add(new MappingJackson2HttpMessageConverter(builder.build()));
        converters.add(new MappingJackson2XmlHttpMessageConverter(builder.createXmlMapper(true).build()));
    }
}

View 配置

Spring 运行依据申请门路间接返回 View 视图,用户能够通过配置 ViewControllerRegistry 实现这个性能。

@Configuration
@EnableWebMvc
public class WebConfig implements WebMvcConfigurer {

    @Override
    public void addViewControllers(ViewControllerRegistry registry) {registry.addViewController("/").setViewName("home");
    }
}

Spring 还容许用户自定以视图解析逻辑并通过 ViewResolverRegistry 注册到 MVC 中:

@Configuration
@EnableWebMvc
public class WebConfig implements WebMvcConfigurer {

    @Override
    public void configureViewResolvers(ViewResolverRegistry registry) {registry.enableContentNegotiation(new MappingJackson2JsonView());
        registry.freeMarker().cache(false);
    }

    @Bean
    public FreeMarkerConfigurer freeMarkerConfigurer() {FreeMarkerConfigurer configurer = new FreeMarkerConfigurer();
        configurer.setTemplateLoaderPath("/freemarker");
        return configurer;
    }
}

动态资源配置

如果用户某次申请的数据是动态资源,那么这次申请不应该由 Controller 逻辑进行解决。Spring 提供了 ResourceHandlerRegistry 让用户配置动态资源匹配规定。

@Configuration
@EnableWebMvc
public class WebConfig implements WebMvcConfigurer {

    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {registry.addResourceHandler("/resources/**")
            .addResourceLocations("/public", "classpath:/static/")
            .setCacheControl(CacheControl.maxAge(Duration.ofDays(365)));
    }
}

当 DispatcherServlet 映射到 ”/” 门路后,咱们依然能够配置解决动态资源的默认 Servlet,动态资源的映射门路是 ”/**”,优先级比 ”/” 低。个别状况下动态资源的 Servlet 应该是最低的,启用动态资源的 servelt 的示例如下所示:

@Configuration
@EnableWebMvc
public class WebConfig implements WebMvcConfigurer {

    @Override
    public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {configurer.enable();
    }
}
@Configuration
@EnableWebMvc
public class WebConfig implements WebMvcConfigurer {

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

门路匹配规定

咱们都晓得在 Controller 上增加 @RequestMapping 办法之后,Spring 会把申请映射到对应的 Controller 办法上,那么咱们可不可以管制这个门路匹配过程呢?Spring 提供了 PathMatchConfigurer 让用户能够配置门路匹配规定:

@Configuration
@EnableWebMvc
public class WebConfig implements WebMvcConfigurer {

    @Override
    public void configurePathMatch(PathMatchConfigurer configurer) {
        configurer
            .setPatternParser(new PathPatternParser())
            .addPathPrefix("/api", HandlerTypePredicate.forAnnotation(RestController.class));
    }

    private PathPatternParser patternParser() {// ...}
}

高级配置

@EnableWebMvc 注解的原理就是向容器中注入类名为 DelegatingWebMvcConfiguration,该类会读取各个 WebMvcConfigurer 并对 MVC 进行配置。所以咱们也能够不应用 @EnableWebMvc,通过自定义 DelegatingWebMvcConfiguration 的模式对 MVC 进行更灵便的配置。

@Configuration
public class WebConfig extends DelegatingWebMvcConfiguration {// ...}

我是御狐神,欢送大家关注我的微信公众号:wzm2zsd

本文最先公布至微信公众号,版权所有,禁止转载!

退出移动版