我有一个Jersey服务,它通过POST方法接受一个对象作为XML。由于预期的数据无效(字段太长等),在编组期间会出现一些错误。如何正常捕获并返回这些错误,而不是获取通用“客户端发送的请求语法不正确”错误。
澄清: REST调用的主体是这样的:
@Consumes({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
@Path("/users")
@POST
public Response createUser(@Context SecurityContext sc, User user) {
// do some stuff
}
用户对象作为通话主体发送的位置。在User对象的集合中引发了错误。
答案 0 :(得分: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返回一个响应实体,但我认为您可以看到如何轻松地将“field”和“message”元素添加到此类的实例中。
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;
}
}
}