css
package com.my.config;
import cn.hutool.core.io.FileUtil;
import com.fasterxml.jackson.core.JsonEncoding;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.util.DefaultPrettyPrinter;
import com.fasterxml.jackson.databind.*;
import com.fasterxml.jackson.databind.exc.InvalidDefinitionException;
import com.fasterxml.jackson.databind.ser.FilterProvider;
import com.google.gson.Gson;
import org.springframework.http.HttpInputMessage;
import org.springframework.http.HttpOutputMessage;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConversionException;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.http.converter.HttpMessageNotWritableException;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.http.converter.json.MappingJacksonInputMessage;
import org.springframework.http.converter.json.MappingJacksonValue;
import org.springframework.util.TypeUtils;
import java.io.*;
import java.lang.reflect.Type;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.*;
/**
* 自定义消息处理
*/
public class CryptMessageConvertPro extends MappingJackson2HttpMessageConverter {
private List<MediaType> supportedMediaTypesNew = new ArrayList<>();
private final static String APPLICATION_CRYPT = "application/crypt;charset=UTF-8";
private static final Map<String, JsonEncoding> ENCODINGS = new HashMap(JsonEncoding.values().length + 1);
private static CryptMessage cryptMessage;
static {
JsonEncoding[] var0 = JsonEncoding.values();
int var1 = var0.length;
for(int var2 = 0; var2 < var1; ++var2) {
JsonEncoding encoding = var0[var2];
ENCODINGS.put(encoding.getJavaName(), encoding);
}
ENCODINGS.put("US-ASCII", JsonEncoding.UTF8);
/**
* 消息处理工具类,即对数据加解密操作
*/
cryptMessage = new MessageCryptUtils.Base64Message();//base64加解密
// cryptMessage = new MessageCryptUtils.AESMessage("1qazxsw23edcvfr4");//aes加解密
// cryptMessage = new MessageCryptUtils.RSAMessage(FileUtil.readUtf8String("F:\\primary.pem"),FileUtil.readUtf8String("F:\\public.pem"));//rsa加解密
}
/**
* 此处加入自定义的 MediaType
* @return
*/
@Override
public List<MediaType> getSupportedMediaTypes() {
if (supportedMediaTypesNew.isEmpty()) {
supportedMediaTypesNew.addAll(super.getSupportedMediaTypes());
supportedMediaTypesNew.add(new MediaType("application","crypt", StandardCharsets.UTF_8));
}
return Collections.unmodifiableList(this.supportedMediaTypesNew);
}
@Override
protected void writeInternal(Object o, Type type, HttpOutputMessage outputMessage) throws IOException, HttpMessageNotWritableException {
MediaType contentType = outputMessage.getHeaders().getContentType();
JsonEncoding encoding = this.getJsonEncoding(contentType);
OutputStream body = outputMessage.getBody();
Object object = o;
/** ========此处做加密处理========== **/
if (APPLICATION_CRYPT.startsWith(Objects.requireNonNull(outputMessage.getHeaders().getContentType()).toString())) {
try {
String jsonString = this.objectMapper.writeValueAsString(object);
object = cryptMessage.encodeCrypt(jsonString);
} catch (Exception e) {
throw new RuntimeException("响应结果加密异常");
}
}
/** =======此处做加密处理========== **/
JsonGenerator generator = this.objectMapper.getFactory().createGenerator(body, encoding);
try {
this.writePrefix(generator, object);
Object value = object;
Class<?> serializationView = null;
FilterProvider filters = null;
JavaType javaType = null;
if (object instanceof MappingJacksonValue) {
MappingJacksonValue container = (MappingJacksonValue)object;
value = container.getValue();
serializationView = container.getSerializationView();
filters = container.getFilters();
}
if (type != null && TypeUtils.isAssignable(type, value.getClass())) {
javaType = this.getJavaType(type, (Class)null);
}
ObjectWriter objectWriter = serializationView != null ? this.objectMapper.writerWithView(serializationView) : this.objectMapper.writer();
if (filters != null) {
objectWriter = objectWriter.with(filters);
}
if (javaType != null && javaType.isContainerType()) {
objectWriter = objectWriter.forType(javaType);
}
SerializationConfig config = objectWriter.getConfig();
if (contentType != null && contentType.isCompatibleWith(MediaType.TEXT_EVENT_STREAM) && config.isEnabled(SerializationFeature.INDENT_OUTPUT)) {
objectWriter = objectWriter.with(new DefaultPrettyPrinter());
}
objectWriter.writeValue(generator, value);
this.writeSuffix(generator, object);
generator.flush();
} catch (InvalidDefinitionException var13) {
InvalidDefinitionException ex = var13;
throw new HttpMessageConversionException("Type definition error: " + ex.getType(), ex);
} catch (JsonProcessingException var14) {
JsonProcessingException ex = var14;
throw new HttpMessageNotWritableException("Could not write JSON: " + ex.getOriginalMessage(), ex);
}
}
@Override
protected Object readInternal(Class<?> clazz, HttpInputMessage inputMessage) throws IOException, HttpMessageNotReadableException {
JavaType javaType = this.getJavaType(clazz, (Class)null);
return this.readJavaType(javaType, inputMessage);
}
@Override
public Object read(Type type, Class<?> contextClass, HttpInputMessage inputMessage) throws IOException, HttpMessageNotReadableException {
JavaType javaType = this.getJavaType(type, contextClass);
return this.readJavaType(javaType, inputMessage);
}
private Object readJavaType(JavaType javaType, HttpInputMessage inputMessage) throws IOException {
MediaType contentType = inputMessage.getHeaders().getContentType();
Charset charset = contentType != null && contentType.getCharset() != null ? contentType.getCharset() : StandardCharsets.UTF_8;
boolean isUnicode = ENCODINGS.containsKey(charset.name());
try {
InputStream body = inputMessage.getBody();
/**=======此处做解密处理==========**/
if (contentType != null && contentType.toString().equals(APPLICATION_CRYPT)) {//解密加密数据
try {
byte[] bytes = new byte[body.available()];
body.read(bytes);
String res = cryptMessage.decodeCrypt(bytes);
Object result = this.objectMapper.readValue(res.getBytes(StandardCharsets.UTF_8), javaType);
return result;
} catch (Exception e) {
throw new RuntimeException("参数解密失败");
}
}
/**==========此处做解密处理=======**/
if (inputMessage instanceof MappingJacksonInputMessage) {
Class<?> deserializationView = ((MappingJacksonInputMessage)inputMessage).getDeserializationView();
if (deserializationView != null) {
ObjectReader objectReader = this.objectMapper.readerWithView(deserializationView).forType(javaType);
if (isUnicode) {
return objectReader.readValue(body);
}
Reader reader = new InputStreamReader(body, charset);
return objectReader.readValue(reader);
}
}
if (isUnicode) {
return this.objectMapper.readValue(body, javaType);
} else {
Reader reader = new InputStreamReader(body, charset);
return this.objectMapper.readValue(reader, javaType);
}
} catch (InvalidDefinitionException var9) {
InvalidDefinitionException ex = var9;
throw new HttpMessageConversionException("Type definition error: " + ex.getType(), ex);
} catch (JsonProcessingException var10) {
JsonProcessingException ex = var10;
throw new HttpMessageNotReadableException("JSON parse error: " + ex.getOriginalMessage(), ex, inputMessage);
}
}
}
spring的配置
css
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 WebConfig implements WebMvcConfigurer {
@Override
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
// 设置优先级为 0,优先使用
converters.set(1, new CryptMessageConvertPro());
}
}
加密工具
css
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 WebConfig implements WebMvcConfigurer {
@Override
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
// 设置优先级为 0,优先使用
converters.set(1, new CryptMessageConvertPro());
}
}
用法
css
@RequestMapping(method = RequestMethod.POST,value = "/test2",produces = "application/crypt")
@ResponseBody
public CryptResult test2(@RequestBody Map<String,Object> param, HttpServletRequest request) throws InterruptedException {
String string = UUID.randomUUID().toString();
param.put("uuid", string);
System.out.println(string);
return CryptResult.success(param);
}