文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

基于SpringBoot自定义接口响应消息格式及原理解析

2024-11-30 13:33

关注

消息格式转换原理

在默认情况下,RestController接口返回的数据格式是json,如下接口:

@RestController
@RequestMapping("/rmf")
public class ResponseMessageFormatController {


  @GetMapping("/index")
  public Users index() {
    return new Users(1, "张飒", 66, "男") ;
  }
  
}

接口返回

接口默认返回了json数据格式

通过Postman,我这里是没有在Header中添加Accept。当后台在处理该请求时会认为你能接收任意类型的数据格式也就是MediaType=** 接受任意类型 acceptableTypes = getAcceptableMediaTypes(request); } // 获取当前容器中所有的HttpMessageConverter支持的MediaType List producibleTypes = getProducibleMediaTypes(request, valueType, targetType); List compatibleMediaTypes = new ArrayList<>(); // 确定具体输出的应该是那种消息格式, determineCompatibleMediaTypes(acceptableTypes, producibleTypes, compatibleMediaTypes); // 遍历 for (MediaType mediaType : compatibleMediaTypes) { // 判断当前的MediaType的类型[type] 和 子类型 [subtype] 中分别不是 * 和 *+ // 就符合条件,找到第一个直接返回,这就确定了将会给客户端返回的消息格式 if (mediaType.isConcrete()) { selectedMediaType = mediaType; break; } else if (mediaType.isPresentIn(ALL_APPLICATION_MEDIA_TYPES)) { selectedMediaType = MediaType.APPLICATION_OCTET_STREAM; break; } } if (selectedMediaType != null) { selectedMediaType = selectedMediaType.removeQualityValue(); // 遍历所有的HttpMessageConverter,是否有能支持上面确定的selectedMediaType for (HttpMessageConverter converter : this.messageConverters) { GenericHttpMessageConverter genericConverter =(converter instanceof GenericHttpMessageConverter ghmc ? ghmc : null); if (genericConverter != null ? ((GenericHttpMessageConverter) converter).canWrite(targetType, valueType, selectedMediaType) : converter.canWrite(valueType, selectedMediaType)) { body = getAdvice().beforeBodyWrite(body, returnType, selectedMediaType, (Class>) converter.getClass(), inputMessage, outputMessage); // 输出结果 ((HttpMessageConverter) converter).write(body, selectedMediaType, outputMessage); } } } } }

以上是关于消息处理的部分源码分析。

返回XML格式

如果需要返回xml格式的数据,我们只需引入下面依赖即可。

引入依赖:


  com.fasterxml.jackson.dataformat
  jackson-dataformat-xml

postman进行测试

正确的返回了xml格式

为什么引入上面的依赖后就可以直接通过设置Accept为application/xml就可以返回xml格式呢?

原理:

// 在这导入的JacksonHttpMessageConvertersConfiguration类中进行了配置
@Import({ JacksonHttpMessageConvertersConfiguration.class })
public class HttpMessageConvertersAutoConfiguration {
}


@Configuration(proxyBeanMethods = false)
class JacksonHttpMessageConvertersConfiguration {
  @Configuration(proxyBeanMethods = false)
  // 当前的类路径下有XmlMapper类,该类就在上面引入的包中
  @ConditionalOnClass(XmlMapper.class)
  @ConditionalOnBean(Jackson2ObjectMapperBuilder.class)
  protected static class MappingJackson2XmlHttpMessageConverterConfiguration {
    @Bean
    @ConditionalOnMissingBean
    public MappingJackson2XmlHttpMessageConverter mappingJackson2XmlHttpMessageConverter(Jackson2ObjectMapperBuilder builder) {
      return new MappingJackson2XmlHttpMessageConverter(builder.createXmlMapper(true).build());
    }
  }  
}

当当前的类路径下有XmlMapper就会自动的创建处理XML格式的MappingJackson2XmlHttpMessageConverter

自定义消息格式

如果客户端要求接收的数据格式是yaml格式,这时候就需要自定义HttpMessageConverter

引入依赖:


  com.fasterxml.jackson.dataformat
  jackson-dataformat-yaml

自定义HttpMessageConverter:

@Component
public class YamlHttpMessageConverter extends AbstractHttpMessageConverter {


  public YamlHttpMessageConverter() {
    super(new MediaType("application", "yaml")) ;
  }
  
  @Override
  protected boolean supports(Class clazz) {
    return true ;
  }


  @Override
  protected Object readInternal(Class clazz, HttpInputMessage inputMessage)
      throws IOException, HttpMessageNotReadableException {
    return null ;
  }


  @Override
  protected void writeInternal(Object t, HttpOutputMessage outputMessage)
      throws IOException, HttpMessageNotWritableException {
    try (OutputStream os = outputMessage.getBody()) {
      YAMLFactory factory = new YAMLFactory();
      // 该配置作用就是:去掉开头的三个 '---'
      factory.configure(Feature.WRITE_DOC_START_MARKER, false) ;
      ObjectMapper mapper = new ObjectMapper(factory) ;
      os.write(mapper.writeValueAsString(t).getBytes(StandardCharsets.UTF_8)) ;
    }
  }


}

测试

正确的返回了yaml格式

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 资料下载
  • 历年真题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容
咦!没有更多了?去看看其它编程学习网 内容吧