您好,登錄后才能下訂單哦!
這期內容當中小編將會給大家帶來有關SpringBoot中怎么統一全局Controller返回值格式,文章內容豐富且以專業的角度為大家分析和敘述,閱讀完這篇文章希望大家可以有所收獲。
在使用controller對外提供服務的時候,很多時候都需要統一返回值格式,例如
{ "status": true, "message": null, "code": "200", "data": { "name": "json", "desc": "json返回值" } }
如果不使用全局統一返回,就需要寫一個工具類,然后controller返回對應的對象
@Data public class ResponseData { private boolean status; private String message; private String code; private Object data; }
@RequestMapping("/foo") public ResponseData foo() { // 或者使用工具類返回,根據業務設置值 return new ResponseData(); }
除了上述方法,可以對返回值進行統一處理,不需要對所有controller都使用一個返回值,controller只需要返回原始值,處理器會對返回值進行封裝
同時也可以添加自定義注解,此注解用于忽略返回值封裝,按照controller原始值返回
org.springframework.web.method.support.HandlerMethodReturnValueHandler
使用不同策略處理從調用處理程序方法的返回值
策略處理頂層接口,自定義返回值格式需要實現此接口
supportsReturnType:設置支持返回值類型
handleReturnValue:處理返回值基礎參數
org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter
請求映射處理適配,包含了參數、返回值處理器等信息
HandlerMethodReturnValueHandlerComposite內部維護了HandlerMethodReturnValueHandler列表
可以自定義注解,用于類或者方法級別忽略返回值封裝
@Target({ElementType.TYPE, ElementType.METHOD}) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface IgnoreResponseWrapper { }
org.springframework.web.servlet.mvc.method.annotation.RequestResponseBodyMethodProcessor
屬于HandlerMethodReturnValueHandler子類
主要功能是對請求和響應體的做處理的方法
所有屬于RequestResponseBodyMethodProcessor的子類都需要替換為自定義返回值處理
實現原理就是,在bean初始化的時候,獲取到所有處理器數組,然后將所有是RequestResponseBodyMethodProcessor處理器子類對返回值處理的過程替換為自定義處理器
處理這樣當調用對應返回值處理器時,將會使用到自定義的返回值處理器,也就是所有返回值都會按照規定的進行處理
創建普通springboot項目,項目創建在此不做說明
創建類實現HandlerMethodReturnValueHandler接口,主要用于實現自定義返回值內容,不需要注入容器
import com.codecoord.unifyreturn.annotation.IgnoreResponseWrapper; import com.codecoord.unifyreturn.domain.ResponseBase; import org.springframework.core.MethodParameter; import org.springframework.web.context.request.NativeWebRequest; import org.springframework.web.method.support.HandlerMethodReturnValueHandler; import org.springframework.web.method.support.ModelAndViewContainer; public class ResponseBodyWrapHandler implements HandlerMethodReturnValueHandler { private final HandlerMethodReturnValueHandler delegate; public ResponseBodyWrapHandler(HandlerMethodReturnValueHandler delegate) { this.delegate = delegate; } @Override public boolean supportsReturnType(MethodParameter returnType) { return delegate.supportsReturnType(returnType); } @Override public void handleReturnValue(Object returnValue, MethodParameter returnType, ModelAndViewContainer mavContainer, NativeWebRequest webRequest) throws Exception { // 如果類或者方法含有不包裝注解則忽略包裝 IgnoreResponseWrapper wrapper = returnType.getDeclaringClass().getAnnotation(IgnoreResponseWrapper.class); if (wrapper != null) { delegate.handleReturnValue(returnValue, returnType, mavContainer, webRequest); return; } wrapper = returnType.getMethodAnnotation(IgnoreResponseWrapper.class); if (wrapper != null) { delegate.handleReturnValue(returnValue, returnType, mavContainer, webRequest); return; } // 自定義返回格式 ResponseBase responseBase = new ResponseBase(); responseBase.setStatus(true); responseBase.setCode("200"); responseBase.setData(returnValue); delegate.handleReturnValue(responseBase, returnType, mavContainer, webRequest); } }
創建類實現InitializingBean,在初始化時調用,需要注入到容器中,否則Spring無法管理
import java.util.ArrayList; import java.util.List; @Component public class ResponseBodyWrapFactoryBean implements InitializingBean { private final RequestMappingHandlerAdapter adapter; @Autowired public ResponseBodyWrapFactoryBean(RequestMappingHandlerAdapter adapter) { this.adapter = adapter; } @Override public void afterPropertiesSet() throws Exception { List<HandlerMethodReturnValueHandler> returnValueHandlers = adapter.getReturnValueHandlers(); if (returnValueHandlers.size() > 0) { // 將內置的返回值處理器進行替換 List<HandlerMethodReturnValueHandler> handlers = new ArrayList<>(returnValueHandlers); decorateHandlers(handlers); adapter.setReturnValueHandlers(handlers); } } /** * 將所有RequestResponseBodyMethodProcessor返回值處理器替換為自定義的返回值處理器 * * @author tianxincode@163.com * @since 2020/10/12 */ private void decorateHandlers(List<HandlerMethodReturnValueHandler> handlers) { for (HandlerMethodReturnValueHandler handler : handlers) { if (handler instanceof RequestResponseBodyMethodProcessor) { // 替換為自定義返回值處理器 ResponseBodyWrapHandler decorator = new ResponseBodyWrapHandler(handler); int index = handlers.indexOf(handler); handlers.set(index, decorator); break; } } } }
創建controller信息,例如此處map不需要封裝,按照原來格式響應
@RestController @RequestMapping("/unify") public class UnifyReturnValueController { @RequestMapping("string") public String stringHandler(){ return "接收成功了"; } @RequestMapping("/json") public JSONObject jsonHandler(){ JSONObject object = new JSONObject(); object.put("name", "json"); object.put("desc", "json返回值"); return object; } @RequestMapping("/map") @IgnoreResponseWrapper public Map<String, Object> mapHandler(){ Map<String, Object> map = new HashMap<>(10); map.put("name", "map"); map.put("desc", "map返回值"); return map; } @RequestMapping("/list") public List<Object> listHandler(){ List<Object> data = new ArrayList<>(); data.add(100); data.add(95); data.add(99); return data; } }
4.測試信息 測試json(有封裝)
{ "status": true, "message": null, "code": "200", "data": { "name": "json", "desc": "json返回值" } }
測試map(無封裝)
{ "name": "map", "desc": "map返回值" }
別的方法測試一樣
項目結構參考紅框部分,別的忽略
除了對返回值進行全局統一,也可以對異常進行全局處理和按照統一格式返回
上述就是小編為大家分享的SpringBoot中怎么統一全局Controller返回值格式了,如果剛好有類似的疑惑,不妨參照上述分析進行理解。如果想知道更多相關知識,歡迎關注億速云行業資訊頻道。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。