`
zweichxu
  • 浏览: 134834 次
  • 性别: Icon_minigender_1
  • 来自: 南京
社区版块
存档分类
最新评论

spring mvc框架增加对消息的加密/解密

 
阅读更多

 开发中会遇到要求对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

 

分享到:
评论

相关推荐

    Spring MVC请求参数与响应结果全局加密和解密详解

    Spring MVC请求参数与响应结果全局加密和解密详解 在本文中,我们将详细介绍Spring MVC请求参数与响应结果全局加密和解密的相关知识点,包括请求参数的加密和解密、响应结果的加密和解密、ContentType的处理等。 ...

    Spring数据库连接等配置加密

    总的来说,Spring框架通过结合配置文件和解密器,可以有效地保护数据库连接等敏感信息,避免了因信息泄露带来的潜在风险。开发者应根据项目需求选择合适的加密算法和工具,并确保加密密钥的安全管理,以提升应用的...

    json接口的spring实例(含httpclient、加密解密)

    本示例将围绕一个基于Spring框架实现的JSON接口,结合HTTPClient库进行网络通信,并利用DES(Data Encryption Standard)加密解密技术确保数据安全。 首先,我们来看JSON接口的实现。Spring框架提供了丰富的支持来...

    spring-boot示例项目

    本项目示例基于spring boot 最新版本(2.1.9)实现,Spring Boot、Spring Cloud 学习示例,将持续更新…… 在基于Spring Boot、Spring ...Spring Boot是由Pivotal团队提供的全新框架,其设计目的是用来简化新Sprin

    AES加密解密

    本项目涉及使用AES进行数据加密解密,同时结合了Eclipse开发工具、MySQL数据库以及Spring MVC、Spring和MyBatis框架,构建了一个具有权限管理功能的应用。 首先,AES加密是一种块加密算法,它基于替换和置换的过程...

    spring+spring mvc+mybaits搭建基础框架

    spring+spring mvc+mybaits搭建基础框架,内集成sqllite数据库,直接把demo中的war包放到服务器下即可运行,实现数据库密码连接等信息在配置文件中以密文形式存在des方式加密解密,。http://localhost:8090/

    jdk1.8实现http接口rsa加密解密.zip

    在Java开发中,使用JDK 1.8结合Spring MVC框架来实现HTTP接口的RSA加密解密,可以增强数据安全性,防止敏感信息在传输过程中被窃取。 首先,我们需要理解RSA的工作原理。RSA基于数论中的大数因子分解难题,它包含两...

    SSMRSA前后台加密解密案例

    同时,可以通过Spring的配置文件来注入密钥对或者相关的加密解密服务。 6. **标签相关性**:"SSM"标签指的是本案例使用了SSM框架;"RSA"标签表示涉及RSA加密算法;"加密"标签则强调了数据安全的实现。 总结来说,...

    druid实现springmvc数据库连接的用户名和密码加密

    在Spring MVC中,可以创建一个自定义的Bean,该Bean使用Java的`java.security.MessageDigest`类或其他加密库来实现加密功能。 2. **扩展Druid配置**:默认的Druid配置并不直接支持加密的用户名和密码。因此,我们...

    基于SM3算法和SM4算法的在线加解密系统(针对任何文件的加解密)

    该在线加解密系统采用了Spring MVC框架进行开发,Spring MVC是Spring框架的一个模块,提供了模型-视图-控制器(MVC)架构,使得开发者可以轻松地构建可维护的、高性能的Web应用程序。而artery则是对Spring的进一步...

    MD5 加密解密例子

    Struts是MVC架构的Web开发框架,Spring提供了全面的DI(依赖注入)和AOP(面向切面编程)功能,而Hibernate则是一个流行的ORM(对象关系映射)工具,它们一起构建了企业级应用的坚实基础。 以下是一个简单的MD5加密...

    RSA 加密程序 Version 1.5(支持文件、文本加密解密, 支持多种语言)

    程序采用了经典的MVC的设计方案,将底层的RSA加密解密功能封装为单独的组件,并定义了RSA的操作模型,提供视图和底层模型进行交互的外观;视图层分离为视图和控制器两块,视图信息的更新由控制层进行控制。 程序综合...

    spring cloud config、bus源码

    Spring Cloud Config/Bus 源码解读 本文将对 Spring Cloud Config/Bus 的源码进行解读,涵盖 Server ...通过对源码的分析,可以更好地理解 Spring Cloud Config/Bus 的工作机制,并更好地使用这个框架来管理配置文件。

    Spring数据源及配置文件数据加密实现过程详解

    其中,对称加密是指使用同一个密钥进行加密和解密,而非对称加密是指使用一对密钥进行加密和解密。 三、加密配置文件的实现过程 下面是一个使用对称加密算法对数据源配置文件进行加密的示例实现过程: 首先,需要...

    RSA加密!非对称加密

    首先,加密过程中,发送方使用接收方的公钥对信息进行加密。公钥是由接收方生成的一对密钥之一,可以公开分享,而不会损害私钥的安全性。在RSA算法中,公钥通常由两个大素数的乘积以及一个欧拉函数的计算结果组成。 ...

    加密解密思路

    标题中的“加密解密思路”指的是在信息技术领域中,如何对数据进行安全保护的重要概念。在互联网通信中,为了确保信息的隐私和安全性,我们通常会使用加密算法将明文转化为密文,防止非授权人员获取敏感信息。解密则...

    java微信公众号MVC开发框架

    jwx是开源的java公众号开发MVC框架,基于spring配置文件和微信消息或事件注解,通过微信上下文处理一个或多个微信公众号服务请求。目的主要有两个,其一生封装微信请求xml消息为java实体对象,将返回对象转换为xml...

    java springboot 电子签名 文件发送自己签加密

    在Spring Boot应用中,可以使用Java Cryptography Extension(JCE)提供的加密算法,如AES、RSA等,来对文件进行加密。Spring Security也可以提供帮助,其提供的CipherService类可以简化加密操作。在文件存储时,先...

    MVC单点登录

    以上代码展示了使用Spring Security配置SSO的基本框架,包括允许匿名访问登录页面、对其他请求进行身份验证、以及设置RememberMe服务。 **6. SSO的挑战与解决方案** - 安全性:确保票据的安全传输和存储,防止中间...

Global site tag (gtag.js) - Google Analytics