したがって、対応するフィールドを持つUserDto DTOクラスがあります。
public class UserDto { private Long id; private String name; private String login; private String password; private String email; }
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
      
      コンストラクターとゲッターセッターを省略します-それらを作成する方法を知っていると確信していますが、コードが3〜4倍に増加するという感覚はありません-既に存在していると想像してみましょう。
CRUDメソッドを使用して、コントローラーを介してDTOを受け入れます。 繰り返しますが、すべてのCRUDメソッドを書くわけではありません-実験の純度のために、いくつかあります。 createおよびupdateNameにします。
  @PostMapping(consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE) public ResponseEntity<UserDto> create(@RequestBody UserDto dto) { return new ResponseEntity<>(service.save(dto), HttpStatus.OK); } @PutMapping(consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE) public ResponseEntity<UserDto> updateName(@RequestBody UserDto dto) { return new ResponseEntity<>(service.update(dto), HttpStatus.OK); }
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
      
      明確にするために、それらも簡素化する必要がありました。 したがって、UserDtoに変換されるJSONを取得し、JSONに変換されてクライアントに送信されるUserDtoを返します。
ここで、一緒に作業するいくつかの検証アノテーションに精通することを提案します。
  @Null //   null @NotNull //    null @Email //   e-mail
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
      
      すべての注釈はjavax.validation.constraintsライブラリで利用可能です。 したがって、検証されたオブジェクトをすぐに受け取り、さらに本質に変換してデータベースに保存するように、DTOを構成します。 入力する必要があるフィールドには、 NotNullをマークし、電子メールにもマークを付けます。
 public class UserDto { @Null //   private Long id; @NotNull private String name; @NotNull private String login; @NotNull private String password; @NotNull @Email private String email; }
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
      
      DTOの検証設定を設定します-id以外のすべてのフィールドに入力する必要があります-データベースで生成されます。 検証をコントローラーに追加します。
  @PostMapping(consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE) public ResponseEntity<UserDto> create(@Validated @RequestBody UserDto dto) { return new ResponseEntity<>(service.save(dto), HttpStatus.OK); } @PutMapping(consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE) public ResponseEntity<UserDto> updateName(@Validated @RequestBody UserDto dto) { return new ResponseEntity<>(service.update(dto), HttpStatus.OK); }
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
      
      このように構成された検証は、新しいユーザーの作成には適していますが、既存のユーザーの更新には適していません。このため、id(nullに設定)を取得する必要があります。また、updateNameの名前のみを変更するため、 。 つまり、IDと名前を取得する必要があります。 そして、ここには可視性インターフェースが必要です。
DTOクラスに直接インターフェイスを作成しましょう(わかりやすくするために、このようなものを別のクラスに入れることをお勧めします。たとえば、転送などの別のパッケージに入れることをお勧めします)。 インターフェイスはNewと呼ばれ、2番目はExistと呼ばれ、そこからUpdateNameを継承します(将来、Existから他の可視性インターフェイスを継承できるようになり、複数の名前を変更します)。
 public class User { interface New { } interface Exist { } interface UpdateName extends Exist { } @Null //   private Long id; @NotNull private String name; @NotNull private String login; @NotNull private String password; @NotNull @Email private String email; }
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
      
      次に、Newインターフェースで注釈をマークします。
  @Null(groups = {New.class}) private Long id; @NotNull(groups = {New.class}) private String name; @NotNull(groups = {New.class}) private String login; @NotNull(groups = {New.class}) private String password; @NotNull(groups = {New.class}) @Email(groups = {New.class}) private String email;
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
      
      現在、これらの注釈は、新規インターフェースを指定する場合にのみ機能します。 名前フィールドを更新する必要がある場合にのみ、ケースに注釈を設定できます(非nullのIDと名前を指定する必要があることを思い出してください、残りはnullです)。 これは次のようなものです。
  @Null(groups = {New.class}) @NotNull(groups = {UpdateName.class}) private Long id; @NotNull(groups = {New.class, UpdateName.class}) private String name; @NotNull(groups = {New.class}) @Null(groups = {UpdateName.class}) private String login; @NotNull(groups = {New.class}) @Null(groups = {UpdateName.class}) private String password; @NotNull(groups = {New.class}) @Null(groups = {UpdateName.class}) @Email(groups = {New.class}) private String email;
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
      
      コントローラーで必要な設定を行い、検証を設定するインターフェースを登録するだけです。
  @PostMapping(consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE) public ResponseEntity<UserDto> create(@Validated(UserDto.New.class) @RequestBody UserDto dto) { return new ResponseEntity<>(service.save(dto), HttpStatus.OK); } @PutMapping(consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE) public ResponseEntity<UserDto> updateName(@Validated(UserDto.UpdateName.class) @RequestBody UserDto dto) { return new ResponseEntity<>(service.update(dto), HttpStatus.OK); }
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
      
      これで、各メソッドに対して、独自の設定セットが呼び出されます。
そこで、入力データを検証する方法を考え出しましたが、今では出力を検証する必要があります。 これは@JsonViewアノテーションを使用して行われます。
これで、出力DTOには、すべてのフィールドが含まれます。 しかし、パスワードを与える必要がないと仮定します(例外的な場合を除く)。
出力DTOを検証するために、出力の可視性を担当する2つのインターフェイスを追加します。詳細(ユーザーへの表示用)とAdminDetails(管理者のみへの表示用)です。 インターフェイスは相互に継承できますが、認識を簡単にするために、ここではこれを行いません。この主題に関する入力データの例にすぎません。
  interface New { } interface Exist { } interface UpdateName extends Exist { } interface Details { } interface AdminDetails { }
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
      
      これで、必要に応じてフィールドに注釈を付けることができます(パスワード以外はすべて表示されます)。
  @Null(groups = {New.class}) @NotNull(groups = {UpdateName.class}) @JsonView({Details.class}) private Long id; @NotNull(groups = {New.class, UpdateName.class}) @JsonView({Details.class}) private String name; @NotNull(groups = {New.class}) @Null(groups = {UpdateName.class}) @JsonView({Details.class}) private String login; @NotNull(groups = {New.class}) @Null(groups = {UpdateName.class}) @JsonView({AdminDetails.class}) private String password; @NotNull(groups = {New.class}) @Null(groups = {UpdateName.class}) @Email(groups = {New.class}) @JsonView({Details.class}) private String email;
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
      
      必要なコントローラーメソッドをマークするために残ります。
  @JsonView(Details.class) @PostMapping(consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE) public ResponseEntity<UserDto> create(@Validated(UserDto.New.class) @RequestBody UserDto dto) { return new ResponseEntity<>(service.save(dto), HttpStatus.OK); } @JsonView(Details.class) @PutMapping(consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE) public ResponseEntity<UserDto> updateName(@Validated(UserDto.UpdateName.class) @RequestBody UserDto dto) { return new ResponseEntity<>(service.update(dto), HttpStatus.OK); }
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
      
      また、別の場合には、@ JsonView(AdminDetails.class)にパスワードのみをプルするメソッドに注釈を付けます。 パスワードだけでなくすべての情報を管理者に送信する場合は、必要なすべてのフィールドに適宜注釈を付けます。
  @Null(groups = {New.class}) @NotNull(groups = {UpdateName.class}) @JsonView({Details.class, AdminDetails.class}) private Long id; @NotNull(groups = {New.class, UpdateName.class}) @JsonView({Details.class, AdminDetails.class}) private String name; @NotNull(groups = {New.class}) @Null(groups = {UpdateName.class}) @JsonView({Details.class, AdminDetails.class}) private String login; @NotNull(groups = {New.class}) @Null(groups = {UpdateName.class}) @JsonView({AdminDetails.class}) private String password; @NotNull(groups = {New.class}) @Null(groups = {UpdateName.class}) @Email(groups = {New.class}) @JsonView({Details.class, AdminDetails.class}) private String email;
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
      
      この記事が、入力DTOの検証とこの出力の可視性の理解に役立つことを願っています。