有没有办法在不使用struts.xml的情况下重定向到另一个动作类

时间:2013-04-27 17:21:53

标签: java jsp authentication struts2

我在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>

请帮助我找到更好的方法。

2 个答案:

答案 0 :(得分:3)

看起来你想要检查基本动作类的构造函数,但是你错了。对象工厂使用构造函数来实例化您的操作实例。在这个阶段,您可以使用一些东西。在你的情况下,这是错的。另一种方法是,如果您将逻辑移动到方法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对象不可变,以免损害安全功能。

答案 1 :(得分: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>

或者通过网址格式:

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

修改

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