2016-05-26 7 views
1

パスワードのように安全である必要があるこれらの読み取り専用フィールドがあります。Dropwizardで@POSTのフィールドのみを確​​認する

public class User { 
    @NotEmpty 
    @Size(max = 100) 
    private String name; 
    @NotEmpty 
    private String username; 
    @NotEmpty 
    @Email 
    private String email; 
    private String password; 

    @JsonIgnore 
    public String getPassword() { 
    return password; 
    } 

    @JsonProperty 
    public void setPassword(String password) { 
    this.password = password; 
    } 
} 

これはうまくいきます。私が得ることができるように/投稿することができますが、私は決してパスワードを受け取ることはありません。しかし、初めて投稿されたときにパスワードが空であってはならないことを確認したい。私がしている場合

@NotEmpty 
private string password; 

このユーザーのパスワードを変更したくない場合、私のPUT(編集)要求は検証エラーで失敗します。

の1-継承Userクラス、ゲッターの上に@NotEmptyアノテーションを持つことができる唯一のPOSTのための特別なクラスを作成します。

私は考えることができる2つのソリューションがあります。

public static class Create extends User { 
    @NotEmpty 
    @Override 
    public String getPassword() { 
    return password; 
    } 
} 

それはすでにCRUD資源に大きく継承を利用していますので、これは私のコードベースのため、一般的ではなく動作するはずです。私はこのアプローチのために多くのことを壊して複製する必要があります。リソースクラスの

2 -ハンドルの検証:

public class UserResource { 

    @POST 
    public User createUser(User user) { 
    if(user.getPassword().isEmpty()) { 
     throw new ConstraintValidation....(); 
    } 
    } 
} 

仕事をしていませんが、とてもきれいではありません。特に私はこれらの5-10を持っているからです。

他の代替手段はありますか?

+0

はデフォルトのものを使用するのではなく、独自のバリデータの実装を行い、その後、より複雑なチェックを持ってもらえますか?たとえば、ユーザーが存在するかどうか(作成していない場合)を確認し、それに基づいてパスワードを検証できるバリデーターを持つことができます。私はあなたがバリデータのリソースタイプにアクセスしているとは思わないが、あなたのメソッドタイプをthreadLocalまたは同様のばかげたものに保存するジャージーフィルタを実装している場合を除きます。 – pandaadb

+0

実際、ジャージー情報を読んで、バリデーターにUriInfoを注入することができます。次に、呼び出されたリソースメソッドに基づいて妥当性検査の問題は発生しません。参照してください:https://jersey.java.net/documentation/latest/bean-validation.html – pandaadb

+0

私は実際にこれを考慮し、私が何か関連性があるかどうかを確認するためにConstraintValidatorContextのフィールドをチェックしました。ジャージー注射を考えなかった。私はこれも、ハイバーネーションバリデータで動作すると思いますよね?そうであれば、回答を作成してマークすることができます。ありがとう! – Natan

答えて

3

は別にジャージ注入とカスタムバリデータから、私はそれが、ナタンをあなたに興味かもしれないと思うクーラーと簡単かつスムーズな解決策を見つけた:

DWではなく、検証グループをサポートしています。これらを使用すると、メソッドに基づいて注釈を付けることができます。あなたはここでその詳細を読むことができます:

http://www.dropwizard.io/0.9.0/docs/manual/validation.html

(FWIW、私は私の例では、RCのリリースを使用しています)。

それではを始めましょう:

@Path("/hello/world") 
@Produces(MediaType.APPLICATION_JSON) 
public class HelloWorldResource { 

    @POST 
    @Path("/v1") 
    @Consumes(MediaType.APPLICATION_JSON) 
    @Produces(MediaType.APPLICATION_JSON) 
    public Response test(@Valid @Validated(V1Check.class) User user) { 
     // checks only username 
     System.out.println(user.getName()); 
     System.out.println(user.getPassword()); 

     return Response.ok().build(); 
    } 


    @POST 
    @Path("/v2") 
    @Consumes(MediaType.APPLICATION_JSON) 
    @Produces(MediaType.APPLICATION_JSON) 
    public Response test2(@Valid @Validated(V2Check.class) User user) { 
     // checks both 
     System.out.println(user.getName()); 
     System.out.println(user.getPassword()); 

     return Response.ok().build(); 
    } 
} 

これは、リソースクラスです。 @Validatedで両方のメソッドにどのように注釈を付けたかを見てください。これは、DWに正確に検証するものを指示します。私もそのクラスにインターフェースを組み込み

public class User { 

    @JsonProperty("name") 
    private String name; 

    @JsonProperty("password") 
    private String password; 

    @NotEmpty(message="other message", groups= {V2Check.class}) 
    public String getPassword() { 
     return password; 
    } 

    public void setPassword(String password) { 
     this.password = password; 
    } 

    @NotEmpty(message="asd asd asd", groups= {V1Check.class, V2Check.class }) 
    public String getName() { 
     return name; 
    } 

    public void setName(String name) { 
     this.name = name; 
    } 

    public interface V1Check {}; 
    public interface V2Check {}; 
} 

は、ここに私のユーザークラスです。パスワードはV2のみがチェックされるようになりました。したがって、POSTメソッドの場合は、Validメソッドのアノテーションにそのメソッドを追加し、getメソッドはV1のままにしておき、パスワードを無視します。

そして、良い対策のために、私のテストのためのスターター:

public class Starter extends Application<Configuration> { 

    @Override 
    public void run(Configuration configuration, Environment environment) throws Exception { 
     environment.jersey().register(HelloWorldResource.class); 
    } 

    public static void main(String[] args) throws Exception { 
     new Starter().run("server", "/Users/artur/dev/repo/dw-test/src/main/resources/configuration.yaml"); 
    } 

} 

これは、これを行うにはDWの方法です、しかし、あなたは同様にあなたのカスタムバリデータにジャージ注入を追加することができるはずです。あなたがあなたのパスワードをチェックする必要がないので、カスタムバリデーターJUSTを書く必要はないようです。

ここは私のカールです。 user_json2:

{ 
    "name" : "artur" 
} 

V1は、パスワードをチェックしません:

arturk:tmp artur$ curl -XPOST "localhost:9085/hello/world/v1/" --header "Content-Type: application/json" -d @user_json2 -v 
    * Trying ::1... 
    * Connected to localhost (::1) port 9085 (#0) 
    > POST /hello/world/v1/ HTTP/1.1 
    > Host: localhost:9085 
    > User-Agent: curl/7.43.0 
    > Accept: */* 
    > Content-Type: application/json 
    > Content-Length: 19 
    > 
    * upload completely sent off: 19 out of 19 bytes 
    < HTTP/1.1 200 OK 
    < Date: Fri, 27 May 2016 09:59:22 GMT 
    < Content-Length: 0 
    < 
    * Connection #0 to host localhost left intact 

V2、パスワードを確認する:

arturk:tmp artur$ curl -XPOST "localhost:9085/hello/world/v2/" --header "Content-Type: application/json" -d @user_json2 -v 
* Trying ::1... 
* Connected to localhost (::1) port 9085 (#0) 
> POST /hello/world/v2/ HTTP/1.1 
> Host: localhost:9085 
> User-Agent: curl/7.43.0 
> Accept: */* 
> Content-Type: application/json 
> Content-Length: 19 
> 
* upload completely sent off: 19 out of 19 bytes 
< HTTP/1.1 400 Bad Request 
< Date: Fri, 27 May 2016 10:07:41 GMT 
< Content-Type: text/html;charset=iso-8859-1 
< Cache-Control: must-revalidate,no-cache,no-store 
< Content-Length: 251 
< 
<html> 
<head> 
<meta http-equiv="Content-Type" content="text/html;charset=utf-8"/> 
<title>Error 400 Bad Request</title> 
</head> 
<body><h2>HTTP ERROR 400</h2> 
<p>Problem accessing /hello/world/v2/. Reason: 
<pre> Bad Request</pre></p> 
</body> 
</html> 
* Connection #0 to host localhost left intact 

私はそれが役に立てば幸い!

乾杯、

アルトゥルは

+0

はい!これは良い方法です。私はジャージーでのエンティティフィルタリングがあることは知っていたが、検証グループについては知らなかった。私はリリースノートでそれを見たと思うが、私はそれについて完全に忘れてしまった。ありがとうございました! – Natan

関連する問題