【问题标题】:Override default message when @ResponseBody is null当@ResponseBody 为空时覆盖默认消息
【发布时间】:2021-08-17 02:44:44
【问题描述】:

我想从这个 Spring 类中覆盖这个行为:

public class RequestResponseBodyMethodProcessor extends AbstractMessageConverterMethodProcessor {
    ...
    @Override
    protected <T> Object readWithMessageConverters(NativeWebRequest webRequest, MethodParameter parameter,
            Type paramType) throws IOException, HttpMediaTypeNotSupportedException, HttpMessageNotReadableException {
            ...
            if (arg == null && checkRequired(parameter)) {
                throw new HttpMessageNotReadableException("Required request body is missing: " +
                    parameter.getExecutable().toGenericString(), inputMessage);
            }
    ...
}

当@ReponseBody 来自@Controller 时,此方法处理错误。我试图让我自己的 CustomBodyMethodProcessorRequestResponseBodyMethodProcessor 扩展,如下所示:

public class CustomBodyMethodProcessor extends RequestResponseBodyMethodProcessor {

    public CustomBodyMethodProcessor(List<HttpMessageConverter<?>> converters) {
        super(converters);
    }

    @Override
    protected <T> Object readWithMessageConverters(NativeWebRequest webRequest, MethodParameter parameter,
                                                   Type paramType) throws IOException, HttpMediaTypeNotSupportedException, HttpMessageNotReadableException {

        HttpServletRequest servletRequest = webRequest.getNativeRequest(HttpServletRequest.class);
        Assert.state(servletRequest != null, "No HttpServletRequest");
        ServletServerHttpRequest inputMessage = new ServletServerHttpRequest(servletRequest);

        Object arg = readWithMessageConverters(inputMessage, parameter, paramType);
        if (arg == null && checkRequired(parameter)) {
            //I want to change this....
            throw new HttpMessageNotReadableException("Required request body is missing: " +
                    parameter.getExecutable().toGenericString(), inputMessage);
        }
        return arg;
    }

}

所以,添加新的 CustomBodyMethodProcessor 我做了:

@Configuration
@EnableWebMvc
public class WebMvcConfig implements  WebMvcConfigurer {

    @Autowired
    List<HttpMessageConverter<?>> converters;


    @Override
    public void addArgumentResolvers(List<HandlerMethodArgumentResolver> resolvers) {
        WebMvcConfigurer.super.addArgumentResolvers(resolvers);
        resolvers.add(new CustomBodyMethodProcessor(converters));

    }

}

但这不起作用。当我调试时,总是在 RequestResponseBodyMethodProcessorreadWithMessageConverters 方法中停止,而不是在 CustomBodyMethodProcessor

的我的覆盖方法中停止

感谢您为我提供的任何帮助!

谢谢

【问题讨论】:

  • 如果您在列表的前面添加您的 (resolvers.add(new …, 0);) 会发生什么?或者在添加你的之前删除另一个 (resolvers.removeIf(i -&gt; i instanceof RequestResponseBodyMethodProcessor);)?
  • 嗨! resolvers 为空,内部没有 RequestResponseBodyMethodProcessor 的实例。添加我的索引为 0 并且没有结果...谢谢!
  • 你的回答@BeUndead 带我走上正确的道路...stackoverflow.com/a/19847526/4267653

标签: java spring-boot spring-mvc


【解决方案1】:

找到了解决办法。

    @Autowired
    private RequestMappingHandlerAdapter adapter;

    @PostConstruct
    public void prioritizeCustomArgumentMethodHandlers () {
        List<HandlerMethodArgumentResolver> argumentResolvers = new ArrayList<>(adapter.getArgumentResolvers ());
        List<HandlerMethodArgumentResolver> customResolvers = adapter.getCustomArgumentResolvers();
        argumentResolvers.removeAll(customResolvers);
        argumentResolvers.addAll (0, customResolvers);
        adapter.setArgumentResolvers (argumentResolvers);
    }

我的 CustomBodyMethodProcessor 已添加到解析器列表中,但原始 RequestResponseBodyMethodProcessor 具有优先权,因此永远不会调用 CustomBodyMethodProcessor

解决方案是从解析器中删除我的 CustomBodyMethodProcessor,给予优先权并再次将其添加到列表中!

感谢https://stackoverflow.com/a/19847526/4267653@BeUndead 提供线索!

【讨论】:

  • 不知道它在这种情况下是否有效,但大多数 Spring 集合在类上支持 implements Ordered@Order。所以你可以在你的自定义类上尝试@Order(Ordered.HIGHEST_PRECEDENCE),它可以在没有这一步的情况下工作。很高兴你让它工作了。
猜你喜欢
  • 2020-01-17
  • 2014-04-04
  • 2014-03-05
  • 1970-01-01
  • 2011-02-25
  • 2014-06-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多