首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何处理REST服务中的无效参数?

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

Stack Overflow用户
提问于 2015-01-21 14:39:49
回答 4查看 8.6K关注 0票数 3

我使用REST @RestController提供一个webservice服务。

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

也许这不是正确的方法。但是,如何返回简单的错误消息呢?(用户不会手动访问webservice。其他连接到rest控制器的服务)。

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2015-01-21 16:36:09

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

代码语言:javascript
运行
复制
@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验证的泛型类。

代码语言:javascript
运行
复制
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+服务器端错误。

代码语言:javascript
运行
复制
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服务验证方法,允许您报告精确的变量路径以及每个字段的自定义错误消息。

票数 4
EN

Stack Overflow用户

发布于 2015-01-21 16:23:23

您应该在应用程序的最外层验证参数,然后再将其传递到您的域中。此时,您仍然处于HTTP层,因此可以采取适当的操作,即返回400个错误的请求状态。

在此范围内,您可以完全控制如何将此信息传递给用户(或其他服务)。如果您只是记录它,或者设计您自己的描述错误的Json/Xml有效负载,那么纯文本就可以了。

票数 1
EN

Stack Overflow用户

发布于 2015-01-21 15:16:46

如果我很了解你,

然后,通常我认为在每个json响应中都有一个键(或者即使您的响应是XML),这会降低流程的状态。这个字段可以称为status。

因此,您返回的每个响应都应该有这个status字段,它的值应该指示在处理过程中发生了什么,以及调用方在响应中应该期望什么。

值可以是数字或文本消息,一些类似常量的消息也可以添加另一个字段,message,它包含一些状态代码的文本-desc。

现在你必须列出一个可能的雕像名单,你的服务可能会发回。

例:

代码语言:javascript
运行
复制
status: 0000 
message: success

status: 0001 
message: invalid_params

status: 0002 
message: invalid_param_value

status: 0003 
message: missing_param,
:
:
etc

因此,您的json响应将始终包含这些字段。在应该返回的其他数据中。

现在客户有责任处理这些反应。

JSON示例:

代码语言:javascript
运行
复制
{
"status":"0000",
"message":"success",
"images":[ ... ]
}

{
"status":"0003",
"message":"missing_param"
}

正如您注意到的,在非0000状态下,没有其他数据被发送回。只是告诉客户我们有“这个问题”。

或者,通过将:添加到错误消息常量中,告诉更多有关错误的信息,从而使其更具有信息性:

前任,

代码语言:javascript
运行
复制
{
"status":"0003",
"message":"missing_param:album_id"
}

告诉用户,缺少一个参数,它是album_id

现在您可以编写所有可能的status响应,在那里,message将成为服务文档的一部分。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/28069858

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档