まず、メソッドの引数を String または Map のいずれかを取るように変更する必要があります。次に、マーシャリングを次のように制御できます。
@Consumes({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
@Path("/users")
@POST
public Response createUser(@Context SecurityContext sc, String json ) {
ObjectMapper mapper = new ObjectMapper();
User user = mapper.readValue( json, User.class );
次に、この周りに try..catch を配置して、検証エラーをキャッチできます。これをクライアントに返す場合は、BAD_REQUEST の Response を作成してから、リクエストのエンティティのオブジェクトを作成します。ConstrainViolationExcpetion によく似たものを作成します。基本的に、1 行のメッセージの説明と、「フィールド」および「詳細」のフィールドを持つオブジェクトのコレクションがあります。次に、それを JSON または XML としてクライアントに返します。JSON での出力例を次に示します。
{"description":"Validation Failed",
"errors":[
{"field":"emailAddress","message":"not a well-formed email address"}
{"field":"phoneNumber","message":"The phone number supplied was null."},
{"field":"password","message":"may not be null"}]}
基本的な ConstrainViolationException に基づいて応答エンティティを返す簡単で汚い例を次に示しますが、このクラスのインスタンスに「フィールド」要素と「メッセージ」要素を簡単に追加する方法を理解できると思います。
public class RestValidationErrorEntity {
public static Response createResponseOrThrow( ConstraintViolationException e ) {
return Response
.status( Response.Status.BAD_REQUEST )
.entity( new RestValidationErrorEntity( e ) )
.build();
}
public String description = "Validation Failed";
public List<Detail> errors = new ArrayList<>();
public RestValidationErrorEntity( ConstraintViolationException e ) {
for ( ConstraintViolation<?> violation : e.getConstraintViolations() ) {
errors.add(
new Detail(
violation.getPropertyPath().toString(), violation.getMessage()
) );
}
}
public static class Detail {
public String field;
public String message;
Detail( String field, String message ) {
this.message = message;
this.field = field;
}
}
}