Spring MVC + DeferredResult添加Hateoas内容

Dam*_*ian 5 spring spring-mvc spring-hateoas

对于其余接口,Spring MVC + RxJava使用从控制器返回 + DeferredResult

我正在考虑将Hateoas支持添加到端点。自然的选择是Spring Hateoas。问题是春季Hateoas使用ThreadLocal,因此它不能在异步/多线程环境中工作。

有什么方法可以解决该约束?我不这么认为,但也许有人有任何建议。

有没有人使用其他API添加 其他端点 Hateoas支持?

谢谢。

And*_*cev 3

所以答案有点晚了,但可能有人会发现它有用。你对 ThreadLocal 的看法是正确的 - 如果你在不同的线程中生成 hatoas 链接,那么它会失败并出现异常。我找到了某种解决方法:

@RequestMapping(path = "/{id}", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
DeferredResult<ResponseEntity<ProductResource>> example(@PathVariable("id") final String productId, final HttpServletRequest request) {

    final DeferredResult<ResponseEntity<ProductResource>> deferredResult = new DeferredResult<>();

    request.setAttribute(WebUtils.INCLUDE_CONTEXT_PATH_ATTRIBUTE, request.getContextPath());
    final RequestAttributes requestAttributes = new ServletRequestAttributes(request);

    productByIdQuery.byId(UUID.fromString(productId)).subscribe(productEntity -> {
        RequestContextHolder.setRequestAttributes(requestAttributes);
            deferredResult.setResult(result, HttpStatus.OK))
    }, deferredResult::setErrorResult);

    return deferredResult;
}
Run Code Online (Sandbox Code Playgroud)

正如您所看到的,我保存了 RequestAttributes,以便稍后在回调中设置它们。这仅解决了问题的一部分 - 您将得到另一个异常,因为您将失去 contextPath 属性。为了避免这种情况,显式保存它:

request.setAttribute(WebUtils.INCLUDE_CONTEXT_PATH_ATTRIBUTE, request.getContextPath());
Run Code Online (Sandbox Code Playgroud)

经过这些更改后,一切似乎都正常,但当然看起来很混乱。我希望有人能提供更优雅的解决方案。