Spring中处理JSON请求通常使用@RequestBody和@ResponseBody注解,针对JSON请求加解密和过滤字符串,Spring提供了RequestBodyAdvice和ResponseBodyAdvice两个接口 
具体使用 
1、解密:


import com.hive.util.AESOperator;
import org.apache.commons.io.IOUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.MethodParameter;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpInputMessage;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.servlet.mvc.method.annotation.RequestBodyAdvice; import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Type; /**
* 请求数据解密
*/
@ControllerAdvice(basePackages = "com.hive")
public class MyRequestBodyAdvice implements RequestBodyAdvice {
private final static Logger logger = LoggerFactory.getLogger(MyResponseBodyAdvice.class);
@Override
public boolean supports(MethodParameter methodParameter, Type targetType, Class<? extends HttpMessageConverter<?>> converterType) {
return true;
} @Override
public Object handleEmptyBody(Object body, HttpInputMessage inputMessage, MethodParameter parameter, Type targetType, Class<? extends HttpMessageConverter<?>> converterType) {
return body;
} @Override
public HttpInputMessage beforeBodyRead(HttpInputMessage inputMessage, MethodParameter parameter, Type targetType, Class<? extends HttpMessageConverter<?>> converterType) throws IOException {
try {
return new MyHttpInputMessage(inputMessage);
} catch (Exception e) {
e.printStackTrace();
return inputMessage;
}
} @Override
public Object afterBodyRead(Object body, HttpInputMessage inputMessage, MethodParameter parameter, Type targetType, Class<? extends HttpMessageConverter<?>> converterType) {
return body;
} class MyHttpInputMessage implements HttpInputMessage {
private HttpHeaders headers; private InputStream body; public MyHttpInputMessage(HttpInputMessage inputMessage) throws Exception {
this.headers = inputMessage.getHeaders();
this.body = IOUtils.toInputStream(AESOperator.getInstance().decrypt(IOUtils.toString(inputMessage.getBody(), "UTF-8")), "UTF-8");
} @Override
public InputStream getBody() throws IOException {
return body;
} @Override
public HttpHeaders getHeaders() {
return headers;
}
}
}

2、加密:

package com.hive.core.json;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.hive.util.AESOperator;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.MethodParameter;
import org.springframework.http.MediaType;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice; /**
* 返回数据加密
*/
@ControllerAdvice(basePackages = "com.hive")
public class MyResponseBodyAdvice implements ResponseBodyAdvice {
private final static Logger logger = LoggerFactory.getLogger(MyResponseBodyAdvice.class);
private final static String KEY = "!QA2Z@w1sxO*(-8L"; @Override
public boolean supports(MethodParameter returnType, Class converterType) {
return true;
} @Override
public Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType, Class selectedConverterType, ServerHttpRequest request, ServerHttpResponse response) {
boolean encode = false;
if (returnType.getMethod().isAnnotationPresent(SerializedField.class)) {
//获取注解配置的包含和去除字段
SerializedField serializedField = returnType.getMethodAnnotation(SerializedField.class);
//是否加密
encode = serializedField.encode();
}
if (encode) {
logger.info("对方法method :" + returnType.getMethod().getName() + "返回数据进行加密");
ObjectMapper objectMapper = new ObjectMapper();
try {
String result = objectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(body);
return AESOperator.getInstance().encrypt(result);
} catch (JsonProcessingException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
return body;
}
}

注解类:

package com.hive.core.json;

import org.springframework.web.bind.annotation.Mapping;

import java.lang.annotation.*;

@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Mapping
public @interface SerializedField {
/**
* 是否加密
* @return
*/
boolean encode() default true;
}
}

 
默认是true,我这边使用false。注解类中还可以定义需要过滤的字符串

AES加密类

package com.hive.util;

import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder; import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec; /**
* AES CBC加密
*/
public class AESOperator {
/*
* 加密用的Key 可以用26个字母和数字组成 此处使用AES-128-CBC加密模式,key需要为16位。
*/
private String KEY = "!QA2Z@w1sxO*(-8L";
private String VECTOR = "!WFNZFU_{H%M(S|a";
private static AESOperator instance = null; private AESOperator() { } public static AESOperator getInstance() {
return Nested.instance;
}
//于内部静态类只会被加载一次,故该实现方式时线程安全的!
static class Nested {
private static AESOperator instance = new AESOperator();
} /**
* 加密
*
* @param content
* @return
* @throws Exception
*/
public String encrypt(String content) throws Exception {
return encrypt(content, KEY, VECTOR);
}
/**
* 加密
*
* @param content
* @return
* @throws Exception
*/
public String encrypt(String content,String key) throws Exception {
return encrypt(content, key, VECTOR);
} /**
* 加密
*
* @param content
* @param key
* @param vector
* @return
* @throws Exception
*/
public String encrypt(String content, String key, String vector) throws Exception {
if (key == null) {
return null;
}
if (key.length() != 16) {
return null;
}
SecretKeySpec skeySpec = new SecretKeySpec(key.getBytes("UTF-8"), "AES");
IvParameterSpec iv = new IvParameterSpec(vector.getBytes());// 使用CBC模式,需要一个向量iv,可增加加密算法的强度
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, skeySpec, iv);
byte[] encrypted = cipher.doFinal(content.getBytes("UTF-8"));
return new BASE64Encoder().encode(encrypted);// 此处使用BASE64做转码。
} /**
* 解密
*
* @param content
* @return
* @throws Exception
*/
public String decrypt(String content) throws Exception {
return decrypt(content, KEY, VECTOR);
}
/**
* 解密
*
* @param content
* @return
* @throws Exception
*/
public String decrypt(String content,String key) throws Exception {
return decrypt(content, key, VECTOR);
}
/**
* 解密
*
* @param content
* @param key
* @param vector
* @return
* @throws Exception
*/
public String decrypt(String content, String key, String vector) throws Exception {
try {
if (key == null) {
return null;
}
if (key.length() != 16) {
return null;
}
SecretKeySpec skeySpec = new SecretKeySpec(key.getBytes("UTF-8"), "AES");
IvParameterSpec iv = new IvParameterSpec(vector.getBytes());
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(Cipher.DECRYPT_MODE, skeySpec, iv);
byte[] encrypted1 = new BASE64Decoder().decodeBuffer(content);// 先用base64解密
byte[] original = cipher.doFinal(encrypted1);
String originalString = new String(original, "UTF-8");
return originalString;
} catch (Exception ex) {
return null;
}
} public static void main(String[] args) throws Exception {
// 需要加密的字串
String cSrc = "我爱你"; // 加密
long lStart = System.currentTimeMillis();
String enString = AESOperator.getInstance().encrypt(cSrc,"!QA2Z@w1sxO*(-8L");
System.out.println("加密后的字串是:" + enString); long lUseTime = System.currentTimeMillis() - lStart;
System.out.println("加密耗时:" + lUseTime + "毫秒");
// 解密
lStart = System.currentTimeMillis();
String DeString = AESOperator.getInstance().decrypt(enString);
System.out.println("解密后的字串是:" + DeString);
lUseTime = System.currentTimeMillis() - lStart;
System.out.println("解密耗时:" + lUseTime + "毫秒");
} }

最新文章

  1. ambari2.4.2_centos7 学习全纪录
  2. 80.Android之内存管理
  3. 关于全局唯一ID生成方法
  4. Microsoft Dynamics CRM 2011/2013 JS操作集锦
  5. Android 中View的绘制机制源代码分析 三
  6. 利用css3动画和border来实现圆形进度条
  7. 使用C#对MongoDB中的数据进行查询,改动等操作
  8. Python 智能处理方向的工具
  9. Spring+SpringMVC+MyBatis深入学习及搭建(十)——MyBatis逆向工程
  10. 深入设计电子计算器(一)——CPU框架及指令集设计
  11. 构造方法、This关键字、静态与封装的特性与作用
  12. ubuntu下安装Visual Studio Code
  13. 七、.net core下配置、数据库访问等操作实现
  14. Aspects源码解析(转载)
  15. Pytorch快速入门及在线体验
  16. VirtualBox如何扩展虚拟机Ubuntu的硬盘容量-转
  17. ucos ii 46个系统API函数解析
  18. JS的正则表达式简介
  19. 详细解读Spark的数据分析引擎:Spark SQL
  20. Installing Hyperledger Fabric v1.1 on Ubuntu 16.04 — Part I

热门文章

  1. python 百度cpc点击
  2. js中数组常用的api 及其作用
  3. Python之历史
  4. CSS&amp;JS两种方式实现手风琴式折叠菜单
  5. C++知识回顾之__stdcall、__cdcel和__fastcall三者的区别
  6. Android中使用progurad混淆代码
  7. 编码最佳实践——Liskov替换原则
  8. Spark编译
  9. 转:IIS 应用程序池 内存 自动回收
  10. 由内省引出JavaBean的讲解