Spring 接口数据加密---局部加密篇

Spring 接口数据加密—局部加密

  • 注解
  • RequestBody 解密
  • ResponseBody 加密
  • 使用

注解

package com.base.project.commcon.annotation.des;

import java.lang.annotation.*;

@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface DecryptRequestBody {

    boolean dencrypt() default true;
}
DecryptRequestBody注解
自定义解密注解,默认设置解密==true, 注解适用于方法上
package com.base.project.commcon.annotation.des;

import java.lang.annotation.*;

@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface EncryptResponBody {

    boolean encrypt() default true;
}
EncryptResponBody
自定义解密注解

RequestBody 解密

package com.base.project.advice;

import com.base.project.commcon.annotation.des.DecryptRequestBody;
import org.springframework.core.MethodParameter;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpInputMessage;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.json.GsonHttpMessageConverter;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.servlet.mvc.method.annotation.RequestBodyAdvice;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Type;

/**
 * 这里只针对application/json的数据进行请求解密
 */
@ControllerAdvice
public class AppRequestBodyAdvice implements RequestBodyAdvice {
    @Override
    public boolean supports(MethodParameter methodParameter, Type type, Class<? extends HttpMessageConverter<?>> aClass) {

        if(GsonHttpMessageConverter.class.isAssignableFrom(aClass)){

            return true;
        }
        return false;
    }

    @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 {
        boolean dencrypt = false;
        HttpInputMessage returnInputMessage = null;

        if(methodParameter.getMethod().isAnnotationPresent(DecryptRequestBody.class)) {

            DecryptRequestBody body = methodParameter.getMethodAnnotation(DecryptRequestBody.class);
            dencrypt = body.dencrypt();
        }
        if(dencrypt) {

            InputStream is = httpInputMessage.getBody();

            //在此处对数据进行解密

            returnInputMessage = new DecryptHttpInputMessage(httpInputMessage.getHeaders(), this.toDencrypt(is));
            //returnInputMessage =
        }else {

            returnInputMessage = httpInputMessage;
        }

        return returnInputMessage;
    }

    @Override
    public Object afterBodyRead(Object o, HttpInputMessage httpInputMessage, MethodParameter methodParameter, Type type, Class<? extends HttpMessageConverter<?>> aClass) {

        return o;
    }

    public InputStream toDencrypt(InputStream is) throws IOException {

        ByteArrayOutputStream out = new ByteArrayOutputStream();
        byte[] b = new byte[4096];
        int n = 0;
        while ((n = is.read(b)) > 0) {
            out.write(b, 0, n);
        }
        byte[] buf = out.toByteArray();

        //对buf进行解密
        //
        ByteArrayInputStream bis = new ByteArrayInputStream(buf);
        return bis;
    }
    class DecryptHttpInputMessage implements HttpInputMessage{

        private HttpHeaders headers = null;
        private InputStream is = null;

        public DecryptHttpInputMessage(HttpHeaders headers, InputStream is) {

            this.headers = headers;
            this.is = is;
        }
        @Override
        public HttpHeaders getHeaders() {
            // TODO Auto-generated method stub
            return headers;
        }

        @Override
        public InputStream getBody() throws IOException {
            // TODO Auto-generated method stub
            return is;
        }


    }
}

ResponseBody 加密

package com.base.project.advice;

import com.base.project.commcon.annotation.des.EncryptResponBody;
import org.springframework.core.MethodParameter;
import org.springframework.http.MediaType;
import org.springframework.http.converter.json.GsonHttpMessageConverter;
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;

import java.io.IOException;

/**
 * 这里只针对application/json的数据进行响应加密
 */
@ControllerAdvice
public class AppResponseBodyAdvice implements ResponseBodyAdvice {
    @Override
    public boolean supports(MethodParameter methodParameter, Class aClass) {

        if(GsonHttpMessageConverter.class.isAssignableFrom(aClass)){

            return true;
        }
        return false;
    }

    @Override
    public Object beforeBodyWrite(Object o, MethodParameter methodParameter, MediaType mediaType, Class aClass, ServerHttpRequest serverHttpRequest, ServerHttpResponse serverHttpResponse) {

        boolean encrypt = false;
        if(methodParameter.getMethod().isAnnotationPresent(EncryptResponBody.class)) {

            EncryptResponBody encryptBody = methodParameter.getMethodAnnotation(EncryptResponBody.class);
            encrypt = encryptBody.encrypt();
        }
        if(encrypt) {

            try {

                //对数据进行加密返回
                byte[] buf = this.toEncrypt(o);
                serverHttpResponse.getBody().write(buf);
                return null;
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }

        }
        return o;
    }
    private byte[] toEncrypt(Object o){

        //object内容进行加密
        return o.toString().getBytes();
    }
}

使用

将注解设置在要解密或者解密,或者加解密的action方法上即可。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值