【问题标题】:How to enable HAL rendering without using @EnableHypermediaSupport with spring hateoas?如何在不使用 @EnableHypermediaSupport 和 spring hateoas 的情况下启用 HAL 渲染?
【发布时间】:2014-01-10 09:48:52
【问题描述】:

借助@EnableHypermediaSupport(type = HypermediaType.HAL)Spring hateoas 提供了一种简单方便的方式来启用 HAL 渲染。

注释触发了一些配置魔法,这里解释: https://github.com/spring-projects/spring-hateoas#enablehypermediasupport

但是,如果您正在开发一个给定的基于 xml-config 的 Spring 应用程序,那么集成 @EnableHypermediaSupport 并不容易。我尝试了很多不同的方法来启用 HAL 渲染,但没有一个解决方案能够正常工作:

  • 在现有的 mvc servlet xml 配置中包含一个配置类。
  • 使用不同版本的 spring hateos (0.70.0, 0.80.0, 0.9.0.BUILD-SNAPSHOT),希望 0.90.0 会产生开箱即用的 HAL,因为根据 jira 问题,它应该成为默认渲染(至少对于 spring data rest)。
  • 使用自定义MappingJackson2HttpMessageConverter 注册new Jackson2HalModule() 也不起作用。尽管转换器用于渲染(例如渲染日期),但输出并未在 HAL 中渲染。

因此我的问题是:如何在不使用 EnableHypermediaSupport 的情况下启用 HAL 渲染?

我故意省略了任何代码 sn-ps,因为我认为它不会有太大帮助。

【问题讨论】:

  • 添加一个用@EnableHypermediaSupport注解的类有什么问题?
  • 只要这是唯一的 mvc 设置,它就可以工作。但是在 mvc-servlet.xml 中有一个 元素。根据所使用的 hateoas 版本,我们要么得到一个异常,要么无法刷新上下文,要么链接不再呈现 HAL。它们以默认的弹簧方式呈现。
  • 它对我有用。我使用版本 0.8.0.RELEASE
  • 乍一看还不错。但在细节上,它的表现有所不同。例如:如果您省略接受标头、使用 applicatim/json 或使用 application/hal+json,则仅使用 java 配置的解决方案会返回 HAL。包含配置类的解决方案不适用于 application/json。另一个问题是,使用 0.80.0 RELEASE,我们的可分页资源结果包含错误数量的嵌入式资源。例如,我们有一个资源 users,虽然 pagesize 设置为 4 并且存在 10 个用户,但只返回了两个用户。
  • 自 0.9.0 版发布以来对此有何更新?

标签: java spring spring-mvc hateoas spring-hateoas


【解决方案1】:

基于@WaldemarSchneider answer,这里有一个具体的操作方法:

创建一个 HTTP 消息转换器:

public class HalHttpMessageConverter extends AbstractJackson2HttpMessageConverter {

  public HalHttpMessageConverter() {
    super(new ObjectMapper(), new MediaType("application", "hal+json", DEFAULT_CHARSET));
    objectMapper.registerModule(new Jackson2HalModule());
    objectMapper.setHandlerInstantiator(new Jackson2HalModule.HalHandlerInstantiator(new DefaultRelProvider(), null));
    // customize your mapper if needed
    objectMapper.enable(SerializationFeature.INDENT_OUTPUT);
  }

  @Override
  protected boolean supports(Class<?> clazz) {
    return ResourceSupport.class.isAssignableFrom(clazz);
  }

}

在您的 servlet 上下文中注册它:

<mvc:annotation-driven>
  <mvc:message-converters>
    <bean class="package.to.HalHttpMessageConverter" />
  </mvc:message-converters>
</mvc:annotation-driven>

别忘了让你的休息控制器产生application/hal+json

@RestController
@RequestMapping(value = "/articles", produces = "application/hal+json")
public class ArticleRestController {
  ...
}

【讨论】:

    【解决方案2】:

    也许这个问题有点老了,但我想为以下用户提供我的解决方案。

    我有类似的情况(Spring MVC 3.2.10.RELEASE,Spring HATEAOS 0.16.0.RELEASE)来配置 spring hatoas 以使用超媒体而无需 java 配置。

    我的解决方案如下:

    创建一个自定义的 HalJacksonHttpMessageConverter(其作用类似于 Spring MVC 标准 MappingJacksonHttpMessageConverter,它还必须有一个公开 ObjectMapper 的方法),但将 application/hal+json 注册为支持的超媒体类型。如果给定的类可从 ResourceSupport 分配,则 supports 方法应返回 true。

    在您的 xml 配置中创建一个 RelProvider(在这种情况下 DefaultRelProvider 满足了我的需求)。

    我创建了一个 BeanPostProcessorBean(实现的接口:BeanPostProcessor 和 BeanFactoryAware)。 使用以下设置从我的 HalJachsonHttpMessageConverter 丰富现有的 ObjectMapper:

    // retrieve the object mapper from the messageConverter
    RelProvider provider = beanFactory.getBean("relProvider", RelProvider.class);
    ObjectMapper mapper = (ObjectMapper) objectMapper;
    mapper.registerModule(new Jackson2HalModule());
    mapper.setHandlerInstantiator(new Jackson2HalModule.HalHandlerInstantiator(provider, null));
    mapper.enable(SerializationFeature.INDENT_OUTPUT);
    

    在你的 spring bean xml 中注册这些 bean。 我希望这有帮助。如果有人有更好的配置方法,请告诉我。

    【讨论】:

    • 感谢您在此处添加,对我的媒体类型有一个想法
    猜你喜欢
    • 2016-05-26
    • 1970-01-01
    • 1970-01-01
    • 2017-03-14
    • 1970-01-01
    • 2016-06-13
    • 2020-11-17
    • 2017-12-17
    • 1970-01-01
    相关资源
    最近更新 更多