如何配置 MappingJackson2HttpMessageConverter 由 spring-hateoas 注册

2022-09-03 08:11:03

我喜欢在我的项目中使用spring-hateoas,并用.现在的问题是,这个神奇的配置注释注册了自己的,我自己的自定义转换器将被忽略。@EnableHypermediaSupportMappingJackson2HttpMessageConverter

背景:我向我的项目添加了一些 Jackson 模块(如 ),我希望它们使用 注册。这是通过在 或 中重写来完成的。JodaModuleobjectMapper.findAndRegisterModules();configureMessageConverters(List<HttpMessageConverter<?>> converters)WebMvcConfigurationSupportWebMvcConfigurer

我当前的配置如下所示:

@Configuration
@EnableHypermediaSupport(type = HAL)
public class WebMvcConfiguration extends WebMvcConfigurationSupport {

  @Override
  protected void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
    final MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();
    converter.getObjectMapper().findAndRegisterModules();

    converters.add(converter);
  }
}

有没有办法自定义弹簧仇恨使用的或使用的方法?MappingJackson2HttpMessageConverterObjectMapper


答案 1

我必须做同样的事情。使用HATEOAS .16,我能够做到这一点。但真的真的很丑。

关键是,在HypermediaSupportBeanDefinitionRegistrar中,注册HAL转换器的部分在尝试添加另一个HAL转换器之前会检查是否已经存在HAL转换器。所以我只是在我的WebMVCConfig::configureMessageConverters中添加了一个HAL转换器。

像这样:

private static final String DELEGATING_REL_PROVIDER_BEAN_NAME = "_relProvider";
private static final String LINK_DISCOVERER_REGISTRY_BEAN_NAME = "_linkDiscovererRegistry";
private static final String HAL_OBJECT_MAPPER_BEAN_NAME = "_halObjectMapper";

@Autowired
private ListableBeanFactory beanFactory;

private static CurieProvider getCurieProvider(BeanFactory factory) {

    try {
        return factory.getBean(CurieProvider.class);
    } catch (NoSuchBeanDefinitionException e) {
        return null;
    }
}

@Override
    public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
        List<HttpMessageConverter<?>> baseConverters = new ArrayList<HttpMessageConverter<?>>();
        super.configureMessageConverters(baseConverters);

        //Need to override some behaviour in the HAL Serializer...so let's make our own
        CurieProvider curieProvider = getCurieProvider(beanFactory);
        RelProvider relProvider = beanFactory.getBean(DELEGATING_REL_PROVIDER_BEAN_NAME, RelProvider.class);
        ObjectMapper halObjectMapper = beanFactory.getBean(HAL_OBJECT_MAPPER_BEAN_NAME, ObjectMapper.class);

        halObjectMapper.registerModule(new Jackson2HalModule());
        halObjectMapper.setHandlerInstantiator(new Jackson2HalModule.HalHandlerInstantiator(relProvider, curieProvider));

        MappingJackson2HttpMessageConverter halConverter = new TypeConstrainedMappingJackson2HttpMessageConverter(
            ResourceSupport.class);
        halConverter.setSupportedMediaTypes(Arrays.asList(HAL_JSON));
        halConverter.setObjectMapper(halObjectMapper);

        converters.add(halConverter);
    }

这显然是依赖于实现的,使用实现细节,并且真的不允许您修改@EnableHyperMediaSupport为您构建的那个。但它现在有效。


答案 2

我使用以下方法

@Configuration
@EnableHypermediaSupport(type = HypermediaType.HAL)
public class MvcConfig {    

  @Bean
  public MappingJackson2HttpMessageConverter mappingJacksonHttpMessageConverter() {