web-dev-qa-db-ja.com

Spring-data-restリソースの一部のフィールドを除外する

Spring-data-restをspring-data-mongodbと一緒に使用して、読み取り専用リソースを公開しようとしています。

私が出会った問題は、自分のドキュメントに対して異なる見方をしたいということです。ドキュメントに個人情報が含まれていて、それらを公開したくない場合を考えてみましょう。

だから私はいくつかの方法を試しました。私はこの投稿を読みます 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-172567198 答えは@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ごとに無効にすることはできません。

別の提案はありますか?

12
Hugo Lassiège

重要な点は、Spring Data RESTは、リポジトリ定義ではなくドメインオブジェクトに基づいてJacksonシリアル化パラメーターを使用することです。JSONに特定のフィールドが表示されないようにする簡単な方法の1つは次のとおりです。

@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を使用するオプションです。しかし、忘れないでください。ジャクソンのシリアライゼーションを適用するときになると、プロジェクトはドメインモデルの設定を上書きします。これは、上記のUserオブジェクトのプロジェクションを記述し、String getPassword()。これにより、ドメインモデルのデフォルト設定が上書きされ、パスワードがエクスポートされます。責任はあなた次第です。

最後に一つだけ。 Spring Data REST supportExcerpt Projections。最も一般的な使用例は、CustomerオブジェクトはAddressオブジェクトに関連付けられています。デフォルトでは、顧客の住所を表示するための関係は次のようになります。ナビゲートするURI。ただし、常にアドレス情報が必要な場合は、これを回避できます[〜#〜] get [〜#〜]アドレス詳細をレンダリングするプロジェクションを作成することによる操作。次に、Customerオブジェクトに対してそれを構成し、デフォルトでこのプロジェクションをオンにして、基本的にアドレスをインライン化します。顧客レコードをフェッチするときの詳細。

これらすべての詳細について、リファレンスドキュメントが最新のものではないことに気づきました。進捗状況を追跡して、次のようにドキュメントを適切に更新できます。

また、Spring DataのALPSメタデータRESTは、@ JsonIgnorehttps://jira.spring.io/browse/DATAREST-46 を参照)

追伸@ RestResourceは非推奨であり、エクスポートするフィールドを設定するための推奨される方法ではありません。代わりに、前に示したように@ JsonIgnoreを使用します。

20
gregturn

@ johannes-rudolphの提案によると...

この設定をフィールド(またはアクセサーからマッピングする場合はプロパティ)に適用することを検討してください。

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

これは、アクセス値が意味することを行います。関連付けられたフィールドを書き込み専用としてマークします。したがって、値は設定できますが、Jackson/JSONシリアル化された形式を介して取得できません。

14
sofend