SpringBoot对请求体和响应体进行处理

本文共 4,535 字,预计阅读时间 15 分钟

 


有时需要对请求或返回的数据进行加密,那么SpringBoot就提供了支持,可对请求体进行处理,也可对响应体进行处理。

1.对请求体处理

对响应体进行处理,需要实现RequestBodyAdvice接口,重写方法。

复制代码
package com.zys.example.config;

import lombok.extern.slf4j.Slf4j;
import org.springframework.core.MethodParameter;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpInputMessage;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.servlet.mvc.method.annotation.RequestBodyAdvice;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Type;
import java.nio.charset.StandardCharsets;

@Component
@ControllerAdvice
@Slf4j
public class DecodeRequestBodyAdvice implements RequestBodyAdvice {


    @Override
    public boolean supports(MethodParameter methodParameter, Type type, Class<? extends HttpMessageConverter<?>> aClass) {
        return true;
    }

    @Override
    public HttpInputMessage beforeBodyRead(HttpInputMessage httpInputMessage, MethodParameter methodParameter, Type type, Class<? extends HttpMessageConverter<?>> aClass) {
        //获取请求头信息
        String header = httpInputMessage.getHeaders().getFirst("header");
        log.info("获取的请求头header:{}", header);
        String body = null;
        try {
            // 从流中提取数据
            InputStream is = httpInputMessage.getBody();
            byte[] data = new byte[is.available()];
            is.read(data);
            body = new String(data, StandardCharsets.UTF_8);
            log.info("请求的数据,{}", body);
            //对数据进行处理 
        } catch (IOException e) {
            e.printStackTrace();
        }
        return new DecodedHttpInputMessage(httpInputMessage.getHeaders(), new ByteArrayInputStream(body.getBytes(StandardCharsets.UTF_8)));
    }

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

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

    static class DecodedHttpInputMessage implements HttpInputMessage {
        HttpHeaders headers;
        InputStream body;

        public DecodedHttpInputMessage(HttpHeaders headers, InputStream body) {
            this.headers = headers;
            this.body = body;
        }

        @Override
        public InputStream getBody() {
            return body;
        }

        @Override
        public HttpHeaders getHeaders() {
            return headers;
        }
    }
}
复制代码

 需要注意是,其仅针对@RequestBody注解生效,也就是说要必须是POST请求,使用@RequestBody注解接收,才能执行上述的操作。否则不生效,如下:

复制代码
@RestController
public class TestController {

    @PostMapping("/test")
    public JSONObject get(@RequestBody JSONObject json) {
        return json;
    }
}
复制代码

 使用了@ControllerAdvice,若不指定值,则会对所有的请求进行拦截并解密。若只对特定的接口进行拦截解密,则使用数组指定接口即可:

@ControllerAdvice({"/test"})

2.对响应体处理

对响应体进行处理,需要新建类,实现ResponseBodyAdvice接口,重写方法。

复制代码
package com.zys.example.config;

import lombok.extern.slf4j.Slf4j;
import org.springframework.core.MethodParameter;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;

@Component
@ControllerAdvice
@Slf4j
public class EncodeResponseBodyAdvice implements ResponseBodyAdvice<Object> {

    @Override
    public boolean supports(MethodParameter methodParameter, Class<? extends HttpMessageConverter<?>> aClass) {
        //若返回false则下面的配置不生效
        return true;
    }

    @Override
    public Object beforeBodyWrite(Object body, MethodParameter methodParameter, MediaType mediaType, Class<? extends HttpMessageConverter<?>> aClass, ServerHttpRequest serverHttpRequest, ServerHttpResponse serverHttpResponse) {
        //获取请求头信息,需要时获取
        String header = serverHttpRequest.getHeaders().getFirst("header");
        log.info("获取的请求头header:{}",header);
        //body即是返回的数据,可对其进行处理后返回,如加密
        return body;
    }
}
复制代码

 

posted @   钟小嘿  阅读(1972)  评论(0编辑  收藏  举报
编辑推荐:
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
阅读排行:
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!
历史上的今天:
2020-10-19 Java8新特性
点击右上角即可分享
微信分享提示