如何在API中处理不正确的格式化请求

时间:2018-06-03 21:34:00

标签: java spring api exception

我想知道处理这种类型的请求的正确方法是什么。我有来自UI的删除请求,它是ID的整数列表。所以请求看起来像:

www.myui.com/delete/1,2,3,4 

这是一个格式正确的请求。但如果由于任何原因的请求来自卷曲请求或邮递员等,它可能被格式化为:

www.myui.com/delete/1,,3,4 

在这种情况下,第二个索引将包含null,因为它正在检查整数。但是,如果我们期待一个String列表,那么如果它被格式化为/ 1,2,3,4,那么它将是一个简单的空字符串或n个空白字符,所以我必须遍历请求并检查如果字符串列表中的字符串只是空格并且返回404。

我应该在控制器中执行此操作还是允许此类请求传递,并最终在dao中抛出异常,因为它将尝试删除null或只是空格的id将不存在于DB中。

以下是我当前正在处理请求的示例,该请求是整数列表。

@DeleteMapping(value="/delete/{ids}")
    public ResponseEntity delete(@PathVariable("ids") List<Integer> ids)
            throws DatabaseException {
        if (ids.contains(null)) {
            return new ResponseEntity<>(HttpStatus.BAD_REQUEST);
        }
        service.delete(ids);
        return new ResponseEntity<>(HttpStatus.NO_CONTENT);
    }

2 个答案:

答案 0 :(得分:2)

简而言之,快速失败是一种更好的方法,因为它有助于尽早和快速地检测故障,尽管您也可以考虑应用程序的业务要求和一般设计指南,如果它应该是宽松的,那么您可能会使用类似的东西:

service.delete(ids.stream().filter(Objects::nonNull).collect(Collectors.toList()));

并返回一个至少包含许多项目的响应正文。

如果您的申请必须严格,那么应该尽快返回错误的请求。

此外,您必须考虑到您的服务和/或DAO不是专门从控制器调用的,因此必须在那里实现验证和/或检查,并且尽量不要让格式错误的请求到达数据库。你已经知道他们会导致错误,这只会浪费流量。

最后,我希望你的案例中的整数id不是数据库生成的,在这种情况下,它会成为一个主要的安全问题,因为你在api上暴露了持久性细节,攻击者可能会消灭你的数据库或部分数据库通过发送递增整数列表。我建议你使用某种随机生成的唯一ID来暴露api(这并不意味着你应该摆脱整数基索引)。

答案 1 :(得分:1)

检测到错误后立即处理错误是正确的。在这种情况下,在控制器级别检测到错误请求,因此它是在那里处理它的最佳选择。

虽然您的方法很好,但查看@ResponseHandler可能具有指导意义,因为它可用于在Controller级别上概括已知异常的处理。