RequestBodyAdvice和ResponseBodyAdvice接口

接口源码

	
	//ResponseBodyAdvice接口
	public interface ResponseBodyAdvice<T> {
	    boolean supports(MethodParameter var1, 
	    				 Class<? extends HttpMessageConverter<?>> var2);
	
	    @Nullable
	    T beforeBodyWrite(@Nullable T var1, 
	    				  MethodParameter var2, 
	    				  MediaType var3, 
	    				  Class<? extends HttpMessageConverter<?>> var4, 
	    				  ServerHttpRequest var5, 
	    				  ServerHttpResponse var6); 
		}

	//RequestBodyAdvice 接口
	public interface RequestBodyAdvice {
	    boolean supports(MethodParameter var1, 
	    				 Type var2, 
	    				 Class<? extends HttpMessageConverter<?>> var3);
	
	    HttpInputMessage beforeBodyRead(HttpInputMessage var1, 
	    								MethodParameter var2, 
	    								Type var3, 
	    								Class<? extends HttpMessageConverter<?>> var4) 
	    								throws IOException;
	
	    Object afterBodyRead(Object var1, 
	    					 HttpInputMessage var2, 
	    					 MethodParameter var3, 
	    					 Type var4, 
	    					 Class<? extends HttpMessageConverter<?>> var5);
	
	    @Nullable
	    Object handleEmptyBody(@Nullable Object var1, 
	    						HttpInputMessage var2, 
	    						MethodParameter var3, 
	    						Type var4, 
	    						Class<? extends HttpMessageConverter<?>> var5);
	}
		

使用场景

RequestBodyAdvice一般使用是处理解密json串,而ResponseBodyAdvice是一般使用是处理加密字符串。

执行机制

1.RequestBodyAdvice

  需在Controller层中的方法上加上@RequestMapping和@RequestBody;若是没有@RequestBody,
  RequestBodyAdvice则不会执行。

2.ResponseBodyAdvice

 需在controller层中的方法上加上@RequestMapping和ResponseBody;若是没有@ResponseBody,
 ResponseBodyAdvice不会执行。

运用

1.准备自定义注解

	@Target(Element.METHOD)
	@Retention(RetentionPolicy.RUNTIME)
	public @interface Encrypt{
		// do nothing,this is just a mark 
	}

2.实现接口类

	@Slf4j
	@RestControllerAdvice
	public class ParamEncryptResponseBodyAdvice implements ResponseBodyAdvice { 
	
	    @Value("${public.clientKey}")
	    private String clientKey;
	
	    @Override
	    public boolean supports(MethodParameter methodParameter, Class aClass) {
	        boolean support = methodParameter.hasMethodAnnotation(Encrypt.class);
	        return support;
	    }
	
	    @Override
	    public Object beforeBodyWrite(Object o, MethodParameter methodParameter, 
	    							   MediaType mediaType, 
	    							   Class aClass, ServerHttpRequest serverHttpRequest, 
	    							   ServerHttpResponse serverHttpResponse) {
	        log.info("开始数据加密");
	        String jsonStr = JSON.toJSONString(o);
	        log.info("加密数据:{}", jsonStr);
	        /* 使用加密算法进行加密:
	         * RSA(非对称加密,公钥加密,私钥解密),
	         * AES(对称加密,加密解密同一个规则,采用4x4字节矩阵加密)
	         **/
	        String encryptStr = RSAUtils.encrypt(jsonStr,clientKey);
	        log.info("加密结果:{}", encryptStr);
	        return JSON.parseObject(encryptStr);
	    }
	}

//解密
@Slf4j
@RestControllerAdvice
public class ParamDecryptRequestBodyAdvice implements RequestBodyAdvice { 

    @Value("${private.clientKey}")
    private String clientKey;

    @Override
    public boolean supports(MethodParameter methodParameter, 
   							Type type, Class<? extends HttpMessageConverter<?>> aClass) {
   		//return false does not execute					
        return methodParameter.hasParameterAnnotation(
        						RequestBody.class) && 
        						methodParameter.hasMethodAnnotation(Encrypt.class);
    }

    @Override
    public HttpInputMessage beforeBodyRead(HttpInputMessage httpInputMessage,
    										MethodParameter methodParameter,
    										Type type,
    										Class<? extends HttpMessageConverter<?>> aClass) throws IOException {
        
        return new HttpInputMessage() {
            @Override
            public InputStream getBody() throws IOException {
                try {
                    String inputString = IOUtils.inputStream2String(httpInputMessage.getBody());
                    log.info("接收到解密请求:{}",inputString);
                    try{
                        JSONObject jsonObject = JSON.parseObject(inputString);
                        if(jsonObject.containsKey("requsetData")){
                            String encryptStr = jsonObject.getString("requsetData");
                            String decryptStr = RSAUtils.decrypt(encryptStr,clientKey); 
                        }
                    }catch (JSONException e){
                        log.error("解密出错,JSON解析异常:{}",e); 
                        e.printStackTrace();
                    }catch (ClassCastException e){
                        log.error("解密出错,JSON解析异常:{}",e); 
                        e.printStackTrace();
                    }
                }catch (IOException e){
                    log.error("解密出错:{}",e);
                    e.printStackTrace();
                }
                return httpInputMessage.getBody();
            }

            @Override
            public HttpHeaders getHeaders() {
                return httpInputMessage.getHeaders();
            }
        };
    }

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

    @Override
    public Object handleEmptyBody(Object o, 
    							  HttpInputMessage httpInputMessage, 
    							  MethodParameter methodParameter, 
    							  Type type, 
    							  Class<? extends HttpMessageConverter<?>> aClass) {
        return o;
    } 
}
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值