spring mvc框架增加对消息的加密/解密 博客分类: spring mvc笔记
程序员文章站
2024-03-13 18:49:51
...
开发中会遇到要求对http传输的数据进行加密传输,我们可以重写spring mvc的MappingJackson2HttpMessageConverter类,实现对加密解密的支持。代码如下:
package com.hzwei.spring.messageconvert.ext; import java.io.*; import java.lang.reflect.Type; import org.springframework.http.*; import org.springframework.http.converter*; import org.springframework.http.converter.json.*; import org.springframework.util.TypeUtils; import com.fasterxml.jackson.core.*; import com.fasterxml.jackson.core.util.*; import com.fasterxml.jackson.databind.*; import com.fasterxml.jackson.databind.ser.FilterProvider; import com.jsecode.platform.util.EncryptDecrypt; /** * 扩展MappingJackson2HttpMessageConverter类,增加对消息的解密/加密支持处理(支持spring-web-4.3.x) */ public class EncryptMappingJackson2HttpMessageConverter extends MappingJackson2HttpMessageConverter { private static final MediaType TEXT_EVENT_STREAM = new MediaType("text", "event-stream"); private PrettyPrinter ssePrettyPrinter; private boolean needEncryptOutputMessage = false; private boolean needDecryptInputMessage = false; protected void init(ObjectMapper objectMapper){ super.init(objectMapper); DefaultPrettyPrinter prettyPrinter = new DefaultPrettyPrinter(); prettyPrinter.indentObjectsWith(new DefaultIndenter(" ", "\ndata:")); this.ssePrettyPrinter = prettyPrinter; } public boolean isNeedEncryptOutputMessage(){ return needEncryptOutputMessage; } public void setNeedEncryptOutputMessage(boolean needEncryptOutputMessage){ this.needEncryptOutputMessage = needEncryptOutputMessage; } public boolean isNeedDecryptInputMessage(){ return needDecryptInputMessage; } public void setNeedDecryptInputMessage(boolean needDecryptInputMessage){ this.needDecryptInputMessage = needDecryptInputMessage; } @Override protected Object readInternal(Class<?> clazz, HttpInputMessage inputMessage) throws IOException, HttpMessageNotReadableException{ JavaType javaType = getJavaType(clazz, null); return readJavaType(javaType, inputMessage); } public Object read(Type type, Class<?> contextClass, HttpInputMessage inputMessage) throws IOException, HttpMessageNotReadableException{ JavaType javaType = getJavaType(type, contextClass); return readJavaType(javaType, inputMessage); } private Object readJavaType(JavaType javaType, HttpInputMessage inputMessage){ try{ if(inputMessage instanceof MappingJacksonInputMessage){ Class<?> deserializationView = ((MappingJacksonInputMessage)inputMessage).getDeserializationView(); if(deserializationView != null){ return this.objectMapper.readerWithView(deserializationView) .forType(javaType) .readValue(getInputStreamData(inputMessage.getBody())); } } return this.objectMapper.readValue(getInputStreamData(inputMessage.getBody()), javaType); }catch(JsonProcessingException ex){ throw new HttpMessageNotReadableException("JSON parse error: " + ex.getOriginalMessage(), ex); }catch(IOException ex){ throw new HttpMessageNotReadableException("I/O error while reading input message", ex); } } private byte[] getInputStreamData(InputStream in) throws IOException{ ByteArrayOutputStream swapStream = new ByteArrayOutputStream(); byte[] buff = new byte[1024]; int offset = 0; while((offset = in.read(buff)) > 0){ swapStream.write(buff, 0, offset); } byte[] bytes = swapStream.toByteArray(); if(needDecryptInputMessage){ // 对bytes进行解密 bytes = EncryptDecrypt.AESFastDecrypt2(bytes); //TODO 此处换上您的解密算法 } return bytes; } @Override protected void writeInternal(Object object, Type type, HttpOutputMessage outputMessage) throws IOException, HttpMessageNotWritableException{ if(needEncryptOutputMessage){ writeInternalEncrypt(object, type, outputMessage); }else{ super.writeInternal(object, type, outputMessage); } } // 对返回值进行序列化并使用AES加密 protected void writeInternalEncrypt(Object object, Type type, HttpOutputMessage outputMessage) throws IOException, HttpMessageNotWritableException{ MediaType contentType = outputMessage.getHeaders().getContentType(); JsonEncoding encoding = getJsonEncoding(contentType); JsonFactory factory = this.getObjectMapper().getFactory(); ByteArrayBuilder bb = new ByteArrayBuilder(factory._getBufferRecycler()); JsonGenerator generator = factory.createGenerator(bb, encoding); writeToJsonGenerator(object, type, generator, contentType); try{ //TODO 此处换上您自己的加密算法 byte[] byteData = EncryptDecrypt.AESFastEncrypt(bb.toByteArray()); outputMessage.getBody().write(byteData); }catch(Exception ex){ throw new HttpMessageNotWritableException("Could not encrypt and write message: " + ex.getMessage(), ex); } } // 保持MappingJackson2HttpMessageConverter原滋原味的序列化方法 protected void writeToJsonGenerator(Object object, Type type, JsonGenerator generator, MediaType contentType) throws IOException, HttpMessageNotWritableException{ try{ writePrefix(generator, object); Class<?> serializationView = null; FilterProvider filters = null; Object value = object; JavaType javaType = null; if(object instanceof MappingJacksonValue){ MappingJacksonValue container = (MappingJacksonValue)object; value = container.getValue(); serializationView = container.getSerializationView(); filters = container.getFilters(); } if(type != null && value != null && TypeUtils.isAssignable(type, value.getClass())){ javaType = getJavaType(type, null); } ObjectWriter objectWriter; if(serializationView != null){ objectWriter = this.objectMapper.writerWithView(serializationView); }else if(filters != null){ objectWriter = this.objectMapper.writer(filters); }else{ objectWriter = this.objectMapper.writer(); } if(javaType != null && javaType.isContainerType()){ objectWriter = objectWriter.forType(javaType); } SerializationConfig config = objectWriter.getConfig(); if(contentType != null && contentType.isCompatibleWith(TEXT_EVENT_STREAM) && config.isEnabled(SerializationFeature.INDENT_OUTPUT)){ objectWriter = objectWriter.with(this.ssePrettyPrinter); } objectWriter.writeValue(generator, value); writeSuffix(generator, object); generator.flush(); }catch(JsonProcessingException ex){ throw new HttpMessageNotWritableException("Could not write JSON: " + ex.getOriginalMessage(), ex); } } }
在spring mvc项目中,替换MappingJackson2HttpMessageConverter为EncryptMappingJackson2HttpMessageConverter