SpringMVC自定义消息转换器的使用其实很简单

 更新时间:2024年07月08日 10:01:27   作者:kusedexingfu  
这篇文章主要介绍了SpringMVC自定义消息转换器的使用方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教

在我们的日常开发中,作为服务端,接收的数据是加密的字符串。我们可能会在Controller中获取到加密的字符串,然后手动解密,类似于如下做法(用base64做样例):

@PostMapping
public void base64Post(String base64Param) throws UnsupportedEncodingException {
    String jsonStr = new String(Base64.getDecoder().decode(base64Param), "UTF-8");
}

其实通过SpringMVC的消息转换器HttpMessageConverter可以统一的处理这种问题。

下面就来介绍下实现方式吧。

什么是消息转换器

在SpringMVC中,可以使用@RequestBody和@ResponseBody两个注解,分别完成请求报文到对象和对象到响应报文的转换,这种灵活的消息转换机制就是利用HttpMessageConverter来实现的,Spring内置了很多HttpMessageConverter,比如MappingJackson2HttpMessageConverter,StringHttpMessageConverter等,下面我们来自定义自己的消息转换器来满足上面的需求

自定义消息转换器

import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.http.HttpInputMessage;
import org.springframework.http.HttpOutputMessage;
import org.springframework.http.MediaType;
import org.springframework.http.converter.AbstractHttpMessageConverter;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.http.converter.HttpMessageNotWritableException;
import org.springframework.util.StreamUtils;

import java.io.IOException;
import java.nio.charset.Charset;
import java.util.Base64;

/**
 * 针对Object的base64消息处理器
 */
public class Base64ObjMessageConverter extends AbstractHttpMessageConverter<Object> {

    public Base64ObjMessageConverter() {
        // 新建一个我们自定义的媒体类型application/base64obj
        super(new MediaType("application", "base64obj", Charset.forName("UTF-8")));
    }


    @Override
    protected boolean supports(Class<?> clazz) {
        return true;
    }

    @Override
    protected Object readInternal(Class<? extends Object> clazz, HttpInputMessage inputMessage) throws IOException, HttpMessageNotReadableException {
        String source = new String(Base64.getDecoder().decode(StreamUtils.copyToString(inputMessage.getBody(), Charset.forName("UTF-8"))), "UTF-8");
        return new ObjectMapper().readValue(source, clazz);
    }

    @Override
    protected void writeInternal(Object obj, HttpOutputMessage outputMessage) throws IOException, HttpMessageNotWritableException {
        byte[] encode = Base64.getEncoder().encode(new ObjectMapper().writeValueAsString(obj).getBytes());
        outputMessage.getBody().write(encode);
    }
}

如上,我们继承了泛型类AbstractHttpMessageConverter,并重写了它的几个方法。

  • supports:设置处理哪些类。
  • readInternal:处理输入内容,即处理请求值。
  • writeInternal:处理输出内容,即处理返回值。

构造方法定义了要处理的MediaType,这里我定义的是application/base64obj;charset=utf-8,接下来在Controller中也要用到这个MediaType

上面我自定义的消息转换器处理的是Object类型,你也可以指定泛型为特定的类型,只处理该种类型的数据。

将自定义的消息转换器加入到springmvc容器中

这里采用配置类的形式

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

import java.util.List;

@Configuration
public class MessageConverterConfig implements WebMvcConfigurer {

    @Override
    public void extendMessageConverters(List<HttpMessageConverter<?>> converters) {
        converters.add(base64ObjMessageConverter());
    }

    @Bean
    public Base64ObjMessageConverter base64ObjMessageConverter() {
        return new Base64ObjMessageConverter();
    }
}

Controller代码

@PostMapping(value = "base64obj",  consumes = "application/base64obj;charset=utf-8",produces = "application/base64obj;charset=utf-8")
    public User base64obj(@RequestBody User user) {
        System.out.println(user);
        return user;
    }

我们可以通过设置consumes和produces来让springmvc采用不同的消息转换器处理我们的请求。

我们的测试代码设置的@PostMapping的属性consumers和produces都为我们的自定义的消息处理器要处理的类型application/base64obj;charset=utf-8

即请求和返回都需要经过自定义消息处理器Base64ObjMessageConverter的处理。

注意:

  • 我们可以将consumers和produces设置为不同的MediaType来让不同的消息转换器来处理,但是开发中一般不会这么做。
  • 比如输入的格式是XML,返回的格式确实JSON,这样做是很逆天的。
  • consumers和produces一般都会采用相同的MediaType。

PostMan请求测试

我们将json字符串 {"id":1,"name":"name","sex":"男"} 转为base64字符串:eyJpZCI6MSwibmFtZSI6Im5hbWUiLCJzZXgiOiLnlLcifQ==

用postma请求,设置Content-Type为我们自定义的application/base64obj;charset=utf-8

设置请求体,发送请求,结果能响应

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • Java长度不足左位补0的3种实现方法

    Java长度不足左位补0的3种实现方法

    这篇文章主要介绍了Java长度不足左位补0的3种实现方法小结,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-12-12
  • java集合——Java中的equals和hashCode方法详解

    java集合——Java中的equals和hashCode方法详解

    本篇文章详细介绍了Java中的equals和hashCode方法详解,Object 类是所有类的父类,非常具有实用价值,需要的朋友可以参考下。
    2016-10-10
  • java中创建写入文件的6种方式详解与源码实例

    java中创建写入文件的6种方式详解与源码实例

    这篇文章主要介绍了java中创建写入文件的6种方式详解与源码实例,Files.newBufferedWriter(Java 8),Files.write(Java 7 推荐),PrintWriter,File.createNewFile,FileOutputStream.write(byte[] b) 管道流,需要的朋友可以参考下
    2022-12-12
  • SpringBoot项目属性配置(application.properties、yml和yaml)

    SpringBoot项目属性配置(application.properties、yml和yaml)

    SpringBoot支持多种配置文件格式,包括application.properties、yml和yaml,application.properties是键值对结构,常用于简单配置,如设置服务器端口,yml和yaml文件格式相同,使用缩进表示层级,适合复杂配置,下面就来详细的介绍一下
    2025-08-08
  • IDEA中设置代码自动提示为Alt+/的具体做法

    IDEA中设置代码自动提示为Alt+/的具体做法

    很多公司都强制性要求使用Intellij IDEA,其实Intellij IDEA也确实很好用,但是一下子从Eclipse跳转到Intellij IDEA转也是需要一段时间的,为了迎合之前的习惯,就需要在Intellij IDEA中改变一些设置,如代码自动生成,本文给大家分享设置方法,感兴趣的朋友一起看看吧
    2023-01-01
  • JAVA进阶之Spring Boot自动配置示例详解

    JAVA进阶之Spring Boot自动配置示例详解

    Spring Boot自动配置是其核心特性之一,极大地简化了Spring应用的开发过程,这篇文章主要介绍了JAVA进阶之Spring Boot自动配置示例详解的相关资料,需要的朋友可以参考下
    2026-01-01
  • Java 并行数据处理和性能分析

    Java 并行数据处理和性能分析

    这篇文章主要介绍了Java 并行数据处理和性能分析,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-10-10
  • Java运算符从见过到掌握下

    Java运算符从见过到掌握下

    计算机的最基本用途之一就是执行数学运算,作为一门计算机语言,Java也提供了一套丰富的运算符来操纵变量,本篇对大家的学习或工作具有一定的价值,紧接上篇,需要的朋友可以参考下
    2021-09-09
  • Java使用钉钉创建企业内部机器人的实现

    Java使用钉钉创建企业内部机器人的实现

    钉钉的出现为企业节约了大量人力成本,其中也开放了大量的外部api接口方便企业使用。本文主要介绍了Java使用钉钉创建企业内部机器人的实现,感兴趣的可以了解一下
    2021-11-11
  • 分析Java中ArrayList与LinkedList列表结构的源码

    分析Java中ArrayList与LinkedList列表结构的源码

    这篇文章主要介绍了Java中ArrayList与LinkedList列表结构的源码,文章最后对LinkedList和ArrayList以及Vector的特性有一个对比总结,需要的朋友可以参考下
    2016-05-05

最新评论