[英]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. 您目前拥有的代码存在一些问题。
SessionAware
interface in your action unless you need access to the session inside of the action itself. 除非需要访问操作本身内部的会话,否则不需要在操作中实现SessionAware
接口。 Below is some example code for creating a basic login system using the Struts2 framework. 下面是使用Struts2框架创建基本登录系统的一些示例代码。
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 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
其无效或清除会话。
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.