首页 > 其他分享 >自定义消息转换器对请求报文的统一解密处理

自定义消息转换器对请求报文的统一解密处理

时间:2023-12-23 14:44:08浏览次数:32  
标签:org 自定义 报文 springframework import 转换器 com public objectMapper

1.自定义拦截器Interceptor

package com.example.springbootdemo.config;

import lombok.extern.slf4j.Slf4j;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@Slf4j
public class CustomInterceptor implements HandlerInterceptor {

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
            throws Exception {
        return true;
    }

}

2.自定义sm4的加解密工具

package com.example.springbootdemo.util;

import cn.hutool.crypto.SmUtil;
import cn.hutool.crypto.symmetric.SM4;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSONObject;
import com.example.springbootdemo.config.CommonLocalDateTimeSerializer;
import com.example.springbootdemo.requet.CommonRequest;
import com.example.springbootdemo.requet.LoginReq;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;

import java.time.LocalDateTime;

public class SM4Util {

    private static final String key = "w5mqd1mv318stg2w";

    public String getEncryptBase64(String jsonStr){
        SM4 sm41 = SmUtil.sm4(key.getBytes());
        String encryptHex = sm41.encryptHex(jsonStr);
        return encryptHex;
    }

    public String getDecryptStr(String EncryptBase64){
        SM4 sm41 = SmUtil.sm4(key.getBytes());
        String sourceDate = sm41.decryptStr(EncryptBase64);
        return sourceDate;
    }


    public static void main(String[] args) throws JsonProcessingException {
        ObjectMapper objectMapper = new ObjectMapper();
        //objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);

        LoginReq loginReq = new LoginReq();
        loginReq.setUserName("zhangsan");
        loginReq.setPassword("password123");

        String s = objectMapper.writeValueAsString(loginReq);
        System.out.println(s);
        System.out.println(JSONUtil.toBean(s, LoginReq.class));
        String jsonStr = JSONUtil.toJsonStr(loginReq);
        String jsonString = JSONObject.toJSONString(loginReq);
        System.out.println(objectMapper.convertValue(jsonString, LoginReq.class));
        System.out.println(s);

    }

}

3.自定义JSON序列化配置

package com.example.springbootdemo.config;

import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;

import java.io.IOException;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;

public class CommonLocalDateTimeSerializer extends JsonSerializer<LocalDateTime> {

    public static final String FULL_YMD_HMS_PATTERN = "yyyy-MM-dd HH:mm:ss";

    public static final String ZONE_ID = "Asia/Shanghai";

    @Override
    public void serialize(LocalDateTime dateTime, JsonGenerator gen, SerializerProvider serializers) throws IOException {
        DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern(FULL_YMD_HMS_PATTERN).withZone(ZoneId.of(ZONE_ID));
        String format = dateTime.format(dateTimeFormatter);
        // dateTimeFormatter.format(dateTime);
        gen.writeString(format);
    }
}
    @Bean
    public ObjectMapper objectMapper(){
        ObjectMapper objectMapper = new ObjectMapper();
        objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);

        // 自定义LocalDateTime类型数据的json序列化方式
        JavaTimeModule javaTimeModule = new JavaTimeModule();
        javaTimeModule.addSerializer(LocalDateTime.class, new CommonLocalDateTimeSerializer());

        return objectMapper;
    }

4.自定义消息转换器

package com.example.springbootdemo.config;

import cn.hutool.json.JSONUtil;
import com.example.springbootdemo.requet.CommonRequest;
import com.example.springbootdemo.util.SM4Util;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.IOUtils;
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.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;

@Slf4j
public class CustomHttpMessageConverter extends AbstractHttpMessageConverter {

    private ObjectMapper objectMapper;

    private SM4Util sm4Util;

    private ThreadLocal<CommonRequest> threadLocal = new ThreadLocal<>();

    public CustomHttpMessageConverter(ObjectMapper objectMapper, SM4Util sm4Util) {
        this.objectMapper = objectMapper;
        this.sm4Util = sm4Util;
    }

    @Override
    protected boolean supports(Class clazz) {
        return false;
    }

    /**
     *是否使用readInternal方法处理请求报文
     * @return
     */
    @Override
    public boolean canRead(Class clazz, MediaType mediaType) {
        return true;
    }

    @Override
    protected Object readInternal(Class clazz, HttpInputMessage inputMessage) throws IOException, HttpMessageNotReadableException {
        InputStream body = inputMessage.getBody();
        String reqBody = IOUtils.toString(body, StandardCharsets.US_ASCII);
        log.info("通用请求CommonRequest密文:{}", reqBody);
        CommonRequest request = this.objectMapper.reader().forType(CommonRequest.class).readValue(reqBody);
        String decryptStr = sm4Util.getDecryptStr(request.getReqJsonData());
        log.info("通用请求CommonRequest解密报文:{}", decryptStr);

        request.setReqJsonData(decryptStr);
        threadLocal.set(request);

        return this.objectMapper.reader().forType(clazz).readValue(decryptStr);
    }

    /**
     *是否使用writeInternal方法处理响应报文
     * @return
     */
    @Override
    protected boolean canWrite(MediaType mediaType) {
        // 对某些请求使用或者不使用消息转换器
        RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = ((ServletRequestAttributes) requestAttributes).getRequest();
        request.getHeader("key1");
        request.getRequestURI();
        return false;
    }

    @Override
    protected void writeInternal(Object o, HttpOutputMessage outputMessage) throws IOException, HttpMessageNotWritableException {

    }

}

5.定义WebMvcConfigurer

package com.example.springbootdemo.config;

import com.example.springbootdemo.util.SM4Util;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

import java.time.LocalDateTime;
import java.util.Collections;
import java.util.List;

@Configuration
@Slf4j
@ConditionalOnProperty(prefix = "webMvc", value = { "enable" }, havingValue = "true")
public class WebConfig implements WebMvcConfigurer {

    public CustomInterceptor customInterceptor(){
        return new CustomInterceptor();
    }

    @Bean
    public ObjectMapper objectMapper(){
        ObjectMapper objectMapper = new ObjectMapper();
        objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);

        // 自定义LocalDateTime类型数据的json序列化方式
        JavaTimeModule javaTimeModule = new JavaTimeModule();
        javaTimeModule.addSerializer(LocalDateTime.class, new CommonLocalDateTimeSerializer());

        return objectMapper;
    }

    @Bean
    public SM4Util sm4Util(){
        return new SM4Util();
    }

    @Override
    public void extendMessageConverters(List<HttpMessageConverter<?>> converters){
        CustomHttpMessageConverter converter = new CustomHttpMessageConverter(objectMapper(), sm4Util());
        converter.setSupportedMediaTypes(Collections.singletonList(MediaType.ALL));
        converters.add(0, converter);
    }

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(customInterceptor()).addPathPatterns("/**");

    }


}

测试验证:

 

 

标签:org,自定义,报文,springframework,import,转换器,com,public,objectMapper
From: https://www.cnblogs.com/wang-liang-blogs/p/17923106.html

相关文章

  • 【内网渗透】隐藏cobaltstrike服务器—自定义证书+C2侧写
    简介自定义证书查看Cobaltstrike默认证书发现特征含有cobaltstrike关键字常用keytool命令查看证书文件:keytool-list-v-keystorexx.store修改证书密码:keytool-storepasswd-keystoretest.store修改alias别名:keytool-changealias-keystoretest.store-aliasso......
  • 单值转换器
    https://www.cnblogs.com/tianma3798/p/5927470.html 1.当值从绑定源(属性)传播给绑定目标(例XAML中的TextBox的Text)时,调用方法Convert2.当值从绑定目标传播给绑定源时,调用此方法ConvertBack,方法ConvertBack的实现必须是方法Convert的反向实现。以下例子为HTuple属性与XAML中的T......
  • spring项目中自定义注解
    使用BeanPostProcessorBeanPostProcessor是Spring框架提供的一个接口,用于在Spring容器中对Bean进行后处理。自定义注解后,可以实现一个BeanPostProcessor实现类,在BeanPostProcessor的postProcessAfterInitialization()方法中,使用ClassPathScanningCandidateResol......
  • Camstar弹出自定义VP
    写在公共类里:  主页面代码如下: 按钮里写代码,或者某方法里写主页面的传递参数定义:  弹出页面如下:   弹出页面代码如下: ......
  • el-select自定义指令用于触底加载分页请求options数据(附上完整代码和接口可直接用)
    问题描述某些情况下,下拉框需要做触底加载,发请求,获取option的数据为了方便复用,笔者封装了一个自定义指令另外也提供了一个简单的接口,用于演示我们先看看效果图效果图思路分析注意事项一el-select要不嵌入到body中为何,不嵌入到body标签中呢?答曰,更加方便自定义指令管理......
  • Unity3D 自定义Shader 与 内置Shader 如何整合详解
    Unity3D是一款非常流行的游戏开发引擎,它提供了丰富的内置Shader供开发者使用。然而,有时候我们需要根据具体需求自定义Shader来实现特定的效果。本文将详细介绍Unity3D中如何整合自定义Shader和内置Shader,并给出相关的技术详解和代码实现。对啦!这里有个游戏开发交流小组里面聚集了......
  • 如何实现自定义表情?
    1、继承实现协议RCEmoticonTabSource2、在实现的代理方法loadEmoticonView返回View,(返回的以下图中红框区域,里面的视图及逻辑需要自己来添加实现)3、在会话页面viewdidLoad里添加表情包示例代码(Demo源码2中的类RCDCustomerEmoticonTab):RCDCustomerEmoticonTab.h@inter......
  • 自定义中间表(中介模型)
    1多对多关系中,第三张表的建立 -默认使用ManyToMany,自动创建-使用中介模型 -即手动创建第三张表,又要使用好用的查询-完全自己写第三张表#使用中介模型classAuthor(models.Model):nid=models.AutoField(primary_key=True)name=models.CharField(max_length=......
  • WPF自定义控件之图形解锁控件 ScreenUnLock
    ScreenUnLock与智能手机上的图案解锁功能一样。通过绘制图形达到解锁或记忆图形的目的。本人突发奇想,把手机上的图形解锁功能移植到WPF中。也应用到了公司的项目中。在创建ScreenUnLock之前,先来分析一下图形解锁的实现思路。1.创建九宫格原点(或更多格子),每个点定义一个坐标值......
  • 基于vue3和elementplus实现的自定义table组件
    基于vue3和elementplus实现的自定义table组件,集成查询工具栏分页,可通过配置直接实现基础的列表页基于vue3和elementplus实现的自定义table组件,集成查询工具栏分页,可通过配置直接实现基础的列表页目录结构如下:类型声明:declaretypeDictType={value:string|boolean|n......