如何处理REST服务中的无效参数?

mem*_*und 3 java rest spring web-services

REST使用 提供网络服务spring @RestController

一般无效的参数内容应该如何处理?我尝试抛出自定义异常,但这会导致HTTP 500客户端出现错误并从而暴露堆栈跟踪。

也许这不是正确的方法。但是如何只返回简单的错误消息呢?(用户不会手动访问网络服务。只能通过连接到其余控制器的其他服务来访问)。

Chr*_*haw 5

我使用 jersey,这是一个简单的示例,它将使用 hibernate bean 验证框架来验证您的 bean。这是一项正在进行的工作,但您应该可以非常简单地看到它是如何工作的。

@Path("customers")
public class CustomerResource {
    @PUT
    public Response createCustomer(Customer customer) {
        BeanValidator.validate(customer);
        final String rialtoId = customerProvider.createCustomer(customer);

        return Response.ok(rialtoId).build();
    }
}
Run Code Online (Sandbox Code Playgroud)

这是我创建的一个处理 bean 验证的通用类。

public class BeanValidator {

    /**
     * Used to validate an order request and all the attached objects that
     * support validation.
     * 
     * @param request
     * @throws ConstraintViolationException
     */
    public static <T> void validate(T request) throws ConstraintViolationException {
            ValidatorFactory factory = Validation.buildDefaultValidatorFactory();
            Validator validator = factory.getValidator();
            Set<ConstraintViolation<T>> constraintViolations = validator.validate(request);
            if (constraintViolations.size() > 0) {
                    throw new ConstraintViolationException(new HashSet<ConstraintViolation<?>>(constraintViolations));
            }
    }
}


@XmlRootElement
public class Customer {

    @NotNull(message = "spCustomerID1 is a required field")
    @Size(max = 60, message = "spCustomerID1 has a max length of 60 characters")
    private String spCustomerID1;

    @Size(max = 60, message = "spCustomerID2 has a max length of 60 characters")
    private String spCustomerID2;

    @Size(max = 60, message = "spCustomerID3 has a max length of 60 characters")
    private String spCustomerID3;

    @NotNull(message = "customerName is a required field")
    @Size(max = 60)
    private String customerName;

    @Valid
    @NotNull(message = "customerAddress is a required field")
    private PostalAddress customerAddress;

    @Valid
    @NotNull(message = "customerContact is a required field")
    private ContactInfo customerContact;

    @Valid
    @NotNull(message = "technicalContact is a required field")
    private ContactInfo technicalContact;
    ... / Getters and Setters
}
Run Code Online (Sandbox Code Playgroud)

然后这里是一个简单的 ExceptionMapper,它将支持构造一个简单的响应以发送回客户端。请注意,它将响应类型设置为 400 BAD_REQUEST,而不是 500+ 服务器端错误。

public class ConstraintViolationExceptionMapper implements ExceptionMapper<ConstraintViolationException> {

    public Response toResponse(ConstraintViolationException exception) {

        final StringBuilder strBuilder = new StringBuilder();

        for (ConstraintViolation<?> cv : exception.getConstraintViolations()) {
            strBuilder.append(cv.getPropertyPath().toString() + " " + cv.getMessage());
        }

        RestResponse responseEntity = RestResponse.responseCode(ResponseCode.CONSTRAINT_VIOLATION).setResponseMessage(strBuilder.toString()).build();

        return Response.status(Response.Status.BAD_REQUEST).entity(responseEntity).build();
    }
}
Run Code Online (Sandbox Code Playgroud)

此代码尚未经过测试,但它可能有助于了解如何进行验证的一些想法。在我看来,这是进行休息服务验证的一种非常直接的方法,并且允许您报告确切的变量路径以及每个字段的自定义错误消息。