2013-01-14 66 views
3

我有一個Jersey服務,它通過POST方法接受一個XML對象。在編組期間由於數據無效而導致一些錯誤(字段太長等)。如何優雅地捕獲並返回這些錯誤,而不是獲得通用的「客戶端發送的請求在語法上不正確」的錯誤。從Jersey服務返回編組錯誤

澄清:的REST調用的機構是這樣的:

@Consumes({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML}) 
@Path("/users") 
@POST 
public Response createUser(@Context SecurityContext sc, User user) { 
    // do some stuff 
} 

當用戶對象被作爲呼叫的身體。這些錯誤正在用戶對象的集合中引發。

回答

0

噢,首先你需要改變你的方法的參數來取一個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響應,然後爲請求的實體創建一個對象。我創建了一個非常像ConstrainViolationExcpetion的例子。它基本上具有單行消息描述,然後是具有「字段」和「詳細信息」字段的對象集合。然後我將它作爲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; 
     } 
    } 
}