3

我有一个 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
}

用户对象作为调用主体发送的位置。在用户对象的集合中引发了错误。

4

1 回答 1

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;
        }
    }
}
于 2013-01-14T21:22:25.157 回答