温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

SpringBoot中怎么统一全局Controller返回值格式

发布时间:2021-07-31 08:17:20 来源:亿速云 阅读:868 作者:Leah 栏目:开发技术

这期内容当中小编将会给大家带来有关SpringBoot中怎么统一全局Controller返回值格式,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。


一、返回值格式统一

1.返回值介绍

在使用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原始值返回

2.基础类功能

org.springframework.web.method.support.HandlerMethodReturnValueHandler

  • 使用不同策略处理从调用处理程序方法的返回值

  • 策略处理顶层接口,自定义返回值格式需要实现此接口

  • supportsReturnType:设置支持返回值类型

  • handleReturnValue:处理返回值基础参数

SpringBoot中怎么统一全局Controller返回值格式

org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter

  • 请求映射处理适配,包含了参数、返回值处理器等信息

  • HandlerMethodReturnValueHandlerComposite内部维护了HandlerMethodReturnValueHandler列表

SpringBoot中怎么统一全局Controller返回值格式SpringBoot中怎么统一全局Controller返回值格式

可以自定义注解,用于类或者方法级别忽略返回值封装

@Target({ElementType.TYPE, ElementType.METHOD}) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface IgnoreResponseWrapper { }

org.springframework.web.servlet.mvc.method.annotation.RequestResponseBodyMethodProcessor

  • 属于HandlerMethodReturnValueHandler子类

  • 主要功能是对请求和响应体的做处理的方法

  • 所有属于RequestResponseBodyMethodProcessor的子类都需要替换为自定义返回值处理

实现原理就是,在bean初始化的时候,获取到所有处理器数组,然后将所有是RequestResponseBodyMethodProcessor处理器子类对返回值处理的过程替换为自定义处理器

处理这样当调用对应返回值处理器时,将会使用到自定义的返回值处理器,也就是所有返回值都会按照规定的进行处理

3.基础实现

创建普通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返回值格式

除了对返回值进行全局统一,也可以对异常进行全局处理和按照统一格式返回

上述就是小编为大家分享的SpringBoot中怎么统一全局Controller返回值格式了,如果刚好有类似的疑惑,不妨参照上述分析进行理解。如果想知道更多相关知识,欢迎关注亿速云行业资讯频道。

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI