您当前的代码存在一些问题。
- 您应该使用拦截器来强制用户登录,而不是尝试在 JSP 中强制它。 JSP 应该只用于展示,而不是用于流控制。
- 您应该避免在 JSP 中使用 scriptlet(代码块)。这在很久以前就被弃用了,并且被广泛认为是 MVC 应用程序中非常糟糕的做法。
- 您可以直接访问 JSP 中的会话值。除非您需要访问操作本身内部的会话,否则您无需在操作中实现
SessionAware 接口。
- 您应该将用户重定向到登录操作,而不是直接到 JSP 页面,否则您将绕过 Struts2 框架并失去使用该框架的好处。
登录示例
下面是一些使用 Struts2 框架创建基本登录系统的示例代码。
需要登录
这部分是可选的,但一般来说,并不是Web应用程序中的所有页面都需要用户登录。因此,让我们创建一个名为LoginRequired的接口。如果用户尚未登录,任何实现此标记接口的操作都将重定向到登录页面。
注意:如果您愿意,可以使用注解代替,但在本例中,我将使用接口。
public interface LoginRequired {}
拦截器
拦截器将强制用户登录任何实现LoginRequired接口的请求操作。
public class LoginInterceptor extends AbstractInterceptor {
@Override
public String intercept(final ActionInvocation invocation) throws Exception {
Map<String, Object> session = ActionContext.getContext().getSession();
// sb: feel free to change this to some other type of an object which
// represents that the user is logged in. for this example, I am using
// an integer which would probably represent a primary key that I would
// look the user up by with Hibernate or some other mechanism.
Integer userId = (Integer) session.get("userId");
// sb: if the user is already signed-in, then let the request through.
if (userId != null) {
return invocation.invoke();
}
Object action = invocation.getAction();
// sb: if the action doesn't require sign-in, then let it through.
if (!(action instanceof LoginRequired)) {
return invocation.invoke();
}
// sb: if this request does require login and the current action is
// not the login action, then redirect the user
if (!(action instanceof LoginAction)) {
return "loginRedirect";
}
// sb: they either requested the login page or are submitting their
// login now, let it through
return invocation.invoke();
}
}
您还需要一个用于显示和处理登录页面的LoginAction 和一个用于使会话无效或清除会话的LogoutAction。
配置
您需要将拦截器添加到您的堆栈中,并为“loginRedirect”创建一个全局结果映射。
<interceptors>
<interceptor name="login" class="your.package.LoginInterceptor"/>
<!-- sb: you need to configure all of your interceptors here. i'm only
listing the one we created for this example. -->
<interceptor-stack name="yourStack">
...
<interceptor-ref name="login"/>
...
</interceptor-stack>
</interceptors>
<global-results>
<!-- sb: make this the path to your login action.
this could also be a redirectAction type. -->
<result name="loginRedirect" type="redirect">/login</url>
</global-results>