如何正確使用RequestBodyAdvice處理HTTP請求 – 一個全能開發工程師的技巧

一、什麼是RequestBodyAdvice

RequestBodyAdvice是Spring框架中的一個接口,我們可以在實現它的過程中對請求的body進行處理。實現這個接口可以讓我們在處理掉登錄信息之外的請求時候,為請求做一些統一的處理,比如日誌、加解密、甚至是自定義的轉換等操作。


public interface RequestBodyAdvice {
    boolean supports(MethodParameter var1, Type var2, Class<? extends HttpMessageConverter<?>> var3);

    Object handleEmptyBody(Object var1, HttpInputMessage var2, MethodParameter var3, Type var4, Class<? extends HttpMessageConverter<?>> var5);

    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);
}

二、如何使用RequestBodyAdvice

1. 創建一個實現RequestBodyAdvice接口的類

我們創建一個名為MyRequestBodyAdvice的類,並實現RequestBodyAdvice接口的所有方法。


@ControllerAdvice
public class MyRequestBodyAdvice implements RequestBodyAdvice {

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

    @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 {
        return httpInputMessage;
    }

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

2. 配置RequestBodyAdvice實例

在Spring Boot工程的application.properties文件中添加以下代碼,將MyRequestBodyAdvice類注入到Spring容器中。


spring.mvc.async.request-timeout=-1
spring.mvc.ignore-default-model-on-redirect=true
spring.mvc.view.prefix=/WEB-INF/jsp/
spring.mvc.view.suffix=.jsp

spring.mvc.argument-resolvers.order=1
spring.mvc.argument-resolvers.enabled=true
spring.mvc.argument-resolvers.cache.seconds=0

spring.mvc.converters.preferred-json-mapper=jackson

spring.mvc.requestbody.enabled=true
spring.mvc.requestbody.wrap-exceptions=true

spring.mvc.date-format=yyyy-MM-dd HH:mm:ss
spring.mvc.locale=zh_CN
spring.mvc.dispatch-trace-request=false

spring.mvc.throw-exception-if-no-handler-found=true

spring.mvc.view.prefix=/WEB-INF/jsp/
spring.mvc.view.suffix=.jsp

spring.mvc.add-application-context-header=true

spring.mvc.static-path-pattern=/static/**
spring.resources.static-locations=classpath:/static/

spring.http.encoding.charset=UTF-8
spring.http.encoding.force=true
spring.http.encoding.enabled=true

spring.http.multipart.enabled=true
spring.http.multipart.max-file-size=5MB
spring.http.multipart.max-request-size=10MB

spring.jackson.date-format=yyyy-MM-dd HH:mm:ss
spring.jackson.time-zone=GMT+8
spring.jackson.default-property-inclusion=NON_NULL
spring.jackson.deserialization.fail-on-unknown-properties=false

logging.level.root=warn

3. 添加自定義的轉換邏輯

我們可以在beforeBodyRead方法中,對請求體進行自定義轉換操作。


@Bean
public MappingJackson2HttpMessageConverter jsonConverter() {
    ObjectMapper objectMapper = new ObjectMapper();
    objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
    MappingJackson2HttpMessageConverter jsonConverter = new MappingJackson2HttpMessageConverter();
    jsonConverter.setObjectMapper(objectMapper);
    return jsonConverter;
}

@Override
public HttpInputMessage beforeBodyRead(HttpInputMessage httpInputMessage, MethodParameter methodParameter, Type type, Class<? extends HttpMessageConverter<?>> aClass) throws IOException {
    String body = IOUtils.toString(httpInputMessage.getBody(), StandardCharsets.UTF_8);
    Map<String, Object> map = new HashMap<>();
    map.put("data", JSONObject.parse(body));
    return new ServletServerHttpRequest(new MockHttpServletRequest(), new ServletInputStreamWrapper(JSONObject.toJSONBytes(map)), httpInputMessage.getHeaders());
}

三、使用RequestBodyAdvice的注意事項

1. 統一處理請求body可以有助於提高代碼復用率

通過實現RequestBodyAdvice接口,在處理請求body時,我們可以做一些統一的操作,例如加解密、自定義轉換、日誌、參數校驗等。這樣可以幫助我們提高代碼復用率,降低代碼量。

2. 一定要實現supports方法

在實現RequestBodyAdvice接口時,一定要實現supports方法,它用於判斷哪些請求需要處理,哪些不需要處理。如果不實現supports方法,會讓整個RequestBodyAdvice失效。

3. 小心處理異常

在處理請求body時,我們要小心處理異常,比如說請求body為空時,要處理掉這個異常。


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

本文對如何正確使用RequestBodyAdvice處理HTTP請求作了詳細闡述,主要包括RequestBodyAdvice的定義、如何使用RequestBodyAdvice和使用RequestBodyAdvice的注意事項。通過實現RequestBodyAdvice,我們可以統一處理請求body,提高代碼復用率,降低代碼量。

原創文章,作者:小藍,如若轉載,請註明出處:https://www.506064.com/zh-hant/n/289086.html

(0)
打賞 微信掃一掃 微信掃一掃 支付寶掃一掃 支付寶掃一掃
小藍的頭像小藍
上一篇 2024-12-24 03:01
下一篇 2024-12-24 03:01

相關推薦

發表回復

登錄後才能評論