有没有办法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。