我使用REST @RestController提供一个webservice服务。
一般来说,应该如何处理无效的参数内容?我尝试抛出一个自定义异常,但这将导致客户端出现HTTP 500错误,从而公开堆栈跟踪。
也许这不是正确的方法。但是,如何返回简单的错误消息呢?(用户不会手动访问webservice。其他连接到rest控制器的服务)。
发布于 2015-01-21 16:36:09
我正在使用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();
}
}下面是我创建的一个处理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
}下面是一个简单的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();
}
}这段代码还没有经过测试,但它可能有助于获得一些如何进行验证的想法。在我看来,这是一种非常直接的rest服务验证方法,允许您报告精确的变量路径以及每个字段的自定义错误消息。
发布于 2015-01-21 16:23:23
您应该在应用程序的最外层验证参数,然后再将其传递到您的域中。此时,您仍然处于HTTP层,因此可以采取适当的操作,即返回400个错误的请求状态。
在此范围内,您可以完全控制如何将此信息传递给用户(或其他服务)。如果您只是记录它,或者设计您自己的描述错误的Json/Xml有效负载,那么纯文本就可以了。
发布于 2015-01-21 15:16:46
如果我很了解你,
然后,通常我认为在每个json响应中都有一个键(或者即使您的响应是XML),这会降低流程的状态。这个字段可以称为status。
因此,您返回的每个响应都应该有这个status字段,它的值应该指示在处理过程中发生了什么,以及调用方在响应中应该期望什么。
值可以是数字或文本消息,一些类似常量的消息也可以添加另一个字段,message,它包含一些状态代码的文本-desc。
现在你必须列出一个可能的雕像名单,你的服务可能会发回。
例:
status: 0000
message: success
status: 0001
message: invalid_params
status: 0002
message: invalid_param_value
status: 0003
message: missing_param,
:
:
etc因此,您的json响应将始终包含这些字段。在应该返回的其他数据中。
现在客户有责任处理这些反应。
JSON示例:
{
"status":"0000",
"message":"success",
"images":[ ... ]
}
{
"status":"0003",
"message":"missing_param"
}正如您注意到的,在非0000状态下,没有其他数据被发送回。只是告诉客户我们有“这个问题”。
或者,通过将:添加到错误消息常量中,告诉更多有关错误的信息,从而使其更具有信息性:
前任,
{
"status":"0003",
"message":"missing_param:album_id"
}告诉用户,缺少一个参数,它是album_id
现在您可以编写所有可能的status响应,在那里,message将成为服务文档的一部分。
https://stackoverflow.com/questions/28069858
复制相似问题