简体   繁体   English

struts2应用程序中的会话

[英]Sessions in struts2 application

I have created a web application in which I need to maintain the session if a user session is there, and then and only then will it allow the user to see the jsp. 我创建了一个Web应用程序,如果有用户会话,我需要维护会话 ,然后只有这样才能让用户看到jsp。

I have worked with jsp servlets before, but I'm new to struts2. 我之前使用过jsp servlet,但我是struts2的新手。

Here I am setting username in my action class : 这里我在我的动作类中设置用户名

Revised Code 修订后的守则

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

Now, when I am redirected to next page after an action, it shows the session value once. 现在,当我在操作后重定向到下一页时,它会显示一次会话值。 After that, on every page, I am finding null values in session. 之后,在每个页面上,我在会话中找到空值。

<%
    String userName = (String)session.getAttribute("userName");             
    System.out.println(userName);                        

    if(userName == null || userName.equals("") ){
        response.sendRedirect("login.jsp");
    }

%>

I read somewhere that the scope of an action class session is limited to one page - how could I solve this problem? 我在某处读到动作类会话的范围仅限于一页 - 我该如何解决这个问题?

Any example will be very helpful to me. 任何例子都对我很有帮助。

There are a few problems with the code you currently have. 您目前拥有的代码存在一些问题。

  • You should use an Interceptor to enforce that the user is logged in, rather than trying to enforce it in the JSP. 您应该使用Interceptor强制用户登录,而不是尝试在JSP中强制执行它。 JSP should only be for presentation, not for flow control. JSP应仅用于表示,而不用于流控制。
  • You should avoid scriptlets (blocks of code) in JSP. 您应该避免在JSP中使用scriptlet(代码块)。 That was deprecated a really long time ago and is widely considered to be a very poor practice in an MVC application. 很久以前就被弃用了,并且在MVC应用程序中被广泛认为是一种非常糟糕的做法。
  • You can access session values in your JSP directly. 您可以直接访问JSP中的会话值。 You do not need to implement the SessionAware interface in your action unless you need access to the session inside of the action itself. 除非需要访问操作本身内部的会话,否则不需要在操作中实现SessionAware接口。
  • You should redirect the user to a login action, not directly to a JSP page, otherwise you are bypassing the Struts2 framework and losing out on the benefits of using the framework. 您应该将用户重定向到登录操作,而不是直接重定向到JSP页面,否则您将绕过Struts2框架并失去使用框架的好处。

Login Example 登录示例

Below is some example code for creating a basic login system using the Struts2 framework. 下面是使用Struts2框架创建基本登录系统的一些示例代码。

Login Required 要求登录

This part is optional, but in general, not all pages in a web application will require the user to be logged in. Therefore, let's create an interface called LoginRequired . 这部分是可选的,但一般而言,Web应用程序中的所有页面都不需要用户登录。因此,让我们创建一个名为LoginRequired的界面。 Any action that implements this marker interface will redirect to the login page if the user is not already logged in. 如果用户尚未登录,则实现此标记接口的任何操作都将重定向到登录页面。

Note: You can use an annotation instead, if you prefer, but for this example I will use the interface. 注意:如果您愿意,可以使用注释,但是对于此示例,我将使用该界面。

public interface LoginRequired {}

The Interceptor 拦截器

The interceptor will handle forcing the user to login for any requested action which implements the LoginRequired interface. 拦截器将处理强制用户登录任何实现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();
    }
}

You will also need a LoginAction which displays and processes the login page and a LogoutAction which invalidates or clears the session. 您还需要一个LoginAction ,显示和处理登录页面和LogoutAction其无效或清除会话。

The Configuration 配置

You will need to add the interceptor to your stack and also create a global result mapping for "loginRedirect". 您需要将拦截器添加到堆栈中,并为“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>

To maintain a session use SessionAware interface in your action class and implement int public void setSession(Map m) it will take the attribute as a key value pair in map which can be be access from any where just buy retrieving the key. 要维护会话,请在您的操作类中使用SessionAware接口并实现int public void setSession(Map m) ,它将把该属性作为映射中的键值对,可以从任何只需购买检索键的位置进行访问。

for example Action class 例如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;
    }

}

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

I find no reason to use this kind of Map to authorize user. 我没有理由使用这种Map来授权用户。 If your requirement is only validate the user against session then I would recommend to use Filter than some map in some class, the problem with this kind of map is to remove the session objects once session is invalidated, of course you can use HttpSessionListener to make it work but I guess it's best to validate via Filter than Map . 如果你的要求只是针对会话验证用户,那么我建议使用Filter不是某些类中的某个map,这种映射的问题是在会话失效后删除会话对象,当然你可以使用HttpSessionListener来制作它工作,但我想最好通过Filter不是Map进行验证。

Apart from it you can take a look at many security framework (like Apache Shiro ) to make your task simpler and more robust. 除此之外,您还可以查看许多安全框架(如Apache Shiro ),以使您的任务更简单,更健壮。

Has your Action class already implemented the SessionAware interface? 您的Action类是否已实现SessionAware接口?

EDIT: 编辑:

Try this(It's a struts2 style solution): 试试这个(这是一个struts2风格的解决方案):

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

Then use your jsp code to get the userName on page. 然后使用您的jsp代码在页面上获取userName。 I've tested this approach on my machine and it works. 我已经在我的机器上测试了这种方法并且它有效。

EDIT2: BTW, such login check can be done easily and elegant with "Interceptor" provided by Struts2 Framework. EDIT2:BTW,这种登录检查可以通过Struts2 Framework提供的“Interceptor”轻松优雅地完成。

SessionAware implemention not required. 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();
   }
} 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM