2014-09-25 3 views
1

Базирование на https://spring.io/guides/gs/accessing-data-rest/ в примере проекта https://github.com/jcoig/gs-accessing-data-rest) я хранилище определяется следующим образом:Как глобально настроить ресурс ресурса коллекции и путь для ресурсов ресурсов REST Spring?

@RepositoryRestResource 
public interface PersonRepository extends PagingAndSortingRepository<Person, Long> { 
    List<Person> findByLastName(@Param("name") String name); 
} 

Такое Defined хранилище доступно через http://localhost:8080/persons и ответ:

{ 
    "_links" : { 
    "self" : { 
     "href" : "http://localhost:8080/persons{?page,size,sort}", 
     "templated" : true 
    }, 
    "search" : { 
     "href" : "http://localhost:8080/persons/search" 
    } 
    }, 
    "_embedded" : { 
    "persons" : [ { 
     "firstName" : "John", 
     "lastName" : "Smith", 
     "_links" : { 
     "self" : { 
      "href" : "http://localhost:8080/persons/1" 
     } 
     } 
    } ] 
    }, 
    "page" : { 
    "size" : 20, 
    "totalElements" : 1, 
    "totalPages" : 1, 
    "number" : 0 
    } 
} 

Я не хочу имеют persons в URL-адресе, и я не хочу иметь persons в качестве ключа в возвращаемом JSON. Конечно, я могу определить мой репозиторий, как показано ниже:

@RepositoryRestResource(collectionResourceRel = "key", path = "path") 
public interface PersonRepository extends PagingAndSortingRepository<Person, Long> { 
    List<Person> findByLastName(@Param("name") String name); 
} 

но мой вопрос заключается в том, чтобы изменить поведение по умолчанию Spring и получил заказ ключа и пользовательский поставщик пути (только в качестве примера отключить s суффиксы).

ответ

1

Давайте проверим, чего мы пытаемся достичь в первую очередь: Spring Data REST предоставляет два вида первичных ресурсов: ресурсы сбора и ресурсы предметов. Чтобы иметь возможность различать два, нам нужны два разных имени отношений. Таким образом, по умолчанию Spring Data REST использует некапитализированное имя класса домена для ресурса ресурса item и библиотеки Evo Inflector, чтобы разделить репозиторий ресурсов и использовать это как имя отношения коллекции (фактически то, что вы неофициально описали как добавление суффикса s).

Если вы вручную исключаете библиотеку Evo Inflector, Spring REST возвращается к ${itemRel}List для отношения коллекции, которое в первую очередь более неуклюже, чем использование правильно плюрализованных имен.

Как вы уже обнаружили, вы можете вручную настроить имена, которые будут использоваться для каждого репозитория. Однако очень сложно сконфигурировать ресурс коллекции как ресурс rel, поскольку это не позволит клиентам дифференцировать между двумя типами ресурсов.

Предполагая, что вы дочитали до этого читать и по-прежнему хотите, чтобы развернуть пользовательскую стратегию глобально изменить имена соотношения для типов можно реализовать RelProvider (см EvoInflectorRelProvider или DefaultRelProvider для примеров реализации). Если вы зарегистрируете эту реализацию как Spring bean.

@Configuration 
class MyConfig { 

    @Bean 
    YourCustomRelProvider customRelProvider() { 
    return new YourCustomRelProvider(…); 
    } 
} 

Вы могли бы хотеть экспериментировать с заказом (см @Order или интерфейс Ordered) реализации, чтобы убедиться, что ваш пользовательский поставщик выбирается в пользу тех, по умолчанию, зарегистрированных.

+0

Спасибо за ответ! Несчастливо я все еще не могу получить то, что хочу ... В проекте от (без 'collectionResourceRel' и' path') Я добавил класс, реализующий 'RelProvider' с аннотациями' Компонент' и 'Заказ (значение = Заказ.HIGHEST_PRECEDENCE)' и три переопределенные методы: 'getItemResourceRelFor' (возвращает' 'iii" '), ' getCollectionResourceRelFor' (возвращает '' ccc "') и 'поддерживает' (возвращает' true'). В «Application.java» я добавил bean-компонент, как и в вашем ответе, и ... У меня все еще есть «люди» в ключе JSON и в URL-адресе. Что я делаю неправильно? – jcoig

+0

Вот так у нас все получилось, и, похоже, он работает. Было ли так, что все страницы имеют элементы, чтобы интерфейс страницы был нормализован. Можете ли вы подтвердить, что ваш компонент зарегистрирован в качестве компонента? (убедитесь, что вы вызвали метод поддержки) аннотация компонента и метод bean в конфигурации избыточны ... но все равно должны работать. Нам не нужно было делать аннотацию Order. Наш весенний ботинок тоже –

+0

Крис, пожалуйста, посмотрите на этот проект: https://github.com/jcoig/gs-accessing-data-rest. Он основан на http://spring.io/guides/gs/accessing-data-rest/ с изменениями, основанными на намеках Оливера (или, как я их понял). – jcoig

2

Если раствор применяя @Order(value = Ordered.HIGHEST_PRECEDENCE) на настраиваемой RelProvider экземпляра не работает следующий способ может помочь:

@Configuration 
@Import(RepositoryRestMvcConfiguration.class) 
public class RestMvcConfigurer extends RepositoryRestMvcConfiguration 
{ 
... 
@Override 
public ResourceMappings resourceMappings() 
{ 

    final Repositories repositories = repositories(); 
    final RepositoryRestConfiguration config = config(); 
    return new RepositoryResourceMappings(config, repositories, new YourCustomRelProvider()); 
} 
} 

Далее я должен был исключить evo-inflector из пути к классам:

<dependency> 
     <groupId>org.springframework.boot</groupId> 
     <artifactId>spring-boot-starter-data-rest</artifactId> 
     <exclusions> 
      <exclusion> 
       <groupId>org.atteo</groupId> 
       <artifactId>evo-inflector</artifactId> 
      </exclusion> 
     </exclusions> 
    </dependency> 

Не очень Хорошее решение, но оно работает для моей настройки.

+0

Спасибо за ответ Доминик! Оно работает! Теперь у меня есть 'ccc' как ключ в ответе JSON с' http: // localhost: 8080/person {? Page, size, sort} 'in 'href'. Остается вопрос, как изменить этот путь, не используя параметр «path» в аннотации '@ RepositoryRestResource'. – jcoig

+0

Я не уверен, что вы подразумеваете, изменив путь. Если вы ссылаетесь на базовый URI, вы можете перезаписать 'protected void configureRepositoryRestConfiguration (final RepositoryRestConfiguration config)' метод в 'RestMvcConfigurer'. В этом случае вызывается 'config.setBaseUri (" mybaseuri ")'. –

+0

Возвращенный JSON содержит слово «лица» в двух разных местах: в качестве ключа под '_embedded' и в нескольких hrefs. Я хочу изменить пути в этих hrefs без указания пути path = path в аннотации '@ RepositoryRestResource'. – jcoig

Смежные вопросы