在日常开发中,有时候我们经常需要和第三方接口打交道,有时候是我们调用别人的第三方接口,有时候是别人在调用我们的第三方接口,那么为了调用接口的安全性,一般都会对传输的数据进行加密操作,如果每个接口都由我们自己去手动加密和解密,那么工作量太大而且代码冗余。那么有没有简单的方法,借助 spring 提供的  RequestBodyAdviceResponseBodyAdvice 可以实现解密和加密操作。

需求:

1,后台方法上如果有@Encrypt注解和@RequestBody修饰的方法,需要进行参数的解密

2,后台方法上如果有@Encrypt注解和@ResponseBody修饰的方法,需要进行参数的加密

     3,加密和解密规则

           加密:对返回的值中增加-encrypt值

           解密:对传入的值中删除-encrypt值

注:

          1,@Encrypt 为自定义的一个注解。

          2,此处为了简单,就使用删除或增加-encrypt这个,实际情况下可以使用复杂的加解密规则

前置知识:

RequestBodyAdvice:在 sping 4.2 新加入的一个接口,它可以使用在 @RequestBodyHttpEntity 修改的参数之前进行参数的处理,比如进行参数的解密

ResponseBodyAdvice:在 spring 4.1 新加入的一个接口,在消息体被HttpMessageConverter写入之前允许Controller 中 @ResponseBody修饰的方法或ResponseEntity调整响应中的内容,比如进行相应的加密。

功能实现:

1,编写加密注解类(Encrypt)

/**
* 进行参数加密和解密
*
* @author huan.fu
* @date 2018/9/28 - 16:08
*/
@Target({ElementType.PARAMETER, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Encrypt {
}

 2,编写RequestBodyAdvice接口实现类,实现数据的解密操作

/**
* 解密数据
*
* @author huan.fu
* @date 2018/9/28 - 16:09
*/
@Slf4j
@RestControllerAdvice
public class ParamEncryptRequestBodyAdvice implements RequestBodyAdvice { @Override
public boolean supports(MethodParameter methodParameter, Type type, Class<? extends HttpMessageConverter<?>> aClass) {
return methodParameter.hasParameterAnnotation(RequestBody.class);
} @Override
public Object handleEmptyBody(Object o, HttpInputMessage httpInputMessage, MethodParameter methodParameter, Type type, Class<? extends HttpMessageConverter<?>> aClass) {
return o;
} @Override
public HttpInputMessage beforeBodyRead(HttpInputMessage httpInputMessage, MethodParameter methodParameter, Type type, Class<? extends HttpMessageConverter<?>> aClass) throws IOException {
return new HttpInputMessage() {
@Override
public InputStream getBody() throws IOException {
log.info("此处进行解密数据");
return new ByteArrayInputStream(IOUtils.toString(httpInputMessage.getBody()).replace("-encrypt", "").getBytes(StandardCharsets.UTF_8));
} @Override
public HttpHeaders getHeaders() {
return httpInputMessage.getHeaders();
}
};
} @Override
public Object afterBodyRead(Object o, HttpInputMessage httpInputMessage, MethodParameter methodParameter, Type type, Class<? extends HttpMessageConverter<?>> aClass) {
return o;
}
}

 3,编写ResponseBodyAdvice接口实现类,实现数据的加密操作

/**
* 加密数据
*
* @author huan.fu
* @date 2018/9/28 - 16:19
*/
@Slf4j
@RestControllerAdvice
public class ParamEncryptResponseBodyAdvice implements ResponseBodyAdvice { private final ObjectMapper objectMapper = new ObjectMapper(); @Override
public boolean supports(MethodParameter returnType, Class converterType) {
return returnType.hasMethodAnnotation(ResponseBody.class);
} @Override
public Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType, Class selectedConverterType, ServerHttpRequest request, ServerHttpResponse response) {
log.info("此处进行加密数据");
if (null != body) {
try {
Map map = objectMapper.readValue(objectMapper.writeValueAsString(body), Map.class);
map.forEach((key, value) -> map.put(key, value + "-encrypt"));
return map;
} catch (IOException e) {
log.error("加密数据失败.", e);
}
} return body;
}
}

 4,编写控制层进行测试

/**
* 用户信息控制器
*
* @author huan.fu
* @date 2018/9/28 - 15:55
*/
@RestController
@RequestMapping("user-info")
@Slf4j
public class UserInfoController { /**
* 添加用户实现返回值加密
*
* @param userInfo
* @return
*/
@PostMapping("add")
@Encrypt
public UserInfo add(@RequestBody UserInfo userInfo) {
log.info("添加新用户:[{}]", userInfo);
return userInfo;
} /**
* 修改实现获取的参数进行解密
*
* @param userInfo
* @return
*/
@PostMapping("update")
public UserInfo update(@Encrypt @RequestBody UserInfo userInfo) {
log.info("修改用户信息:[{}]", userInfo);
return userInfo;
}
}

 5,测试参数的解密操作

  可以看到:参数中的-encrypt 传递后后台被后台自动截取了,这样就类似于解密操作。

 6,测试返回值的加密操作

 可以看到:返回的值后面都有一个 -encrypt ,这样就实现了类似于加密操作。

基于RequestBodyAdvice和ResponseBodyAdvice来实现spring中参数的加密和解密的更多相关文章

  1. Spring 中参数名称解析 - ParameterNameDiscoverer

    Spring 中参数名称解析 - ParameterNameDiscoverer Spring 系列目录(https://www.cnblogs.com/binarylei/p/10198698.ht ...

  2. 探讨.NET Core中实现AES加密和解密以及.NET Core为我们提供了什么方便!

    前言 对于数据加密和解密每次我都是从网上拷贝一份,无需有太多了解,由于在.net core中对加密和解密目前全部是统一了接口,只是做具体的实现,由于遇到过问题,所以将打算基本了解下其原理,知其然足矣, ...

  3. JAVA中AES对称加密和解密

    AES对称加密和解密 package demo.security; import java.io.IOException; import java.io.UnsupportedEncodingExce ...

  4. JAVA中AES对称加密和解密以及与Python兼容

    引言:本文主要解决Java中用AES加密及解密,同时可通过Python脚本对Java加密后的字符进行解密的操作. 由于近期工作中用到需要使用Java对一串密钥进行加密,并且后台通过Python语言读取 ...

  5. spring中 的MD5 加密

    //对密码进行加密(不需要使用其他Md5工具  .spring中有 在digestUtils)        String password = DigestUtils.md5DigestAsHex( ...

  6. OPENSSL安装 以及使用openssl中的AES加密和解密

    OPENSSL安装:(VS) 1:第一步和所有的软件安装一样. 2:将OPENSSL中INLUCDE 和 LIB 分别拷贝到VS中VC的INLUCDE 和LIB目录下(我的机器上的目录是:C:\Pro ...

  7. asp.net中实现MD5加密、解密的方法

    这个MD5加密.解密的方法会使用即可. 使用时的代码备忘:Response.Write(FormsAuthentication.HashPasswordForStoringInConfigFile(& ...

  8. js中实现base64加密、解密

    //base64加密 解密 /* //1.加密 var result = Base.encode('125中文'); //--> "MTI15Lit5paH" //2.解密 ...

  9. Spring中的面向切面编程(AOP)简介

    一.什么是AOP AOP(Aspect-Oriented Programming, 面向切面编程): 是一种新的方法论, 是对传统 OOP(Object-Oriented Programming, 面 ...

随机推荐

  1. vue 进入页面每次都调用methods里的方法

    // 监听路由,每次进入页面调用方法,放在method里 mounted(){ this.getPath() }, methods: { getPath(){ console.log(this.$ro ...

  2. @RequestParam、@RequestBody、@PathVariable区别和案例分析

    一.前言 @RequestParam.@RequestBody.@PathVariable都是用于在Controller层接收前端传递的数据,他们之间的使用场景不太一样,今天来介绍一下!! 二.实体类 ...

  3. Selenium系列4-元素定位

    前言 说起元素定位,一定是学习自动化测试绕不开的第一道关,无论是web端的UI自动化还是移动端的自动化,在需要首先对元素进行定位才可以完成对元素的操作已达成测试目的,在Selenium中,可以使用fi ...

  4. 5-21python数据类型

    一.字符串,是不可变数据类型,所有字符串的方法都不会修改字符串的值,使用字符串的方法后都是生成了一个新的字符串.就因为字符串是不可变变量! 字符串的方法 1. strip(),默认去空格,但是当()中 ...

  5. php 圆角图片处理

    /** * 把图片转换成圆角 * @param string $imgpath * @param int $radius * @return resource */ public function r ...

  6. 使用PHP获取图像文件的EXIF信息

    在我们拍的照片以及各类图像文件中,其实还保存着一些信息是无法直观看到的,比如手机拍照时会有的位置信息,图片的类型.大小等,这些信息就称为 EXIF 信息.一般 JPG . TIFF 这类的图片文件都会 ...

  7. java中避免集合死链调用

    目录 1. 前言 2. 场景 3. 环境 3.1 开发环境准备 3.2 数据准备 3.2.1 Mysql数据库表及数据 3.2.2 redis库数据 4. 解决方式 5.完整代码 5.1Model 5 ...

  8. Linux系列(36) - yum命令安装(3)

    yum常用命令 查询 yum list:查询所有可用软件包列表 yum search 关键字:搜索服务器上所有和关键字相关的包 安装 yum -y install 包名 选项: -install 安装 ...

  9. localStorage util

    // localStorage util var db ={ set : function(key, obj){ localStorage.setItem(key, JSON.stringify(ob ...

  10. 常用的jquery 中一些js

    目录: 1.验证用户登录信息 2. 获取下拉框所选中的元素 3.  动态获取 id 和对应文本框的值  4. table 中 tr  的隐藏 5 . 更换图片  6. ajax  进行提交 7. 判断 ...