标签:map 通用 springboot 自定义 controller 处理器 HandlerMethodReturnValueHandler 返回值 public
一、返回值格式统一
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
本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享; 2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关; 3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关; 4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除; 5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。