2015-11-18 8 views
1

Очень быстрый вопрос, на который, кажется, нелегко ответить.Вставить объект вместо коллекции весной HATEOAS

Можно ли разместить объект непосредственно под встроенными ресурсами, используя Spring HATEOAS? Требуемый формат вывода в формате JSON должен выглядеть

{ 
    ... 
    _embedded: { 
     myObject: { 
      ... 
     } 
    } 
} 

Используя приведенный ниже код, я всегда в конечном итоге с полуботинки для любого ресурса я хочу встроить.

ArrayList<Resource<?>> embeddedContent = new ArrayList<>(); 
Resource<MyObject> myObjectResource = new Resource<MyObject>(new MyObject()); 
embeddedContent.add(myObjectResource); 
Resources<Resource<?>> embeddedResources = new Resources<Resource<?>>(embeddedContent); 

The embeddedResources затем поставить на класс, который затем отображается на ресурс, а также.

Но по какой-то причине, несмотря на то, что я не добавляя коллекцию встроенных ресурсов, выход по-прежнему показывает myObject внедренный ресурс как массив:

{ 
    ... 
    _embedded: { 
     myObject: [ 
      { 
       ... 
      } 
     ] 
    } 
} 

ответ

1

Параметр enforceEmbeddedCollections в этом конструкторе allow представляют собой встроенные массивы, подобные объекту.

public HalHandlerInstantiator(RelProvider resolver, CurieProvider curieProvider, boolean enforceEmbeddedCollections) {}   

Итак, вы должны установить HalHandlerInstantiator со значением false. Существует небольшой пример:

ObjectMapper halObjectMapper = new ObjectMapper(); 
    halObjectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); 
    halObjectMapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false); 

    halObjectMapper 
      .setHandlerInstantiator(new Jackson2HalModule. 
        HalHandlerInstantiator(new DefaultRelProvider(), null, false)); 

    Jackson2HalModule jackson2HalModule = new Jackson2HalModule(); 

    halObjectMapper.registerModule(jackson2HalModule); 
    try { 
     halObjectMapper.writeValueAsString(new Resources<Album>(Arrays.asList(new Album("1", "title", "1", 1)))); 
    } catch (JsonProcessingException e) { 
     e.printStackTrace(); 
    } 
1

Добавьте следующий фрагмент кода в один из ваших @Configuration классов. Код здесь похож на то, что можно найти в org.springframework.hateoas.config.HypermediaSupportBeanDefinitionRegistrar. Мы в основном перезаписываем HalHandlerInstantiator в HAL-ObjectMapper, где мы передаем false аргументу enforceEmbeddedCollections. Это грязный хак, но в настоящее время нет способа настроить этот аспект машины spring-hateoas.

@Bean 
BeanPostProcessor halModuleReconfigurer(BeanFactory beanFactory) { 
    return new BeanPostProcessor() { 
     @Override 
     public Object postProcessBeforeInitialization(final Object bean, final String beanName) throws BeansException { 
      return bean; 
     } 

     @Override 
     public Object postProcessAfterInitialization(final Object bean, final String beanName) throws BeansException { 
      if (bean instanceof RequestMappingHandlerAdapter) { 

       RequestMappingHandlerAdapter adapter = (RequestMappingHandlerAdapter) bean; 
       adapter.setMessageConverters(reconfigureObjectMapper(adapter.getMessageConverters())); 
      } 

      if (bean instanceof AnnotationMethodHandlerAdapter) { 

       AnnotationMethodHandlerAdapter adapter = (AnnotationMethodHandlerAdapter) bean; 
       List<HttpMessageConverter<?>> augmentedConverters = reconfigureObjectMapper(Arrays.asList(adapter 
        .getMessageConverters())); 
       adapter 
        .setMessageConverters(augmentedConverters.toArray(new HttpMessageConverter<?>[augmentedConverters.size()])); 
      } 

      if (bean instanceof RestTemplate) { 

       RestTemplate template = (RestTemplate) bean; 
       template.setMessageConverters(reconfigureObjectMapper(template.getMessageConverters())); 
      } 

      return bean; 
     } 

     private List<HttpMessageConverter<?>> reconfigureObjectMapper(final List<HttpMessageConverter<?>> converters) { 
      for (HttpMessageConverter<?> converter : converters) { 
       if (converter instanceof MappingJackson2HttpMessageConverter) { 
        MappingJackson2HttpMessageConverter halConverterCandidate = (MappingJackson2HttpMessageConverter) converter; 
        ObjectMapper objectMapper = halConverterCandidate.getObjectMapper(); 
        if (Jackson2HalModule.isAlreadyRegisteredIn(objectMapper)) { 
         final CurieProvider curieProvider = Try.of(() -> beanFactory.getBean(CurieProvider.class)).getOrElse((CurieProvider) null); 
         final RelProvider relProvider = beanFactory.getBean("_relProvider", RelProvider.class); 
         final MessageSourceAccessor linkRelationMessageSource = beanFactory.getBean("linkRelationMessageSource", MessageSourceAccessor.class); 
         objectMapper.setHandlerInstantiator(new Jackson2HalModule.HalHandlerInstantiator(relProvider, curieProvider, linkRelationMessageSource, false)); 
        } 
       } 
      } 

      return converters; 
     } 
    }; 
} 
Смежные вопросы