SpringBoot全局Controller返回值格式统一

网友投稿 1138 2022-12-23

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只需要返回原始值,处理器会对返回值进行封装

同时也可http://以添加自定义注解,此注解用于忽略返回值封装,按照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.springframhttp://ework.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返回值"

}

别的方法测试一样

二、附录说明

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

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

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:vue3 前端框架(vue框架后端)
下一篇:智能车载终端招投标网址(全国电子招投标平台)
相关文章

 发表评论

暂时没有评论,来抢沙发吧~