【问题标题】:Is there a way to redirect to another Action class without using on struts.xml有没有办法在不使用 struts.xml 的情况下重定向到另一个 Action 类
【发布时间】:2013-04-27 17:21:53
【问题描述】:

我在我的 Struts 应用程序中创建了许多类。我没有检查是否在任何课程中都处于登录状态。相反,我扩展了一个基本动作类。

现在我想在我的基本操作中创建一个预处理程序,以检查是否已登录并在未登录时重定向。

我想要这样的东西:

public BaseAction(){
  if(isLoggedIn){
    //go to child which was called
   }
   else {   //redirect to login page
  }          
}

另一种方法是检查isLoggedIn(),方法是在所有操作类中调用此方法并定义一个全局结果,如

<result name="not-logged-in" type="redirectAction">Login.action</result>

请帮我找到更好的方法。

【问题讨论】:

  • 您需要指定您正在使用的 Struts 版本,因为您的代码中同时包含 Struts 1 和 Struts 2 工件。
  • @DaveNewton OP 将其标记为 Struts 2,但我将其重新标记为 Struts。
  • 谢谢大家。它的struts2。

标签: java jsp authentication struts2


【解决方案1】:

看起来你想签入基本动作类的构造函数,但你错了。对象工厂使用构造函数来实例化您的操作实例。在这个阶段,您可以使用一些东西。在你的情况下,这是错误的。另一种方法是,如果您将逻辑移动到方法中,例如 execute() 并在任何方法调用起作用之前调用 super.execute(),但是如果您忘记将超级调用放入操作中,那么您可能最终导致操作代码运行未经过身份验证.为了防止它,您应该在执行任何操作之前运行代码,并且能够访问操作实例或操作上下文以更 Struts2。我猜你从来没有读过这本书Struts 2 in Action所以我会给你一些我自己的想法。它是关于创建AuthenticationInterceptor 和实现UserAware 的操作,该操作将登录的用户注入到实现此接口的操作中。拦截器看起来像

public class AuthenticationInterceptor implements Interceptor {

public void destroy() {
}

public void init() {
}

public String intercept(ActionInvocation actionInvocation) throws Exception {
    Map session = actionInvocation.getInvocationContext().getSession();
    User user = (User) session.get(Struts2MyConstants.USER);
            
    if (user == null) {
        return Action.LOGIN; //login required result
    }               
    else {              
        Action action = (Action)actionInvocation.getAction();
        
        if (action instanceof UserAware) {
            User freshUser = myService.getUser(user.getId());
            ((UserAware)action).setUser(freshUser);
        }
        
        System.out.println("Logged in: interceptor");
        return actionInvocation.invoke();
    }
}

UserAware 看起来像

public interface UserAware {
    
    public void setUser( User user );
    
}

并创建一个安全的默认堆栈来引用任何操作

<interceptors>
  <interceptor name="authenticationInterceptor" class="org.yourapp.struts.interceptor.AuthenticationInterceptor"/>
  <interceptor-stack name="secureStack">
    <interceptor-ref name="authenticationInterceptor"/>
    <interceptor-ref name="defaultStack"/>
  </interceptor-stack>
</interceptors>
<default-interceptor-ref name="secureStack"/> 

如果您执行基本操作来实现UserAware,那么登录的用户对象不仅可以从会话中使用,而且如果您为用户定义 getter 或使其受到保护,那么它也可以在操作中使用。您必须使 User 对象不可变,以免损害安全功能。

【讨论】:

    【解决方案2】:

    您可以使用Filter。这比要求所有类扩展BaseAction 透明得多。

    编辑

    您将在 web.xml 文件中映射此过滤器,因此它将在 Struts 控制器 servlet 之前执行。

    <filter>
       <filter-name>AuthorizationFilter</filter-name>
       <filter-class>my.company.AuthorizationFilter</filter-class>
    </filter>
    
    <filter-mappging>
        <filter-name>AuthorizationFilter</filter-name>
        <servlet-name>StrutsActionServlet</servlet-name>
    </filter-mapping>
    

    或通过 URL 模式:

    <filter-mapping>
        <filter-name>AuthorizationFilter</filter-name>
        <url-pattern>*.do</url-pattern>
    </filter-mapping>
    

    编辑

    您已经更改了问题,看来您毕竟使用的是 struts 2。在这种情况下,您可以编写拦截器而不是过滤器。它基本上会做同样的事情,但拦截器可以与你的其他 struts 配置一起配置。

    【讨论】:

    • 对不起。我刚刚发布了我在浏览时分析的方式。但我想在基类中有这样的东西。我无法更改所有操作类来检查登录。
    • 这就是过滤器的全部想法。你没有在你的动作类中这样做。过滤器拦截请求并在您的操作执行之前执行一些操作。你的行为根本不需要知道这一点。
    • 无论如何它对我来说是一个替代解决方案。但是 StrutsActionServlet 类应该返回什么。操作类将如何重定向到我的登录页面?
    • 这只是一个示例映射。您的过滤器会使用response.sendRedirect() 重定向到您的登录页面。根本不涉及 Struts。
    • 看来您毕竟使用的是 Struts 2,所以我已经编辑了答案。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-07-24
    • 1970-01-01
    • 2018-10-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-17
    相关资源
    最近更新 更多