使用spring-data-rest
时,会对从控制器返回的Resource
个类进行后处理(例如RepositoryRestControllers
)。在后期处理中调用正确的ResourceProcessor
。
负责此操作的班级是ResourceProcessorHandlerMethodReturnValueHandler
,它是spring-hateoas
的一部分。
我现在有一个仅使用spring-hateoas
的项目,我想知道如何在这种情况下配置ResourceProcessorHandlerMethodReturnValueHandler
。看起来它的自动配置部分仍然驻留在spring-data-rest
。
有关如何在ResourceProcessorHandlerMethodReturnValueHandler
上下文中启用spring-hateoas
的任何提示?
答案 0 :(得分:0)
我最近也一直在研究这个问题,而关于如何实现这一目标的文档不存在。如果创建类型为ResourceProcessorInvokingHandlerAdapter
的bean,则似乎会丢失自动配置的RequestMappingHandlerAdapter
及其所有功能。因此,我想避免使用此bean或丢失WebMvcAutoConfiguration
,因为我真正想要的只是ResourceProcessorHandlerMethodReturnValueHandler
。
您不能只通过ResourceProcessorHandlerMethodReturnValueHandler
添加WebMvcConfigurer.addReturnValueHandlers
,因为我们要做的实际上是覆盖整个列表,就像ResourceProcessorInvokingHandlerAdapter.afterPropertiesSet
中发生的一样:
@Override
public void afterPropertiesSet() {
super.afterPropertiesSet();
// Retrieve actual handlers to use as delegate
HandlerMethodReturnValueHandlerComposite oldHandlers = getReturnValueHandlersComposite();
// Set up ResourceProcessingHandlerMethodResolver to delegate to originally configured ones
List<HandlerMethodReturnValueHandler> newHandlers = new ArrayList<HandlerMethodReturnValueHandler>();
newHandlers.add(new ResourceProcessorHandlerMethodReturnValueHandler(oldHandlers, invoker));
// Configure the new handler to be used
this.setReturnValueHandlers(newHandlers);
}
因此,在没有更好的解决方案可用的情况下,我添加了BeanPostProcessor
来处理在现有RequestMappingHandlerAdapter
上设置处理程序列表的问题:
@Component
@RequiredArgsConstructor
@ConditionalOnBean(ResourceProcessor.class)
public class ResourceProcessorHandlerMethodReturnValueHandlerConfigurer implements BeanPostProcessor {
private final Collection<ResourceProcessor<?>> resourceProcessors;
@Override
public Object postProcessAfterInitialization(Object bean, String beanName)
throws BeansException {
if (bean instanceof RequestMappingHandlerAdapter) {
RequestMappingHandlerAdapter requestMappingHandlerAdapter = (RequestMappingHandlerAdapter) bean;
List<HandlerMethodReturnValueHandler> handlers =
requestMappingHandlerAdapter.getReturnValueHandlers();
HandlerMethodReturnValueHandlerComposite delegate =
handlers instanceof HandlerMethodReturnValueHandlerComposite ?
(HandlerMethodReturnValueHandlerComposite) handlers :
new HandlerMethodReturnValueHandlerComposite().addHandlers(handlers);
requestMappingHandlerAdapter.setReturnValueHandlers(Arrays.asList(
new ResourceProcessorHandlerMethodReturnValueHandler(delegate,
new ResourceProcessorInvoker(resourceProcessors))));
return requestMappingHandlerAdapter;
}
else return bean;
}
}
到目前为止,这似乎一直有效...