springboot通用controller处理
作者:互联网
一、返回值格式统一
1.返回值介绍
在使用controller对外提供服务的时候,很多时候都需要统一返回值格式,例如
1 2 3 4 5 6 7 8 9 |
{
"status" : true ,
"message" : null ,
"code" : "200" ,
"data" : {
"name" : "json" ,
"desc" : "json返回值"
}
}
|
如果不使用全局统一返回,就需要写一个工具类,然后controller返回对应的对象
1 2 3 4 5 6 7 |
@Data
public class ResponseData {
private boolean status;
private String message;
private String code;
private Object data;
}
|
1 2 3 4 5 |
@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列表
可以自定义注解,用于类或者方法级别忽略返回值封装
1 2 3 4 5 6 |
@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接口,主要用于实现自定义返回值内容,不需要注入容器
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 |
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无法管理
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 |
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不需要封装,按照原来格式响应
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
@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(有封装)
1 2 3 4 5 6 7 8 9 |
{
"status" : true ,
"message" : null ,
"code" : "200" ,
"data" : {
"name" : "json" ,
"desc" : "json返回值"
}
}
|
测试map(无封装)
1 2 3 4 |
{
"name" : "map" ,
"desc" : "map返回值"
}
|
别的方法测试一样
二、附录说明
项目结构参考红框部分,别的忽略
标签:map,通用,springboot,自定义,controller,处理器,HandlerMethodReturnValueHandler,返回值,public 来源: https://www.cnblogs.com/cj8357475/p/16671715.html