最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

自定義@RequestBody注解如何獲取JSON數(shù)據(jù)

 更新時間:2023年04月10日 14:23:42   作者:明淵陶向反01  
這篇文章主要介紹了自定義@RequestBody注解如何獲取JSON數(shù)據(jù)問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教

Spring MVC 的 @RequestBody 注解只能將請求體中的 JSON 數(shù)據(jù)封裝成 Bean,而無法對單一字段實施管理(例如 required、name 等屬性),這篇文章記錄了我的自定義注解 @JsonArg。

自定義注解

首先思考,我們需要這個注解做什么?

  • 設置該字段的必選性(required)
  • 設置該字段在請求體 JSON 中的 key 值(name、value)
  • 設置該字段的默認值(defaultValue)

于是我們的注解類 @JsonArg 至少應該長這樣:

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.PARAMETER)
public @interface JsonArg {
? ? @AliasFor("name")
? ? String value() default "";

? ? @AliasFor("value")
? ? String name() default "";

? ? boolean required() default true;

? ? String defaultValue() default ValueConstants.DEFAULT_NONE;
}

其中:

  • @Retention(RetentionPolicy.RUNTIME) 聲明我們需要在運行期動態(tài)地獲取它地信息
  • @Target(ElementType.PARAMETER) 聲明這個注解只能作用在方法參數(shù)

是的,它和 Spring MVC 自帶的 @RequestParam 注解非常像,但 @RequestParam 只能作用于 query parameters 和 form data。

自定義解析器

單純的定義注解類程序是無法知道我們要它做什么的,所以我們要告訴程序在遇到這個注解時該做什么。

public class JsonArgMethodArgumentResolver extends AbstractNamedValueMethodArgumentResolver {
? ? /**
? ? ?* 表示關于 namedValue 的信息,包括名稱、是否需要它以及默認值。
? ? ?*
? ? ?* @param parameter 待處理的方法參數(shù)
? ? ?* @return {@link JsonArgNamedValueInfo}
? ? ?*/
? ? @Override
? ? protected NamedValueInfo createNamedValueInfo(MethodParameter parameter) {
? ? ? ? JsonArg ann = parameter.getParameterAnnotation(JsonArg.class);
? ? ? ? return (ann != null ? new JsonArgNamedValueInfo(ann) : new JsonArgNamedValueInfo());
? ? }

? ? /**
? ? ?* 解析方法
? ? ?*
? ? ?* @param name ? ? ?待解析的 JSON 的 key
? ? ?* @param parameter 待處理的方法參數(shù)
? ? ?* @return 解析出來的值
? ? ?*/
? ? @Override
? ? protected Object resolveName(String name, MethodParameter parameter, NativeWebRequest request) throws Exception {
? ? ? ? ContentCachingRequestWrapper contentCachingRequestWrapper = request.getNativeRequest(ContentCachingRequestWrapper.class);
? ? ? ? String body;
? ? ? ? assert contentCachingRequestWrapper != null;
? ? ? ? byte[] contentAsByteArray = contentCachingRequestWrapper.getContentAsByteArray();
? ? ? ? if (contentAsByteArray.length == 0) {
? ? ? ? ? ? try (BufferedReader reader = contentCachingRequestWrapper.getReader()) {
? ? ? ? ? ? ? ? body = reader.lines().collect(Collectors.joining(""));
? ? ? ? ? ? }
? ? ? ? } else {
? ? ? ? ? ? body = new String(contentAsByteArray);
? ? ? ? }
? ? ? ? return JSONObject.parseObject(body).get(name);
? ? }

? ? /**
? ? ?* 是否支持該方法參數(shù)
? ? ?*
? ? ?* @param parameter 待處理的方法參數(shù)
? ? ?*/
? ? @Override
? ? public boolean supportsParameter(MethodParameter parameter) {
? ? ? ? return true;
? ? }

? ? private static class JsonArgNamedValueInfo extends NamedValueInfo {
? ? ? ? public JsonArgNamedValueInfo() {
? ? ? ? ? ? super("", false, ValueConstants.DEFAULT_NONE);
? ? ? ? }

? ? ? ? public JsonArgNamedValueInfo(JsonArg annotation) {
? ? ? ? ? ? super(annotation.name(), annotation.required(), annotation.defaultValue());
? ? ? ? }
? ? }
}

注意到在 resolveName() 方法中我們獲取的 request 類型是 ContentCachingRequestWrapper。

這是因為默認的 request 只能讀取一次請求體,而我們的解析器在解析每個方法參數(shù)時都需要讀取一次請求體。

包裝請求

添加過濾器將我們的請求轉換為所需要的 ContentCachingRequestWrapper。

/*
? ? 將request包裝成ContentCachingRequest,以反復讀取請求體
?*/
@Component
public class CachingRequestBodyFilter extends GenericFilterBean {
? ? @Override
? ? public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
? ? ? ? if (servletRequest instanceof HttpServletRequest) {
? ? ? ? ? ? filterChain.doFilter(new ContentCachingRequestWrapper((HttpServletRequest) servletRequest), servletResponse);
? ? ? ? } else {
? ? ? ? ? ? filterChain.doFilter(servletRequest, servletResponse);
? ? ? ? }
? ? }
}

注冊解析器

最后,將自定義的解析器注冊到 Spring MVC。

@Configuration
public class SpringMvcConfig implements WebMvcConfigurer {
? ? @Override
? ? public void addArgumentResolvers(List<HandlerMethodArgumentResolver> resolvers) {
? ? ? ? resolvers.add(new JsonArgMethodArgumentResolver());
? ? }
}

用法

和 @RequestParam 的用法相似。

public CommonResult<Object> signUp(
? ? ? ? ? ? @JsonArg(name = "uname") String username,
? ? ? ? ? ? @JsonArg(required = false, name = "pwd", defaultValue = "123") String password
? ? ) {
? ? ? ? log.info("[Username]: {}, [Password]: {}", username, password);
? ? ? ? return null;
}

總結

大功告成!

以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。

相關文章

  • Java 非阻塞I/O使用方法

    Java 非阻塞I/O使用方法

    這篇文章主要介紹了Java 非阻塞I/O使用方法,文中涉及非阻塞I/O的簡介,同時向大家展示了利用非阻塞I/O實現(xiàn)客戶端的方法,需要的朋友可以參考下。
    2017-09-09
  • Java字符串排序的幾種實現(xiàn)方式

    Java字符串排序的幾種實現(xiàn)方式

    這篇文章主要給大家介紹了關于Java字符串排序的幾種實現(xiàn)方式, 使用Java平臺進行字符串排序被認為是一件簡單的工作,文中通過實例代碼介紹的非常詳細,需要的朋友可以參考下
    2023-07-07
  • Java使用Collections工具類對List集合進行排序

    Java使用Collections工具類對List集合進行排序

    這篇文章主要介紹了Java使用Collections工具類對List集合進行排序,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2019-10-10
  • 舉例講解Java設計模式中的對象池模式編程

    舉例講解Java設計模式中的對象池模式編程

    這篇文章主要介紹了Java設計模式中的對象池模式編程示例分享,對象池模式經(jīng)常在多線程開發(fā)時被用到,需要的朋友可以參考下
    2016-02-02
  • 解析ConcurrentHashMap: put方法源碼分析

    解析ConcurrentHashMap: put方法源碼分析

    ConcurrentHashMap是由Segment數(shù)組結構和HashEntry數(shù)組結構組成。Segment的結構和HashMap類似,是一種數(shù)組和鏈表結構,今天給大家普及java面試常見問題---ConcurrentHashMap知識,一起看看吧
    2021-06-06
  • 淺談異常結構圖、編譯期異常和運行期異常的區(qū)別

    淺談異常結構圖、編譯期異常和運行期異常的區(qū)別

    下面小編就為大家?guī)硪黄獪\談異常結構圖、編譯期異常和運行期異常的區(qū)別。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2016-09-09
  • Redis原子計數(shù)器incr,防止并發(fā)請求操作

    Redis原子計數(shù)器incr,防止并發(fā)請求操作

    這篇文章主要介紹了Redis原子計數(shù)器incr,防止并發(fā)請求操作,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-11-11
  • SpringBoot整合redis中的JSON序列化文件夾操作小結

    SpringBoot整合redis中的JSON序列化文件夾操作小結

    在我們?nèi)粘5捻椖块_發(fā)中,使用redis作為緩存,來提高系統(tǒng)訪問速度和緩解系統(tǒng)壓力,在使用中遇到幾個問題,本文給大家詳細總結下,對SpringBoot整合redis?JSON序列化相關知識感興趣的朋友一起看看吧
    2022-02-02
  • java技巧:反射判斷field類型的操作

    java技巧:反射判斷field類型的操作

    這篇文章主要介紹了java技巧:反射判斷field類型的操作,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-05-05
  • spring scheduled單線程和多線程使用過程中的大坑

    spring scheduled單線程和多線程使用過程中的大坑

    本文主要介紹了spring scheduled單線程和多線程使用過程中的大坑,文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-01-01

最新評論

彰化县| 正阳县| 平定县| 阳新县| 钟祥市| 阜阳市| 金乡县| 蒲江县| 新化县| 大丰市| 麦盖提县| 龙川县| 青阳县| 崇义县| 新余市| 东宁县| 沐川县| 汪清县| 东源县| 四子王旗| 泸定县| 黎川县| 邻水| 赣州市| 永平县| 黄山市| 彭阳县| 萍乡市| 深圳市| 务川| 松江区| 英山县| 安平县| 虎林市| 榆树市| 新余市| 枝江市| 安化县| 万安县| 浦城县| 清流县|