2015-02-04 2 views
7

Я пытаюсь использовать Spring-data-rest с spring-data-mongodb, чтобы выставлять ресурсы только для чтения.Исключить некоторые поля ресурса Rest-data-rest

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

Так что я попробовал несколько способов. Я прочитал это сообщение https://spring.io/blog/2014/12/02/latest-jackson-integration-improvements-in-spring, в котором описано, как использовать JsonView, чтобы выбрать поля, которые мы хотим открыть.

Я пробовал так:

@RepositoryRestResource(collectionResourceRel = "recommandation", path = "recommandations") 
interface RecommandationRepository extends MongoRepository<Recommendation, ObjectId> { 

@Override 
@JsonView(View.Public.class) 
Iterable<Recommendation> findAll(Iterable<ObjectId> objectIds); 
... // other find methods 

}

Это не работает. Однако в комментариях сказано: https://spring.io/blog/2014/12/02/latest-jackson-integration-improvements-in-spring#comment-1725671983 Ответ на этот вопрос предлагает использовать @Projections Однако @Projections приводят к URL-адресу: «.../recommandations {? Projection}» Это означает, что проекция - это просто вариант, поэтому полный объект все еще открыт.

Существует другой способ, описанный здесь https://github.com/spring-projects/spring-data-rest/wiki/Configuring-the-REST-URL-path Предлагается использовать аннотацию @RestResource (exported = false) для полей, которые мы не хотим раскрывать.

Но это не является гибким. Если я хочу опубликовать открытый API только для чтения и частный API полного доступа. Эта аннотация не может быть отключена на api.

Есть ли еще предложение?

+0

Как вы различаете публичные и частные API? У вас есть два репозитория для одного класса? Как насчет двух классов? – zeroflagL

ответ

14

Важным моментом является то, что Spring Data REST использует параметры сериализации Jackson на основе объекта домена, а не определения репозитория. Один простой способ, чтобы скрыть определенную область от появления в формате JSON, как это:

@Entity 
public class User { 

    @Id @GeneratedValue 
    private Long id; 

    private String name; 

    @JsonIgnore 
    private String password; 
    ... 

В этом примере мой объект Пользователь никогда не будет экспортировать поле пароля, независимо от того, как используется этот объект. Джексон поддерживает либо установку на поле, либо установку соответствующего метода геттера.

При добавлении в модель домена @JsonIgnore, он делает это определение по умолчанию. Проецирование - это опции для изменения полей. Посмотрите на следующий пример:

@Projection(name = "noImages", types = {Item.class}) 
public interface NoImages { 

    public Link getHtmlUrl(); 

} 

Этот проект может быть использован только при визуализации Item объектов домена. Это не вид по умолчанию, а вместо этого вариант использования через ? Projection = noImages. Но не забывайте: когда придет время применить сериализацию Джексона, проект переопределит настройки модели домена. Это означает, что вы можете написать прогноз для этого Пользователь объект выше и включите его String getPassword(). Это изменит настройку по умолчанию для модели домена, в свою очередь, экспортирует пароль. Ответственность за вами.

Последнее изделие. Spring Data REST поддерживает Выдержки из прогнозов. Наиболее распространенным вариантом использования является то, что у вас есть Клиент объект, связанный с Адрес объект.По умолчанию отношение, чтобы увидеть адрес клиента, будет отображать URI для навигации. Но если вы все время нуждаетесь в адресной информации, вы можете избежать этой дополнительной операции GET, создав проекцию, которая отображает данные адреса. Затем вы можете сконфигурировать это для объектов Customer, включите эту проекцию по умолчанию и, по существу, вставьте данные адреса каждый раз, когда вы берете запись клиента.

Я понимаю, что эталонные документы не совсем обновлены во всех этих деталях. Вы можете отслеживать наш прогресс, чтобы обновить документы соответственно следующим образом:

Существует также ошибка в том, что метаданные ALPS от Spring Data REST также необходимо отфильтровать поля домена с тегом @JsonIgnore (см https://jira.spring.io/browse/DATAREST-463)

P.S. @RestResource устарел, а не рекомендуемый подход к настройке того, какие поля будут экспортированы. Вместо этого используйте @JsonIgnore, как показано выше.

+3

'@ JsonIgnore' полностью удаляет поля из ответа. Как вернуть поля только для чтения в ответ, но просто обновить их? – Stackee007

+0

Это проблема конфигурации Джексона: см. [Этот вопрос] (http://stackoverflow.com/questions/16019834/ignoring-property-when-deserializing) для деталей. –

+3

Если мне нужно внутреннее представление (позволяющее отображать и изменять это поле) и публичное представление только для чтения, которое вообще не хочет показывать это поле, @JsonIgnore не поможет мне правильно? Он удалит поле для обоих представлений, нет? –

7

Per @ Johannes-Rudolph предложение ...

Рассмотрим применение этого параметра в поле (или свойство, если вы картографирования от аксессорах):

@JsonProperty(access = JsonProperty.Access.WRITE_ONLY)  
private String password; 

Это делает то, что подразумевает стоимость доступа : обозначение связанного поля как только для записи. Таким образом, значение можно установить, но не получить через сериализованную форму Jackson/JSON.

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