我必须在Jersey中遵循端点结构:
/objects/
/objects/:id
/objects/:id/:field
/objects/:id/:field/:subfield
我使用的ID具有非常特定的格式,因此我首先检查格式是否有效,然后才向数据库发出请求。
现在,我必须将此代码放在每个POST
,PUT
,GET
,DELETE
函数中,以用于{{1}的每个函数}作为参数。所以这只是意味着早日回归。
:id
(实际上,错误实体是包含有关错误的更多信息的对象)
然后对于使用if (!isIdValid(id)){
return Response.status(Response.StatusType.BAD_REQUEST)
.entity("The ID you've provided is invalid")
.build();
}
或:field
参数的每个函数,代码类似。必须每次都复制此检查和错误处理行为。当我开始复制粘贴的东西时,我开始思考:应该有更好的方法吗?
我想将:subfield
检查代码放在:id
级别,然后假设所有其他嵌套级别都具有有效ID。其他参数进一步嵌套相同。
我一直在研究使用子资源定位器,但是你创建了一个返回子资源新实例的函数。如果验证失败,我无法在该级别上条件返回/objects/:id
- 对象。
Response
我可以开始抛出异常,但我宁愿避免这种情况,因为我并不认为无效输入是异常。
如何最好地实施这样的结构?我已经查看了bean验证,但这似乎不允许我为我的特定格式+自定义错误响应定义验证。
我是否遗漏了应该实施子资源的方式?
答案 0 :(得分:0)
如果您可以使用正则表达式检查而不是isIdValid
方法,则可以像这样定义资源
@POST
@Path("objects/{id:\\d+}")
public Response doSmth(@PathParam("id") String id) {
...
}
如果格式为id
格式无效,则调用者将无法获得“未找到”的响应状态,甚至无法使用doSmth
方法。
显然,您可以将String常量用于所有相等的路径值。
final static String ID_RES = "objects/{id:\\d+}";
@POST
@Path(ID_RES)
public Response postSmth(@PathParam("id") String id) {
...
}
...
@GET
@Path(ID_RES)
public Object getSmth(@PathParam("id") String id) {
...
}
还可以阅读Path#value
参数
使用需要进行URI检查的javax.ws.rs.container.ContainerRequestFilter
方法在REST服务器filter
实现中创建并注册。
单个过滤器参数具有ContainerRequestContext
类型,您可以调用getUriInfo
来获取URI和方法abortWith(Response response)
,如果资源ID验证失败,可以使用它来中止调用者请求。
请参阅泽西岛手册的Chapter 10. Filters and Interceptors章节。