当@ResponseBody 为空时覆盖默认消息
Posted
技术标签:
【中文标题】当@ResponseBody 为空时覆盖默认消息【英文标题】:Override default message when @ResponseBody is null 【发布时间】: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 时,此方法处理错误。我试图让我自己的 CustomBodyMethodProcessor 从 RequestResponseBodyMethodProcessor 扩展,如下所示:
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));
但这不起作用。当我调试时,总是在 RequestResponseBodyMethodProcessor 的 readWithMessageConverters 方法中停止,而不是在 CustomBodyMethodProcessor
的我的覆盖方法中停止感谢您为我提供的任何帮助!
谢谢
【问题讨论】:
如果您在列表的前面添加您的 (resolvers.add(new …, 0);
) 会发生什么?或者在添加你的之前删除另一个 (resolvers.removeIf(i -> i instanceof RequestResponseBodyMethodProcessor);
)?
嗨! resolvers
为空,内部没有 RequestResponseBodyMethodProcessor
的实例。添加我的索引为 0 并且没有结果...谢谢!
你的回答@BeUndead 带我走上正确的道路...***.com/a/19847526/4267653
【参考方案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://***.com/a/19847526/4267653 和@BeUndead 提供线索!
【讨论】:
不知道它在这种情况下是否有效,但大多数 Spring 集合在类上支持implements Ordered
或 @Order
。所以你可以在你的自定义类上尝试@Order(Ordered.HIGHEST_PRECEDENCE)
,它可以在没有这一步的情况下工作。很高兴你让它工作了。以上是关于当@ResponseBody 为空时覆盖默认消息的主要内容,如果未能解决你的问题,请参考以下文章
当 ContentControl 的内容为空或为空时,在 ContentControl 中显示默认的 DataTemplate?