在struts2应用程序中的会话

我创build了一个Web应用程序,在这个Web应用程序中,如果用户会话存在,我需要维护会话 ,然后只有这样才能让用户看到jsp。

我以前曾经用过jsp servlets,但是我是struts2的新手。

这里我在我的操作类中设置用户名

修订的代码

private HttpSession session; public void setSession(HttpSession session) { // TODO Auto-generated method stub0 this.session = session; } public HttpSession getSession() { return session; } public String getLoginStatus(){ session = request.getSession(); session.setAttribute("userName", loginBean.getUsername()); return SUCCESS; } 

现在,当一个动作被redirect到下一个页面时,它会显示一次会话值。 之后,在每个页面上,我在会话中find空值。

 <% String userName = (String)session.getAttribute("userName"); System.out.println(userName); if(userName == null || userName.equals("") ){ response.sendRedirect("login.jsp"); } %> 

我在某个地方读到一个动作课的范围只限于一个页面 – 我怎么能解决这个问题呢?

任何例子都会对我很有帮助。

目前您的代码存在一些问题。

  • 您应该使用拦截器来强制用户login,而不是试图在JSP中执行它。 JSP只能用于演示,而不能用于stream量控制。
  • 您应该避免在JSP中使用scriptlet(代码块)。 这在很久以前就被弃用了,在MVC应用程序中被广泛认为是非常糟糕的做法。
  • 您可以直接在JSP中访问会话值。 除非需要访问动作本身内的会话,否则不需要在动作中实现SessionAware接口。
  • 您应该将用户redirect到login操作,而不是直接到JSP页面,否则您将绕过Struts2框架并失去使用框架的好处。

login示例

以下是使用Struts2框架创build基本login系统的一些示例代码。

需要login

这部分是可选的,但是一般来说,Web应用程序中的所有页面都不需要用户login。因此,我们创build一个名为LoginRequired的接口。 如果用户尚未login,则任何实现此标记界面的操作都将redirect到login页面。

注意:如果您愿意,您可以使用注释,但对于此示例,我将使用该界面。

 public interface LoginRequired {} 

拦截器

拦截器将处理强制用户login以实现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(); } } 

您还需要一个显示和处理login页面的LogoutAction和一个使会话无效或清除的LogoutAction

configuration

您需要将拦截器添加到您的堆栈,并创build一个“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> 

要维护一个会话,在你的动作类中使用SessionAware接口,并实现int public void setSession(Map m) ,它将把这个属性作为一个键值对映射到一个可以从任何地方访问的地方获取检索关键字。

比如Action类

 import org.apache.struts2.interceptor.SessionAware; import com.opensymphony.xwork2.ActionSupport; public class LogingEx extends ActionSupport implements SessionAware{ private static final long serialVersionUID = 1L; private String stuname,stuage,country; private int stumarks; Map m; public String getStuname() { return stuname; } public void setStuname(String stuname) { this.stuname = stuname; } public String getStuage() { return stuage; } public void setStuage(String stuage) { this.stuage = stuage; } public String getCountry() { return country; } public void setCountry(String country) { this.country = country; } public int getStumarks() { return stumarks; } public void setStumarks(int stumarks) { this.stumarks = stumarks; } public void setSession(Map m) { this.m=m; } public String execute() { m.put("a",stuname); m.put("b", stuage); m.put("c",stumarks); m.put("d",country); return SUCCESS; } } 

消息来源: http : //www.java4s.com/struts-tutorials/example-on-struts-2-sessionaware-interface/

我觉得没有理由使用这种Map来授权用户。 如果你的要求只是validation用户对会话,那么我会build议使用Filter比在某些类的地图,这种地图的问题是删除会话对象,一旦会话失效,当然你可以使用HttpSessionListener它工作,但我想最好通过FilterMapvalidation。

除此之外,你可以看看许多安全框架(如Apache Shiro ),使您的任务更简单,更健壮。

你的Action类是否已经实现了SessionAware接口?

编辑:

试试这个(这是一个struts2风格的解决scheme):

 public class anAction implements SessionAware{ private Map<String, Object> session; public Map<String, Object> getSession() { return session; } public void setSession(Map<String, Object> session) { this.session = session; } public String getLoginStatus(){ session.put("userName", "test"); //Hard code here for testing. return SUCCESS; } } 

然后使用您的jsp代码来获取页面上的用户名。 我已经在我的机器上testing了这种方法,它工作。

编辑2:顺便说一句,这样的login检查可以轻松和优雅的Struts2框架提供的“拦截器”。

SessionAware实现不是必需的。

 public class LoginAction extends Actionsupport { private Map<String, Object> session; //Getter and Setter method public String execute() throws Exception { session=ActionContext.getContext().getSession(); session.put("userName", "test"); return super.execute(); } } 

下面的journaldev文章有更多的细节在上面的Steven响应的同一行上面http://www.journaldev.com/2210/struts-2-interceptor-tutorial-with-custom-authentication-interceptor-example