当前位置: 首页 > news >正文

北京营销网站建设公司郑州pc网站建设

北京营销网站建设公司,郑州pc网站建设,杨凌网站建设哪家好,哈尔滨大型网站建设目录 前言 一. 自定义序列化器失效 1.1 EnableWebMvc 的作用 1.2 EnableWebMvc 带来了什么后果 1.3 原理分析 1.4 问题解决 二. 总结 前言 在使用Swagger的时候用 到了EnableWebMvc#xff0c;发现之前为了解决Long类型、日期类型等自定义序列化器失效了 Configurati…目录 前言 一. 自定义序列化器失效 1.1 EnableWebMvc 的作用 1.2 EnableWebMvc 带来了什么后果 1.3 原理分析 1.4 问题解决 二. 总结 前言 在使用Swagger的时候用 到了EnableWebMvc发现之前为了解决Long类型、日期类型等自定义序列化器失效了 Configuration EnableOpenApi EnableWebMvc public class SwaggerConfig {Beanpublic Docket api() {return new Docket(DocumentationType.OAS_30).select().apis(RequestHandlerSelectors.withClassAnnotation(RestController.class)).paths(PathSelectors.any()).build();} } Swagger3/2Spring boot 使用小结_spring boot3 swagger3-CSDN博客 我们有时候可能需要自定义一个序列化器来满足自己的需要但是如果项目中不正确使用了EnableWebMvc注解可能会导致这个自定义的序列化器失效。 一. 自定义序列化器失效 首先我们应该看下EnableWebMvc这个注解是拿来干啥的吧。 1.1 EnableWebMvc 的作用 EnableWebMvc用于快捷配置SpringWebMVC。用于自定义MVC的相关配置用的。相当于xml配置 mvc:annotation-driven/ 当我们需要自定义实现MVC的时候有三种选择 实现WebMvcConfigurer接口继承WebMvcConfigurerAdapter类继承WebMvcConfigurationSupport类 我们这里通过一个案例来更直观的看这个注解。本文通过第一种方式来实现。 1.我们自定义一个拦截器MyInterceptor public class MyInterceptor implements HandlerInterceptor {// 目标方法运行之前执行Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {System.out.println(preHandle: request.getRequestURI());return true;}} 2.自定义MVC配置添加我们刚刚定义好的拦截器。 EnableWebMvcConfigurationpublic class MyWebMvcConfig implements WebMvcConfigurer {public void addInterceptors(InterceptorRegistry registry) {registry.addInterceptor(new MyInterceptor());}} 3.定义Controller  RestControllerpublic class MyController {PostMapping(/hello)public User hello(RequestBody User user){return user;}} 4.访问对应的路径就能在控制台上看到信息  还可以配置其他的一些功能例如视图解析器、静态资源映射等等。  1.2 EnableWebMvc 带来了什么后果 假设我们这个项目使用了fastjson来作为默认的转换器 Beanpublic HttpMessageConverters fastJsonHttpMessageConverters() {FastJsonHttpMessageConverter fastConverter new FastJsonHttpMessageConverter();FastJsonConfig fastJsonConfig new FastJsonConfig();fastJsonConfig.setSerializerFeatures(SerializerFeature.PrettyFormat);fastConverter.setFastJsonConfig(fastJsonConfig);HttpMessageConverter? converter fastConverter;return new HttpMessageConverters(converter);} 然后我们访问下案例的接口结果 我们知道fastjson默认情况下是不会输出null这个结果的会被过滤掉并且我们自定义序列化器的时候也没有去指定SerializerFeature.WriteMapNullValue属性。那么问题来了底层进行解析的时候到底用的是什么转换器难道不是我们自定义的fastjson吗 在Spring常见问题解决 - Body返回体中对应值为null的不输出这篇文章的基础上我们直接定位到转换器的代码部分看下返回结果最终用的是什么序列化器 总结下就是自定义序列化器失效了。 当然咱们这里为止我是基于我知道底层原理的情况下指明了这个问题是由于EnableWebMvc的使用引起的。那么接下来就开始分析。 1.3 原理分析 首先说下本质原因EnableWebMvc 导致SpringBoot中 WebMvc的自动配置失效。 再从代码角度来看我们先看下EnableWebMvc 注解 Retention(RetentionPolicy.RUNTIME)Target(ElementType.TYPE)DocumentedImport(DelegatingWebMvcConfiguration.class)public interface EnableWebMvc {} 这里引入了DelegatingWebMvcConfiguration类。而他属于WebMvcConfigurationSupport的子类 Configuration(proxyBeanMethods false) public class DelegatingWebMvcConfiguration extends WebMvcConfigurationSupport 另一方面SpringBoot实际上是整合了MVC的功能的主要通过自动装配机制来完成功能的加载入口在于WebMvcAutoConfiguration类中。 ConditionalOnMissingBean(WebMvcConfigurationSupport.class) public class WebMvcAutoConfiguration {} 可以发现自动装配里面引入了WebMvcConfigurationSupport这个类。只不过是通过ConditionalOnMissingBean注解来注入的。注意了这个注解的用处在于 当这个类型的Bean被注册之后就不会再注册。它会保证你的Bean只有一个。也就是说WebMvcConfigurationSupport类型的包括它的子类Bean只能有一个。即如果我们使用了EnableWebMvc 注解就会和SpringBoot对于MVC的自动装配产生冲突因为其注入了DelegatingWebMvcConfiguration类属于WebMvcConfigurationSupport类的子类。如果存在EnableWebMvc 注解优先以我们自定义的MVC配置为主。 那么问题来了我们从上一篇文章Spring常见问题解决 - Body返回体中对应值为null的不输出中得到一个点就是Spring是通过ObjectMapper对象进行请求和返回体的转换的。 那么EnableWebMvc和他有啥子关系呢我们再回到EnableWebMvc本身。我们根据上文得知它会引入一个WebMvcConfigurationSupport的子类。我们看下这个父类中的代码 ConditionalOnMissingBean(WebMvcConfigurationSupport.class)public class WebMvcAutoConfiguration {Configuration(proxyBeanMethods false)Import(EnableWebMvcConfiguration.class)EnableConfigurationProperties({ WebMvcProperties.class, ResourceProperties.class })Order(0)public static class WebMvcAutoConfigurationAdapter implements WebMvcConfigurer {}} 可以发现有个静态内部类WebMvcAutoConfigurationAdapter。它通过Import注解引入了EnableWebMvcConfiguration Configuration(proxyBeanMethods false)public static class EnableWebMvcConfiguration extends DelegatingWebMvcConfiguration implements ResourceLoaderAware {BeanOverridepublic RequestMappingHandlerAdapter requestMappingHandlerAdapter(Qualifier(mvcContentNegotiationManager) ContentNegotiationManager contentNegotiationManager,Qualifier(mvcConversionService) FormattingConversionService conversionService,Qualifier(mvcValidator) Validator validator) {RequestMappingHandlerAdapter adapter super.requestMappingHandlerAdapter(contentNegotiationManager,conversionService, validator);adapter.setIgnoreDefaultModelOnRedirect(this.mvcProperties null || this.mvcProperties.isIgnoreDefaultModelOnRedirect());return adapter;}} 这个又引入了RequestMappingHandlerAdapter类我们关注requestMappingHandlerAdapter()函数 RequestMappingHandlerAdapter adapter super.requestMappingHandlerAdapter(contentNegotiationManager,conversionService, validator);public class WebMvcConfigurationSupport implements ApplicationContextAware, ServletContextAware {Beanpublic RequestMappingHandlerAdapter requestMappingHandlerAdapter(Qualifier(mvcContentNegotiationManager) ContentNegotiationManager contentNegotiationManager,Qualifier(mvcConversionService) FormattingConversionService conversionService,Qualifier(mvcValidator) Validator validator) {RequestMappingHandlerAdapter adapter createRequestMappingHandlerAdapter();// 设置HttpMessageConverteradapter.setMessageConverters(getMessageConverters());// ..return adapter;}↓↓↓protected final ListHttpMessageConverter? getMessageConverters() {if (this.messageConverters null) {// ...addDefaultHttpMessageConverters(this.messageConverters);}return this.messageConverters;}↓↓↓// 添加默认的消息转换器protected final void addDefaultHttpMessageConverters(ListHttpMessageConverter? messageConverters) {messageConverters.add(new ByteArrayHttpMessageConverter());messageConverters.add(new StringHttpMessageConverter());messageConverters.add(new ResourceHttpMessageConverter());messageConverters.add(new ResourceRegionHttpMessageConverter());try {messageConverters.add(new SourceHttpMessageConverter());}catch (Throwable ex) {// Ignore when no TransformerFactory implementation is available...}messageConverters.add(new AllEncompassingFormHttpMessageConverter());if (romePresent) {messageConverters.add(new AtomFeedHttpMessageConverter());messageConverters.add(new RssChannelHttpMessageConverter());}if (jackson2XmlPresent) {Jackson2ObjectMapperBuilder builder Jackson2ObjectMapperBuilder.xml();if (this.applicationContext ! null) {builder.applicationContext(this.applicationContext);}messageConverters.add(new MappingJackson2XmlHttpMessageConverter(builder.build()));}else if (jaxb2Present) {messageConverters.add(new Jaxb2RootElementHttpMessageConverter());}// 这里还能发现jackson优先级高于gson。if (jackson2Present) {Jackson2ObjectMapperBuilder builder Jackson2ObjectMapperBuilder.json();if (this.applicationContext ! null) {builder.applicationContext(this.applicationContext);}messageConverters.add(new MappingJackson2HttpMessageConverter(builder.build()));}else if (gsonPresent) {messageConverters.add(new GsonHttpMessageConverter());}else if (jsonbPresent) {messageConverters.add(new JsonbHttpMessageConverter());}if (jackson2SmilePresent) {Jackson2ObjectMapperBuilder builder Jackson2ObjectMapperBuilder.smile();if (this.applicationContext ! null) {builder.applicationContext(this.applicationContext);}messageConverters.add(new MappingJackson2SmileHttpMessageConverter(builder.build()));}if (jackson2CborPresent) {Jackson2ObjectMapperBuilder builder Jackson2ObjectMapperBuilder.cbor();if (this.applicationContext ! null) {builder.applicationContext(this.applicationContext);}messageConverters.add(new MappingJackson2CborHttpMessageConverter(builder.build()));}}} 总而言之就是默认的解析器里面不包含我们自定义的fastjson。因此在进行HTTP请求的时候对结果进行反序列化输出的时候使用的序列化器是jackson。 1.4 问题解决 解决方式很简单我们只需要将EnableWebMvc注解去掉即可。去掉后重启下项目我们看下结果 可以发现确实反序列化的时候使用的是fastjson而不是jackson了 再看下我们自定义的拦截器是否生效了 二. 总结 项目中如果我们希望自定义一些MVC的功能我们只需要实现WebMvcConfigurer接口即可。无需添加EnableWebMvc注解。添加EnableWebMvc注解会导致SpringBoot对MVC的自动装配失效。因为Spring对于WebMvcConfigurationSupport类型的Bean只允许存在一个包括其子类。此时以序列化器为例使用EnableWebMvc注解会导致自定义的序列化器失效。例如本文案例的fastjson。而Spring源码中对于默认注入的序列化器类型中并不包含fastjson。Spring官网就已经说了针对于SpringBoot而言项目已经对MVC进行自动装配了因此在自定义MVC功能的时候不要使用EnableWebMvc注解。加一个Configuration即可。
http://www.pierceye.com/news/629885/

相关文章:

  • 小米网站建设外贸网站建设哪家公司好
  • 怎样推广产品专业黑帽seo推广
  • 网站调用字体在阿里云备案网站通过
  • 手机网站做落地页石家庄网络营销
  • 如何把网站主关键词做到百度首页网站页面设计优化方案
  • 做门户网站多少钱做视频解析网站播放器和接口
  • 打开一个网站网站被挂马无法访问
  • 大连网站建设公司排名装饰设计公司哪个好
  • 苏州企业建设网站公司400电话网站源码
  • 贵州住房和城乡建设厅官网泰安千橙网站建设优化熊掌号
  • metro网站模板平面设计师网站
  • 怎样通过阿里云建设网站国内免费crm
  • 网站开发都需要学什么iis7网站建设
  • 网站 关键字it网站建设资讯网
  • 白银网站建设公司石家庄建行网站
  • 做网站全部乱码怎么办教学资源网站建设方案
  • 自己做的网站怎么添加文档做淘宝详情的网站
  • 安全认证的机票网站成就怎么做山东省住房和城乡建设厅政务服务
  • 海口网站建设方案咨询信息流优化师面试常见问题
  • 网上课程网站wordpress自定义页面分页
  • 自建站成本深圳网站建设营销服务平台
  • 模仿网站怎么做网站编辑建设
  • 湖南做网站 磐石网络引领免费网上开店
  • wordpress内容做成目录seo排名分析
  • 大型网站 网站建设做网站赔了8万
  • python官方网站建设网站要什么
  • 青海 网站开发 图灵如何创建自己的网页
  • 建设银行网站怎么登陆不做网站首页的尺寸
  • 谁能给我一个网站谢谢dedecms收费怎么办
  • dede 网站地图 模块青岛做网站服务商