0

我正在构建一个使用服务 API 的 UI 客户端,该服务 API 在幕后使用 Web 服务。其中一项 API 服务如下所示:

interface UserService {
    List<User> findUsers(User loggedInUser, UserSearchParameters searchParameters, PagingParameters pagingParameters) throws AuthenticationFault, InvalidIndexFault;
    void removeUser(User loggedInUser, User userToRemove) throws AutheticationFault;
    void addUser(User loggedInUser, User newUser) throws AuthenticationFault;
}

loggedInUser 是代表调用该方法的用户。AuthenticationFault 是一个检查异常。大约有 20 个这样的服务接口。我想做的是实现一个隐藏loggedInUser参数和AuthenticationFault异常的外观。外观实现将使用当前登录客户端的用户调用这些方法。

我也想对其他检查的异常进行一些清理。如您所见,当客户端尝试检索页面 -1 时会引发 InvalidIndexFault 异常,但这是程序员错误,我不想将其作为已检查异常。

目前我所做的总是为我不喜欢的异常重新抛出一个 RuntimeException,但如果我后来改变主意,那么以后需要做很多工作来改变它。这也感觉像是代码重复。其他程序员刚刚吞下了异常并将它们记录下来,这太可怕了。大多数情况下,如果出现异常,我想将其冒泡到显示错误的 ui 中的错误处理程序。

我想到了一些解决方案:

  1. Java 动态代理
  2. 代码生成

我还没来得及尝试这些解决方案,我想我不妨先在这里问一下。你建议我如何实施这个?环境是 Java 6,构建工具是 Maven 3,如果有帮助的话。

PS。如果您回答这个问题,请多说“选择 2” :) 欢迎任何提示和其他实施细节。

澄清一下,检索当前登录的用户不是问题,因此您不必帮助我。我目前将其隐藏在接口后面并使用 IoC 将其注入。在幕后它使用 ThreadLocals

4

1 回答 1

1

我想这将是一个完美的用例

  1. Java 动态代理
  2. 线程本地人

阐明:

首先,创建您的外观界面:

接口 UserServiceFacede {
    List findUsers(UserSearchParameters searchParameters, PagingParameters pagingParameters) throws AuthenticationFault, InvalidIndexFault;
    void removeUser(User userToRemove) 抛出 AutheticationFault;
    void addUser(User newUser) 抛出 AuthenticationFault;
}

接下来你实现你的 InvocationHandler :

公共类 UserHandler 实现 InvocationHandler{
    私有最终 UserService 服务;

    公共用户处理程序(用户服务服务){
       this.service = 服务;
    }

    公共对象调用(对象代理,方法方法,对象 [] args)抛出 Throwable {
       ……
       // 根据方法参数,在实际服务上调用相应的函数
       // 目的
       ……
    }
}

然后,您可以像这样创建 Proxy 对象:

  UserServiceFacade uProxy = (UserServiceFacade)Proxy.newProxyInstance(UserHandler.class.getClassLoader(),
                                        新类 [] { UserServiceFacade.class},
                                        新用户处理程序(用户服务));

第一个参数是类加载器,第二个是代理必须确认的接口列表,第三个是处理程序对象

现在的问题是如何获得登录用户的句柄。这就是ThreadLocal的用武之地。

创建一个保存登录用户的 ThreadLocal 静态变量。然后在调用代理之前将当前用户设置为 ThreadLocal

     私有静态最终 ThreadLocal 登录用户 = ...;
     ...
     ...
     登录用户.set(当前用户);
     // 如上所述创建一个用户代理对象..
     uProxy.findUser(searchParams, ..);
     ...

从处理程序的调用函数内的 ThreadLocal 中检索用户。现在在处理程序内部,您可以访问 loggedinUser(使用loggedinUser.get())以及用户服务对象(您已将服务对象传递到处理程序的构造函数中)

就您如何处理异常而言,我通常会继续抛出 RuntimeExceptions 的子类。然后在应用程序的外围层捕获这些。外围层是指进入您的应用程序/库的入口点。如果您正在开发 webbApp,这将是您的 Servlet。

于 2011-07-31T14:53:18.160 回答