9.springboot与web开发

1.定制SpringMvc的自动配置

  1. 通过覆盖Bean :

在大多数情况,SpringBoot在自动配置中标记了很多@ConditionalOnMissingBean(xxxxxxxxx.class); (意思就是如果容器中没有,当前的@bean才会生效)。 只需要在自己的配置类中配置对应的一个@Bean就可以覆盖默认自动配置。 还得结合源码的实际功能进行定制。 (经验之谈)

2.通过WebMvcConfigurer进行扩展

    1. 扩展视图控制器
    2. 扩展拦截器
    3. 扩展全局CORS
  • @Configuration
    public class MyWebMvcConfigurer implements WebMvcConfigurer {
        /**
         * 添加视图控制器
         * 立即访问
         * <mvc:view-controller path="/" view-name="index" />
         *
         * @param registry
         */
        @Override
        public void addViewControllers(ViewControllerRegistry registry) {
            registry.addViewController("/yang").setViewName("hello");
        }
    
        /**
         * 添加拦截器
         *
         * @param registry
         */
        @Override
        public void addInterceptors(InterceptorRegistry registry) {
            registry.addInterceptor(new TimeInterceptor())     //添加拦截器
                    .addPathPatterns("/**")    // 拦截映射规则
                    .excludePathPatterns("/pages/**");  // 设置排除的映射规则
    
            // 添加国际化拦截器
            registry.addInterceptor(new LocaleChangeInterceptor())
                    .addPathPatterns("/**");    // 拦截映射规则
        }
    
        /**
         * 全局CORS配置
         *
         * @param
         * @Override public void addCorsMappings(CorsRegistry registry) {
         * registry.addMapping("/user/*")   // 映射服务器中那些http接口运行跨域访问
         * .allowedOrigins("http://localhost:8081")     // 配置哪些来源有权限跨域
         * .allowedMethods("GET","POST","DELETE","PUT");   // 配置运行跨域访问的请求方法
         * }
         */
    
    
        @Bean
        public LocaleResolver localeResolver() {
            CookieLocaleResolver cookieLocaleResolver = new CookieLocaleResolver();
            // 可以设置过期时间
            cookieLocaleResolver.setCookieMaxAge(60 * 60 * 24 * 30);
            cookieLocaleResolver.setCookieName("locale");
            return cookieLocaleResolver;
        }
    }

2.WebMvcConfigurer 原理

实现WebMvcConfigurer接口可以扩展Mvc实现, 又既保留SpringBoot的自动配置

1.在WebMvcAutoConfiguration 也有一个实现了WebMvcConfigurer的配置类

2.WebMvcAutoConfigurationAdapter 它也是利用这种方式去进行扩展, 所以我们通过查看这个类我们发现它帮我们实现了其他不常用的方法,帮助我们进行自动配置,我们只需定制(拦截器、视图控制器、CORS 在开发中需要额外定制的定制的功能)

@Configuration(proxyBeanMethods = false)
@Import(EnableWebMvcConfiguration.class)
@EnableConfigurationProperties({ WebMvcProperties.class,
      org.springframework.boot.autoconfigure.web.ResourceProperties.class, WebProperties.class })
@Order(0)
public static class WebMvcAutoConfigurationAdapter implements WebMvcConfigurer, ServletContextAware {

2. 导入了EnableWebMvcConfiguration

@Import(EnableWebMvcConfiguration.class)

3.EnableWebMvcConfiguration它的父类上 setConfigurers 使用@Autowired

  • 它会去容器中将所有实现了WebMvcConfigurer 接口的Bean都自动注入进来, 添加到configurers 变量中

@Configuration(proxyBeanMethods = false)
@EnableConfigurationProperties(WebProperties.class)
public static class EnableWebMvcConfiguration extends DelegatingWebMvcConfiguration implements ResourceLoaderAware {
  • 添加到delegates委派器中

public void addWebMvcConfigurers(List<WebMvcConfigurer> configurers) {
   if (!CollectionUtils.isEmpty(configurers)) {
      this.delegates.addAll(configurers);
   }
}
  • 底层调用WebMvcConfigurer对应的方法时 就是去拿到之前注入到delegates的WebMvcConfigurer ,依次调用

@Override
public void addInterceptors(InterceptorRegistry registry) {
   for (WebMvcConfigurer delegate : this.delegates) {
      delegate.addInterceptors(registry);
   }
}
  • 当添加了@EnableWebMvc就不会使用SpringMVC自动配置类的默认配置就失效了
    • 为什么呢?原理:
      • 在@EnableWebMvc 中@Import(DelegatingWebMvcConfiguration.class)

3.Json开发

Spring Boot提供了与三个JSON映射库的集成:

jsckson的使用

  • @JsonIgnore
    • 进行排除json序列化,将它标注在属性上将不会进行json序列化
  • @JsonFormat(pattern = "yyyy-MM-dd hh:mm:ss",locale = "zh")
    • 进行日期格式化
  • @JsonInclude(JsonInclude.Include.NON_NULL)
    • 当属性值为null时则不进行json序列化
  • @JsonProperty("uname")
    • 来设置别名

SpringBoot 还提供了@JsonComponent 来根据自己的业务需求进行json的序列化和反序列化

@JsonComponent
public class UserJsonCustom {
    public static class Serializer extends JsonObjectSerializer<User> {

        @Override
        protected void serializeObject(User user, JsonGenerator jgen, SerializerProvider provider) throws IOException {
            jgen.writeObjectField("id", user.getId());   //{"id","xxx"}
            jgen.writeObjectField("uname", "xxxxx");
            /*jgen.writeFieldName("");  单独写key
            jgen.writeObject();   单独写value
            */
            // 1. 一次查不出完整的数据返回给客户端, 需要根据需求去做一些个性化调整
            // 2. 根据不同的权限给他返回不同的序列化数据
        }
    }

    public static class Deserializer extends JsonObjectDeserializer<User> {

        @Override
        protected User deserializeObject(JsonParser jsonParser, DeserializationContext context, ObjectCodec codec, JsonNode tree) throws IOException {
            User user = new User();
            user.setId(tree.findValue("id").asInt());

            return user;
        }
    }
}


版权声明:本文为yfyh2021原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。