3

我正在寻找一种为 Resteasy 服务提供自定义输入验证的良好模式。

假设我有这项服务:

@Local
@Path("/example")
public interface IExample {
  public Response doSomething ( @QueryParam("arg1") String arg1, @QueryParam("arg2") Integer arg2);
}

我已经实现了:

@Stateless
public class Example implements IExample {
  @Override
  public Response doSomething ( String arg1, Integer arg2 ) { ... }
}

验证 arg1 和 arg2 的最佳实践是什么?

我的想法:

  1. 在 doSomething(...) 方法中验证。缺点:当我将来添加一些参数(例如 arg3)时,我很容易忘记验证它。
  2. 在自定义 javax.servlet.Filter 中。缺点:我无法在那里访问 arg1 和 arg2,因为它们还没有被 Resteasy 框架解析。

我想出了这个概念:

public class ExampleValidator implements IExample {
  public static class ValidationError extends RuntimeException { ... }

  @Override 
  public Response doSomething ( String arg1, Integer arg2 ) {
     // here do validation. In case of failure, throw ValidationError
     return null;
  }
}

可以按如下方式使用:

@Stateless
public class Example implements IExample {
  @Override
  public Response doSomething ( String arg1, Integer arg2 ) {
     try { 
       (new ExampleValidator()).doSomething(arg1, arg2); 
     } catch ( ValidationError e ) {
        // return Response with 400
     }
  }
}

这样,当我更改 IExample.doSomething 方法签名时,由于编译时错误,我必须更新 Validator。为了让 Resteasy 不将 ExampleValidator 解释为服务,我使用了 resteasy.jndi.resources 而不是 resteasy.scan,但它失败了(示例 bean 在 resteasy 尝试在部署时使用它之后加载)。

任何想法 - 是否有任何好的验证模式?还是有可能以某种方式让我的概念发挥作用?

编辑:或者,哪一个是最好的,在 Resteasy 中有一些过滤器对应物?在实际实现之前调用我的方法(过滤器)但参数(arg1,arg2)已经解析的某种方案?

在此先感谢,抱歉发了很长的帖子;)卡米尔

4

1 回答 1

1

(1) 可能最简洁的方法是使用 Java EE 6 Bean Validation 框架。这将需要编写自定义验证拦截器。在这种情况下,你将不得不改变你的方法,所以而不是

public Response doSomething ( String arg1, Integer arg2 )

您将使用域对象作为参数

public Response doSomething ( JAXBElement<MyDomainObject> myOJaxb )

然后您需要转换您的请求,以便他们提供 XML 或 JSON 格式的数据,这些数据可以自动转换为实际对象。

(2) 另一种选择是使用普通的ServletFilter。

(3) 准备自定义注解a'la Bean Validation,然后你需要插件自定义注解处理器(看看项目Lombok,作为灵感)。

(4) 最简单的解决方案是使用内置的 REST 验证

@Path("users/{username: [a-zA-Z][a-zA-Z_0-9]}")

但这适用于路径参数,而不是查询参数(我认为,但没有检查 JAX-RS 规范)

您的选择取决于您的界面有多少灵活性以及您有多少时间。

如果你想出一个通用的、可插入到 Resteasy 的解决方案,类似于选项 (3) 中的建议,并在 GitHub 上开源,很多人会喜欢你的 :)

于 2012-02-23T14:32:16.177 回答