微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

SpringBoot全局Controller返回值格式统一

本文主要介绍了SpringBoot全局Controller返回值格式统一,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

目录

一、返回值格式统一

1.返回值介绍

2.基础类功能

3.基础实现

二、附录说明

一、返回值格式统一

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:处理返回值基础参数

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处理器子类对返回值处理的过程替换为自定义处理器

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

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 returnValueHandlers = adapter.getReturnValueHandlers(); if (returnValueHandlers.size() > 0) { // 将内置的返回值处理器进行替换 List handlers = new ArrayList(returnValueHandlers); decorateHandlers(handlers); adapter.setReturnValueHandlers(handlers); } } /** * 将所有RequestResponseBodyMethodProcessor返回值处理器替换为自定义的返回值处理器 * * @author tianxincode@163.com * @since 2020/10/12 */ private void decorateHandlers(List 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 mapHandler(){ Map map = new HashMap(10); map.put("name", "map"); map.put("desc", "map返回值"); return map; } @RequestMapping("/list") public List listHandler(){ List 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返回值" }

别的方法测试一样

二、附录说明

项目结构参考红框部分,别的忽略

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

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐