有没有办法redirect到另一个行动类,而不使用struts.xml

我在我的Struts应用程序中创build了许多类。 我没有检查是否在任何类的login条件。 相反,我已经扩展了基础动作类。

现在我想创build一个预处理程序在我的基本操作来检查login和redirect,如果他们没有login。我想这样的事情。

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> 

请帮我find更好的方法。

看起来你想检查基础动作类的构造函数,但是你错了。 构造函数被对象工厂用来实例化你的动作实例。 在这个阶段有几件事情可以提供给你。 在你的情况是错的。 另一种方法是,如果在任何方法调用之前将逻辑移入方法execute()并调用super.execute() ,但是如果您忘记将超级调用放入操作中,则可能会结束操作代码运行未经authentication。 为了防止它,你应该在执行任何动作之前运行代码,并且能够访问动作实例或动作上下文,以使其成为更多的Struts2。 我想你从来没有读过“Struts 2 in Action”一书,所以我会给你一些我自己的想法。 这是关于创buildAuthenticationInterceptor和实现UserAware的操作,该操作将注册用户login到实现此接口的操作中。 拦截器看起来像

 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 ); } 

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

 <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那么login的用户对象不仅在会话中可用,而且在操作中也可用,如果您为用户定义getter或使其受保护。 您必须使User对象不可变,以便不危害安全function。

您可以使用Filter 。 它会比要求所有类扩展BaseAction更透明。

编辑

您可以将此filter映射到您的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。 在这种情况下,你可以写一个拦截器而不是filter。 它基本上可以做同样的事情,但拦截器可以和其他的strutsconfiguration一起configuration。