美文网首页Spring MVC 之 简单配置
Spring Java 注解配置之 WebMvc配置

Spring Java 注解配置之 WebMvc配置

作者: 巧哥儿 | 来源:发表于2017-08-07 15:50 被阅读1016次

    Spring MVC配置(替代web.xml)

    Spring MVC配置主要由以下几个部分组成:

    1. Spring MVC启动器
    2. RootApplicationContext
    3. ServletApplicationContext

    Spring MVC启动器

    Spring MVC启动器主要是实现WebApplicationInitializer接口的实现类。该接口提供一个方法:onStartup(ServletContext servletContext)。当WEB服务容器启动时会扫描所有实现该接口的实现类,并调用onStartup方法。在实现类中可以通过ServletContext注册接口、Servlet等web.xml能实现的配置。

    public interface WebApplicationInitializer {
            void onStartup(ServletContext servletContext) throws ServletException;
    }
    

    在Spring Web包中提供了1个实现WebApplicationInitializer接口的抽象类,在Spring Webmvc包中提供了2个继承于AbstractContextLoaderInitializer的抽象类:

    1. AbstractContextLoaderInitializer
    2. AbstractDispatcherServletInitializer
    3. AbstractAnnotationConfigDispatcherServletInitializer

    AbstractContextLoaderInitializer

    该抽象类只是为了创建ContextLoaderListener,并通过抽象方法createRootApplicationContext创建的RootApplicationContext注入进Servlet容器事件里面去。

    AbstractDispatcherServletInitializer

    该抽象类继承于AbstractContextLoaderInitializer,默认注册了一个 通过ServletApplicationContext创建的DispatcherServlet。以及提供了配置Mappers的抽象方法、注册Filters的默认返回null的基本方法。

    AbstractAnnotationConfigDispatcherServletInitializer

    该抽象类继承于AbstractDispatcherServletInitializer,使用AnnotationConfigWebApplicationContext来创建RootApplicationContext与ServletApplicationContext。getRootConfigClasses和getServletConfigClasses两个抽象方法,通过两个抽象方法来注册java配置类。

    开始配置

    我的配置有以下配置类

    1. SpringStartupInitializer
    2. ServletRootConfig
    3. ServletWebConfig
    4. SpringCacheEhcacheConfig
    5. SpringDataSourceConfig
    6. SpringShiroSourceConfig

    SpringStartupInitializer

    SpringStartupInitializer是为了替代web.xml,它是一个实现了WebApplicationInitializer接口的类,由于我的配置主要是使用注解配置,因此SpringStartupInitializer是为了替代web只需基础于AbstractAnnotationConfigDispatcherServletInitializer

    public class SpringStartupInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
        @Override
        protected FrameworkServlet createDispatcherServlet(WebApplicationContext servletAppContext) {
            DispatcherServlet dispatcherServlet = new DispatcherServlet(servletAppContext);
            dispatcherServlet.setThrowExceptionIfNoHandlerFound(true);
    
            return dispatcherServlet;
        }
    
        @Override
        public void onStartup(ServletContext servletContext) throws ServletException {
            super.onStartup(servletContext);
    
            registerDruidStatViewServlet(servletContext);
        }
    
        @Override
        protected Filter[] getServletFilters() {
            return new Filter[] { //
                    new CharacterEncodingFilter("UTF-8"), // 编码转换
                    new DelegatingFilterProxy("springSessionRepositoryFilter"), // Spring Session
                    new DelegatingFilterProxy("shiroFilter") };
        }
    
        @Override
        protected Class<?>[] getRootConfigClasses() {
            return new Class<?>[] { ServletRootConfig.class };
        }
    
        @Override
        protected Class<?>[] getServletConfigClasses() {
            return new Class<?>[] { ServletWebConfig.class };
        }
    
        @Override
        protected String[] getServletMappings() {
            return new String[] { "/*" };
        }
    }
    

    ServletRootConfig

    该配置类主要是配置缓存、数据源、Shiro安全框架

    @Configuration
    @EnableCaching // 启用缓存注解
    @EnableScheduling // 启用注解配置定时器
    @Import(value = { SpringCacheEhcacheConfig.class, SpringDataSourceConfig.class, SpringShiroConfig.class })
    public class ServletRootConfig {
        /**
         * Session ID 管理
         * 
         * @return
         */
        @Bean
        public HttpSessionIdResolver httpSessionIdResolver() {
                   // Session ID 获取,主要作用是为了从请求中获取sessionID,这里使用的我自己实现的一个方式
                   // Spring 提供有三种获取方式:
                   // 1、CookieHttpSessionIdResolver  从Cookie中获取
                   // 2、HeaderHttpSessionIdResolver 从请求头中获取
                   // 3、ParamHttpSessionIdResolver 从请求参数中获取
    
            return new OrderHttpSessionIdResolver();
        }
    
        /** 加载配置文件 */
        @Bean("propertiesBean")
        public PropertiesFactoryBean propertiesFactoryBean() throws IOException {
            PropertiesFactoryBean factoryBean = new PropertiesFactoryBean();
            factoryBean.setLocations(ResourceUtil.getResources("classpath:config/*.properties"));
    
            return factoryBean;
        }
    
        /** 注入配置文件 */
        @Bean("propertyPlaceholderConfigurer")
        public static PropertyPlaceholderConfigurer propertyPlaceholderConfigurer(@Qualifier("propertiesBean") Properties properties) throws IOException {
            PropertyPlaceholderConfigurer configurer = new PropertyPlaceholderConfigurer();
            configurer.setProperties(properties);
    
            return configurer;
        }
    }
    

    ServletWebConfig

    ServletWebConfig是实现WebMvcConfigurer的配置类,主要是为了配置Spring WebMvc。在WebMvcConfigurer类中提供有一下空方法

    
        /** */
        @Override
        default void configurePathMatch(PathMatchConfigurer configurer) ;
    
        /** 配置内容协商器 */
        @Override
        default void configureContentNegotiation(ContentNegotiationConfigurer configurer) ;
    
        /** */
        @Override
        default void configureAsyncSupport(AsyncSupportConfigurer configurer) ;
    
        /** */
        @Override
        default void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) ;
    
        /** 添加格式转换器 */
        @Override
        default void addFormatters(FormatterRegistry registry);
    
        /** 添加过滤器 */
        @Override
        default void addInterceptors(InterceptorRegistry registry);
    
        /** 添加静态资源 */
        @Override
        default void addResourceHandlers(ResourceHandlerRegistry registry);
    
        /** 添加跨域配置 */
        @Override
        default void addCorsMappings(CorsRegistry registry);
    
        /** */
        @Override
        default void addViewControllers(ViewControllerRegistry registry);
    
        /** 配置视图转换器 */
        @Override
        default void configureViewResolvers(ViewResolverRegistry registry);
    
        /** */
        @Override
        default void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers);
    
        /** */
        @Override
        default void addReturnValueHandlers(List<HandlerMethodReturnValueHandler> returnValueHandlers);
    
        /** 配置消息转换器,会覆盖Spring默认的消息转换器 */
        @Override
        default void configureMessageConverters(List<HttpMessageConverter<?>> converters);
    
        /** 在Spring默认的消息转换器基础上,扩展自定义消息转换器 */
        @Override
        default void extendMessageConverters(List<HttpMessageConverter<?>> converters);
    
        /** 配置异常处理器 */
        @Override
        default void configureHandlerExceptionResolvers(List<HandlerExceptionResolver> exceptionResolvers);
    
        /** 扩展默认异常处理器 */
        @Override
        default void extendHandlerExceptionResolvers(List<HandlerExceptionResolver> exceptionResolvers);
    
        /**  */
        @Override
        default Validator getValidator();
    
        /** */
        @Override
        default MessageCodesResolver getMessageCodesResolver();
    
    

    在这里我的ServletWebConfig只实现了部分方法

    
    @Configuration
    @EnableWebMvc // 启用WebMVC
    @ComponentScan("cn.virens.web.controller") // 扫描controller所在的包
    @Import(value = { SpringBeetlConfig.class })// beetl 配置(源码:https://gitee.com/virens/multi_spring/blob/master/src/main/java/cn/virens/config/SpringBeetlConfig.java)
    public class ServletWebConfig implements WebMvcConfigurer {
        /**
         * 内容协商器配置。将后缀为json的配置为json处理,后缀为jspx的为页面处理
         */
        @Override
        public void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
            configurer.defaultContentType(MediaType.APPLICATION_JSON_UTF8);
    
            configurer.mediaType("jspx", MediaType.TEXT_HTML);
            configurer.mediaType("json", MediaType.APPLICATION_JSON_UTF8);
        }
    
        /**
         * 添加视图解析器
         */
        @Override
        public void configureViewResolvers(ViewResolverRegistry registry) {
            // 配置Beetl 视图
            BeetlSpringViewResolver beetlSpringViewResolver = new BeetlSpringViewResolver();
            beetlSpringViewResolver.setContentType("text/html;charset=UTF-8");
            beetlSpringViewResolver.setSuffix(".html");
            beetlSpringViewResolver.setOrder(2);
    
            // 配置FastJson 视图
            FastJsonJsonView fastJsonJsonView = new FastJsonJsonView();
            fastJsonJsonView.getFastJsonConfig().setCharset(Charset.forName("UTF-8"));
            fastJsonJsonView.getFastJsonConfig().setDateFormat(CalendarUtil.YMD_HMS); // 所有时间格式都为yyyy-MM-dd HH:mm:ss
    
            // 注册视图
            registry.viewResolver(beetlSpringViewResolver);
            registry.enableContentNegotiation(fastJsonJsonView);
        }
    
        /**
         * 添加消息转换器
         */
        @Override
        public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
            FastJsonHttpMessageConverter fastJsonHttpMessageConverter = new FastJsonHttpMessageConverter();
            fastJsonHttpMessageConverter.getFastJsonConfig().setCharset(Charset.forName("UTF-8"));
            fastJsonHttpMessageConverter.getFastJsonConfig().setDateFormat(CalendarUtil.YMD_HMS); // 所有时间格式都为yyyy-MM-dd HH:mm:ss
    
            // 将消息转换器转给Spring进行管理
            converters.add(new ByteArrayHttpMessageConverter());
            converters.add(new ResourceHttpMessageConverter());
            converters.add(new SourceHttpMessageConverter<>());
            converters.add(new StringHttpMessageConverter(Charset.forName("UTF-8")));
            converters.add(fastJsonHttpMessageConverter);
        }
    
        /**
         * 添加异常统一处理
         */
        @Override
        public void configureHandlerExceptionResolvers(List<HandlerExceptionResolver> exceptionResolvers) {
                    // 我自己实现的(源码:https://gitee.com/virens/multi_spring/blob/master/src/main/java/cn/virens/web/components/spring/VirExceptionResolver.java)
            VirExceptionResolver exceptionResolver = new VirExceptionResolver();
    
            exceptionResolver.addExceptionMessage(UnauthorizedException.class, "未授权");
            exceptionResolver.addExceptionMessage(UnauthenticatedException.class, "未登录");
            exceptionResolver.addExceptionMessage(NoHandlerFoundException.class, "接口不存在");
            exceptionResolver.addExceptionMessage(DataIntegrityViolationException.class, "请检查约束");
            exceptionResolver.addExceptionMessage(MaxUploadSizeExceededException.class, "文件超出大小限制");
    
            exceptionResolver.addExceptionMappings(UnauthorizedException.class, "/error/401");
            exceptionResolver.addExceptionMappings(UnauthenticatedException.class, "/error/401");
            exceptionResolver.addExceptionMappings(HostUnauthorizedException.class, "/error/401");
            exceptionResolver.addExceptionMappings(NoHandlerFoundException.class, "/error/404");
    
            exceptionResolver.setDefaultErrorView("/error/500");
            exceptionResolver.setDefaultStatusCode(500);
            exceptionResolver.setExceptionAttribute("ex");
            exceptionResolver.afterPropertiesSet();
    
            exceptionResolvers.add(exceptionResolver);
        }
    
        /**
         * 格式转换器
         */
        @Override
        public void addFormatters(FormatterRegistry registry) {
            registry.addConverter(new DateConverter());
        }
    
        /**
         * 添加静态资源路径
         */
        @Override
        public void addResourceHandlers(ResourceHandlerRegistry registry) {
            registry.addResourceHandler("/error/**").addResourceLocations("/error/");
            registry.addResourceHandler("/assets/**").addResourceLocations("/assets/");
            registry.addResourceHandler("/upload/**").addResourceLocations("/upload/");
            registry.addResourceHandler("/favicon.ico").addResourceLocations("/favicon.ico");
        }
    
        /**
         * 跨域配置
         */
        @Override
        public void addCorsMappings(CorsRegistry registry) {
            registry.addMapping("/api/**").allowedMethods("GET", "POST", "OPTIONS").allowedHeaders("X-Auth-Token", "Content-Type").exposedHeaders("X-Auth-Token").allowCredentials(true).maxAge(86400);
        }
    
        /** 文件上传配置 */
        @Bean
        public CommonsMultipartResolver multipartResolver() {
            CommonsMultipartResolver multipartResolver = new CommonsMultipartResolver();
            multipartResolver.setMaxUploadSize(10 * 1024 * 1024);
            multipartResolver.setDefaultEncoding("UTF-8");
    
            return multipartResolver;
        }
    
        /** 注入配置文件 */
        @Bean("propertyPlaceholderConfigurer")
        public static PropertyPlaceholderConfigurer propertyPlaceholderConfigurer(@Qualifier("propertiesBean") Properties properties) throws IOException {
            PropertyPlaceholderConfigurer configurer = new PropertyPlaceholderConfigurer();
            configurer.setProperties(properties);
    
            return configurer;
        }
    }
    

    相关文章

      网友评论

        本文标题:Spring Java 注解配置之 WebMvc配置

        本文链接:https://www.haomeiwen.com/subject/xezolxtx.html