日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 前端技术 > javascript >内容正文

javascript

java 自定义注解 生成json_SpringBoot:自定义注解实现后台接收Json参数

發布時間:2023/12/19 javascript 20 豆豆
生活随笔 收集整理的這篇文章主要介紹了 java 自定义注解 生成json_SpringBoot:自定义注解实现后台接收Json参数 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

0.需求

在實際的開發過程中,服務間調用一般使用Json傳參的模式,SpringBoot項目無法使用@RequestParam接收Json傳參

只有@RequestBody支持Json,但是每次為了一個接口就封裝一次實體類比較麻煩

如果使用Map來進行參數接收,則會導致參數不可控,會在接口中新增較多判斷進行入參控制

其次,在實際的開發過程中,我們偶爾會傳入兩個實體類,如果使用@RequestBody也會出錯

因為傳入的參數只能夠讀取一次,一般這里也會封裝一次實體類,不夠方便

也有重寫HttpServletRequestWrapper的處理辦法,但不能解決上一個問題

1.思路

因為一個注解只能讀取一次,按照重寫HttpServletRequestWrapper的思路,將請求中的Json參數進行緩存

另外自定義一個注解,來把參數進行注入。

1.1.自定義@JsonFmt注解

import java.lang.annotation.*;

@Target(ElementType.PARAMETER)

@Retention(RetentionPolicy.RUNTIME)

@Documentedpublic @interfaceJsonFmt {/*** 值*/String value()default "";/*** 是否必須*/

boolean require() default true;

}

這里的值,不是給參數的默認值(defaultValue),而是類似于@RequestParam注解中的value、name,是用來指定入參的key

1.2.自定義注解的實現類

importcom.alibaba.fastjson.JSON;importcom.alibaba.fastjson.JSONObject;importcom.fasterxml.jackson.databind.ObjectMapper;importlombok.extern.slf4j.Slf4j;importorg.springframework.core.MethodParameter;importorg.springframework.util.StringUtils;importorg.springframework.web.bind.support.WebDataBinderFactory;importorg.springframework.web.context.request.NativeWebRequest;importorg.springframework.web.method.support.HandlerMethodArgumentResolver;importorg.springframework.web.method.support.ModelAndViewContainer;importjavax.servlet.http.HttpServletRequest;importjava.io.BufferedReader;importjava.util.HashMap;importjava.util.Map;

@Slf4jpublic class JsonFmtHandlerMethodArgumentResolver implementsHandlerMethodArgumentResolver {//自定義key

private static final String KEY = "TEST_JSON_BODY_KEY";private static ObjectMapper objectMapper = newObjectMapper();

@Overridepublic booleansupportsParameter(MethodParameter parameter) {return parameter.hasParameterAnnotation(JsonFmt.class);

}

@Overridepublic Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throwsException {

JsonFmt jsonFmt= parameter.getParameterAnnotation(JsonFmt.class);

JSONObject jsonObject=getJsonObject(webRequest);

String value=getParamName(parameter,jsonFmt);boolean require =jsonFmt.require();

Object paramValue=getParamValue(jsonObject,value);if (paramValue == null &&require) {throw new Exception("parameter[" + value + "]不能為空。");

}if (paramValue == null) {return null;

}

Class> classType =parameter.getParameterType();if (paramValue.getClass().equals(JSONObject.class)){

paramValue=objectMapper.readValue(paramValue.toString(),classType);

}returnparamValue;

}privateString getParamName(MethodParameter parameter, JsonFmt jsonFmt) {

String value=jsonFmt.value();if(StringUtils.isEmpty(value)) {

value=parameter.getParameterName();

}returnvalue;

}privateObject getParamValue(JSONObject jsonObject,String value) {for(String key: jsonObject.keySet()) {if(key.equalsIgnoreCase(value)){returnjsonObject.get(key);

}

}return null;

}private JSONObject getJsonObject(NativeWebRequest webRequest) throwsException {

String jsonBody=(String) webRequest.getAttribute(KEY, NativeWebRequest.SCOPE_REQUEST);if(StringUtils.isEmpty(jsonBody)){

HttpServletRequest request= webRequest.getNativeRequest(HttpServletRequest.class);

BufferedReader reader=request.getReader();

StringBuilder sb= newStringBuilder();char[] buf = new char[1024];intrd;while ((rd = reader.read(buf)) != -1) {

sb.append(buf,0, rd);

}

jsonBody=sb.toString();if(StringUtils.isEmpty(jsonBody)){

Map params =request.getParameterMap();

Map tmp= newHashMap();for (Map.Entryparam:params.entrySet()) {if(param.getValue().length == 1){

tmp.put(param.getKey(),param.getValue()[0]);

}else{

tmp.put(param.getKey(),param.getValue());

}

}

jsonBody=JSON.toJSONString(tmp);

}

webRequest.setAttribute(KEY, jsonBody, NativeWebRequest.SCOPE_REQUEST);

}returnJSONObject.parseObject(jsonBody);

}

}

方法說明:

supportsParameter:說明支持的注解,只要方法參數有@JsonFmt就啟用該實現類

resolveArgument:解決方法,注解的具體實現

getJsonObject:獲取請求體,這里的實現邏輯就是從請求中獲取Json體,如果沒有獲取到,則從請求參數中獲取(兼容From模式),將請求體封裝為JsonObject

getParamName:獲取注解參數的key,先獲取注解的value,如果為空,則使用方法參數的名稱

getParamValue:這個可以不加,我這里是為了讓key不區分大小寫,如果需要區分,直接使用jsonObject.get(key)即可

1.3.加入自定義注解

importcom.example.demo.jsonfmt.JsonFmtHandlerMethodArgumentResolver;importorg.springframework.context.annotation.Configuration;importorg.springframework.web.method.support.HandlerMethodArgumentResolver;importorg.springframework.web.servlet.config.annotation.WebMvcConfigurer;importjava.util.List;

@Configurationpublic class AppConfig implementsWebMvcConfigurer {

@Overridepublic void addArgumentResolvers(Listresolvers) {

resolvers.add(newJsonFmtHandlerMethodArgumentResolver());

}

}

2.使用

到這里我們就能愉快的使用我們的自定義注解@JsonFmt來進行參數接收了

目前在Json傳參中,能完美的接收實體類、List、Map以及其他基礎類型

在Form傳參中,能夠支持List、Map以及其他基礎類型,對于實體類暫時還不能兼容

因為后臺接收到的是Map,不容易區分哪些是實體類的字段,無法進行填充,這種建議使用@RequestBody

總結

以上是生活随笔為你收集整理的java 自定义注解 生成json_SpringBoot:自定义注解实现后台接收Json参数的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。