简体   繁体   English

如何配置由spring-hateoas注册的MappingJackson2HttpMessageConverter

[英]How to configure MappingJackson2HttpMessageConverter registered by spring-hateoas

I like to use spring-hateoas in my project and configured it with @EnableHypermediaSupport . 我喜欢在我的项目中使用弹簧HATEOAS,并配置它@EnableHypermediaSupport The problem now is, that this magic config annotation registers its own MappingJackson2HttpMessageConverter and my own customized converter will be ignored. 现在的问题是,这个神奇的配置注释会注册自己的MappingJackson2HttpMessageConverter ,我的自定义转换器将被忽略。

Background: I added some Jackson modules (like the JodaModule ) to my project and I want them to get registered using objectMapper.findAndRegisterModules(); 背景:我在我的项目中添加了一些Jackson模块(比如JodaModule ),我想让它们使用objectMapper.findAndRegisterModules();注册objectMapper.findAndRegisterModules(); . This is done by overriding configureMessageConverters(List<HttpMessageConverter<?>> converters) in WebMvcConfigurationSupport or WebMvcConfigurer . 这是通过在WebMvcConfigurationSupportWebMvcConfigurer覆盖configureMessageConverters(List<HttpMessageConverter<?>> converters)WebMvcConfigurer

My current configuration looks like this: 我当前的配置如下所示:

@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);
  }
}

Is there a way to customize the MappingJackson2HttpMessageConverter or the ObjectMapper that is used by spring-hateoas? 有没有办法自定义MappingJackson2HttpMessageConverter或spring-hateoas使用的ObjectMapper

I had to do the same thing. 我不得不做同样的事情。 With HATEOAS .16 i was able to ge this working..but really really ugly. 有了HATEOAS .16,我能够正常工作......但真的很难看。

The key was that in the HypermediaSupportBeanDefinitionRegistrar the part that registers the HAL converter checks to see if there already is a HAL converter before it tries to add another one. 关键是在HypermediaSupportBeanDefinitionRegistrar中,注册HAL转换器的部分在尝试添加另一个之前检查是否已经存在HAL转换器。 So I just added a HAL Converter in my WebMVCConfig::configureMessageConverters myself. 所以我自己在我的WebMVCConfig :: configureMessageConverters中添加了一个HAL Converter。

Something like: 就像是:

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);
    }

This is clearly implementation dependent, uses implementation details, and really doesn't let you modify the one that @EnableHyperMediaSupport build for you....but it works for now. 这显然取决于实现,使用实现细节,并且实际上不允许您修改@EnableHyperMediaSupport为您构建的那个....但它现在可以工作。

I use the following approach 我使用以下方法

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

  @Bean
  public MappingJackson2HttpMessageConverter mappingJacksonHttpMessageConverter() {

I found an ugly solution for my problem: 我发现了一个丑陋的解决方案:

I'm using a BeanPostProcessor and a lot of reflection magic, to replace Spring HATEOAS' internal ConversionService with my own one, that has been added to the Spring context before. 我正在使用BeanPostProcessor和许多反射魔法,用我自己的一个替换Spring HATEOAS的内部ConversionService,之前已经添加到Spring上下文中。 This way I make sure, that Spring HATEOAS uses exactly the same ConversionService as Spring MVC. 这样我确保Spring HATEOAS使用与Spring MVC完全相同的ConversionService。

/**
 * This is a HACK to work around a not yet implemented feature. At the moment Spring Hateoas uses a
 * {@link ConversionService}, which is hold in a private static final field and hence cannot be accessed to add more
 * Converters<br/>
 *
 * <ul>
 *   <li><a href="https://github.com/spring-projects/spring-hateoas/issues/118">Spring Hateoas Issue</a></li>
 *   <li><a
 *     href="http://stackoverflow.com/questions/22240155/converter-from-pathvariable-domainobject-to-string-using-controllerlinkbuilde">
 *     Solution on Stackoverflow</a></li>
 * </ul>
 */
public static class HateoasConversionServicePostProcessor implements BeanPostProcessor {

    @Override
    public Object postProcessBeforeInitialization(final Object bean, final String beanName) throws BeansException {
        if (bean instanceof ConversionService) {
            try {
                Class<?> clazz = Class.forName(
                        "org.springframework.hateoas.mvc.AnnotatedParametersParameterAccessor$BoundMethodParameter");
                Field field = clazz.getDeclaredField("CONVERSION_SERVICE");
                field.setAccessible(true);

                Field modifiersField = Field.class.getDeclaredField("modifiers");
                modifiersField.setAccessible(true);
                modifiersField.setInt(field, field.getModifiers() & ~Modifier.FINAL);

                field.set(null, bean);

                modifiersField.setInt(field, field.getModifiers() & Modifier.FINAL);
            } catch (Exception ex) {
                throw new RuntimeException(ex);
            }
        }

        return bean;
    }

    @Override
    public Object postProcessAfterInitialization(final Object bean, final String beanName) throws BeansException {
        return bean;
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何避免 Spring 引导使用我的 MappingJackson2HttpMessageConverter Bean? - How to avoid Spring Boot uses my MappingJackson2HttpMessageConverter Bean? REST Web服务春季MappingJackson2HttpMessageConverter - REST web service spring MappingJackson2HttpMessageConverter 使用 java-configuration 配置 MappingJackson2HttpMessageConverter - Configure MappingJackson2HttpMessageConverter by using java-configuration Spring Boot配置两个MappingJackson2HttpMessageConverter实例 - Spring Boot configures two MappingJackson2HttpMessageConverter instances Spring Boot 2 中无法识别 MappingJackson2HttpMessageConverter 配置 - MappingJackson2HttpMessageConverter configuration is not being recognized in spring boot 2 无法运行Spring Boot应用程序mappingJackson2httpmessageconverter有问题 - Unable to run spring boot application something wrong with mappingjackson2httpmessageconverter 春季4:MappingJackson2HttpMessageConverter不支持jsonp的application / javascript - Spring 4: MappingJackson2HttpMessageConverter does not support application/javascript for jsonp MappingJackson2HttpMessageConverter导入失败 - MappingJackson2HttpMessageConverter import failed MappingJackson2HttpMessageConverter转换复杂对象时的错误 - MappingJackson2HttpMessageConverter Mistake on Converting Complex Object 注册 GsonHttpMessageConverter 而不是 MappingJackson2HttpMessageConverter - Registering GsonHttpMessageConverter instead of MappingJackson2HttpMessageConverter
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM