java - 用于隐藏 Java Web 服务的身份验证详细信息的外观

标签 java facade

我正在构建一个使用服务 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 是一个已检查的异常。这样的服务接口(interface)大约有 20 个。我想要做的是实现一个隐藏loggedInUser参数和AuthenticationFault异常的外观。外观实现将使用当前登录客户端的用户调用这些方法。

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

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

我想到了一些解决方案:

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

我还没有抽出时间尝试这些解决方案,所以我想我不妨先在这里问一下。你建议我如何实现这个?环境是 Java 6,构建工具是 Maven 3(如果有帮助的话)。

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

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

最佳答案

我想这将是完美的用例

  1. Java 动态代理
  2. 线程局部变量

说明一下:

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

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

接下来你实现你的 InvocableHandler :

public class UserHandler implements InvocationHandler{
    private final UserService service;

    public UserHandler(UserService service) {
       this.service = service;
    }

    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
       ....
       // Based on the method argument, call the appropriate function on the actual service
       // object
       ....
    }
}

然后您可以像这样创建代理对象:

  UserServiceFacade uProxy = (UserServiceFacade)Proxy.newProxyInstance(UserHandler.class.getClassLoader(), 
                                        new Class[] { UserServiceFacade.class},
                                        new UserHandler(userService));

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

现在的问题是如何获取登录用户的句柄。这就是ThreadLocal进来。

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

     private static final ThreadLocal loggedinUser = ...;
     ...
     ...
     loggedinUser.set(currentUser);
     // Create a user Proxy object as mentioned above.. 
     uProxy.findUser(searchParams, ..);
     ...

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

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

关于java - 用于隐藏 Java Web 服务的身份验证详细信息的外观,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6889948/

相关文章:

java - 在 JRuby 中使用的 Java 对象上使用(自定义)getId 方法有什么问题吗?

php - 拉维尔 4 : use Facade in custom Class

java - 'facade method'(调用自己类的公共(public)方法)是否被认为是糟糕的设计?

design-patterns - 使用的最佳设计模式 : adapter or facade

java - 是否可以使用坐标来定位 JButton?

java - 在屏幕上移动手指时 OnTouchListener ACTION_MOVE 不起作用

java - 如何重置java中的标准输入和输出?

java - 如何使文件路径通用,适合所有操作系统?

design-patterns - 组合与立面模式

c++ - 为对象中的对象提供接口(interface)