SpringBoot 中如何自定义 HandlerMethodReturnValueHandler

Cat7373 发布于 2017/07/06 21:41
阅读 6K+
收藏 1

华为云11月刊推送:DIY微信问答机器人,高性能计算代码的20个技巧!>>>

我想在 SpringBoot 的项目中添加一个返回值处理器来处理有特定注解的请求方法。

然而不管我怎么加,我写的返回值处理器压根都没被执行(supportsReturnType 的断点没断下来过)

我现在是这么加的,然而并没有神马卵用:

@Configuration
public class MyConfig {
    @Bean
    public WebMvcConfigurerAdapter webMvcConfigurerAdapter() {
        return new WebMvcConfigurerAdapter() {
            @Override
            public void addReturnValueHandlers(List<HandlerMethodReturnValueHandler> returnValueHandlers) {
                returnValueHandlers.add(new MyReturnValueHandler());
            }
        };
    }
}

 

加载中
0
m
mysilence

亲,这个问题你找到答案了么,我这边配置貌似也一直不生效。。。。

m
mysilence
回复 @猫咪喵喵 : 嗯,谢谢,我是直接去掉了@ResponseBody注解,反正返回值都已经处理过了,不用它自带的转换也没事
Cat7373
Cat7373
没有优雅的解决方案,问题的根源在于自定义的处理器会排在最后面,所以只有默认的处理器全部失败才能轮到自己的 解决思路: 1. 不要标记 @ResponseBody 和 @ RestController 2. 利用反射把自己的处理器加到最前面(要依赖实现很不优雅) (在路上想回复来着。。结果不知道为啥 osc 的客户端发不出去评论,还损失了第一次写的内容 0.0)
0
djyotm
djyotm

参考:https://github.com/AndreasKl/spring-boot-mvc-completablefuture/blob/master/src/main/java/net/andreaskluth/WebMvcConfiguration.java

0
b
booter

filter没有生效是因为自定义的handler需要放到 HttpEntityMethodProcessor 之前,这样才可以,配置文件类参考代码如下:

@Configuration
public class CustomedWebConfig extends WebMvcConfigurationSupport {

  @Autowired
  private RequestMappingHandlerAdapter requestMappingHandlerAdapter;

  @Bean
  public HandlerMethodReturnValueHandler customedReturnValueHandler() {
    return new JsonReturnHandler();
  }

//  @PostConstruct
  public void init() {
    final List<HandlerMethodReturnValueHandler> originalHandlers = new ArrayList<>(
        requestMappingHandlerAdapter.getReturnValueHandlers());
    

//    final int deferredPos = obtainValueHandlerPosition(originalHandlers, DeferredResultMethodReturnValueHandler.class);
//    originalHandlers.add(deferredPos + 1, customedReturnValueHandler());
    
    // Add customed handler BEFORE the HttpEntityMethodProcessor to enable JsonReturnHandler !!
    final int deferredPos = obtainValueHandlerPosition(originalHandlers, HttpEntityMethodProcessor.class);
    originalHandlers.add(deferredPos - 1, customedReturnValueHandler());
    
    requestMappingHandlerAdapter.setReturnValueHandlers(originalHandlers);
    return;
  }

  private int obtainValueHandlerPosition(final List<HandlerMethodReturnValueHandler> originalHandlers, Class<?> handlerClass) {
    for (int i = 0; i < originalHandlers.size(); i++) {
      final HandlerMethodReturnValueHandler valueHandler = originalHandlers.get(i);
      if (handlerClass.isAssignableFrom(valueHandler.getClass())) {
        return i;
      }
    }
    return -1;
  }
}

Cat7373
Cat7373
首先很感谢你的帮助,这个原因我已经知道了,不过感觉反射处理不够优雅 \笑哭,现已换用 AOP 来处理这个问题
返回顶部
顶部