【问题标题】:Checking a session value in Struts 2 web application [duplicate]在 Struts 2 Web 应用程序中检查会话值 [重复]
【发布时间】:2016-07-24 22:13:00
【问题描述】:

我正在使用 Struts 2 创建一个 Web 应用程序。其中有一个登录页面。当用户在输入用户名和密码后单击登录按钮时,将检查凭据,如果发现凭据正确,则创建会话并设置其属性并将控制重定向到 WELCOME JSP。

现在在打开welcome.jsp 之前,我想检查一下是否设置了会话属性。如何在 Struts 2 中做到这一点?

谁能给我解释一下拦截器的概念。我读到我们创建拦截器来在调用动作之前或之后执行任何功能。我可以在每次调用 WELCOME JSP 之前创建一个拦截器来检查会话是否已设置。

【问题讨论】:

标签: java jsp session authentication struts2


【解决方案1】:

您可以使用<s:if> 标签来测试您的属性在 Session 中是否存在。我假设您在您的操作类中设置值,这是您可以在 jsp 页面中执行此操作的方法

<s:if test="%{#session.logged_in ==true}">

我假设我在这里设置了一个标志,指示用户是否以类似的方式登录,您可以根据您的要求进行测试

对于拦截器,它们是 Struts2 开箱即用地提供的一组实用程序类,使您的生活变得轻松。拦截器只是具有框架提供的某些功能的 java 类,其中一些是

  1. 文件上传
  2. i18n
  3. 参数
  4. 令牌等

这些拦截器是根据您的应用程序中配置的拦截器堆栈调用的,它们将在两个地方被调用

  1. 当您向您的操作发送请求时
  2. 请求处理完成并呈现视图时。

在第一种情况下,它们将在您的操作执行或您定义的自定义方法被调用之前被调用,拦截器负责向您的操作类提供所需的数据,拦截器在您的操作调用之前完成的一些工作是

  1. 文件上传
  2. 处理 i18n
  3. 将表单值传递给操作类中的相关字段
  4. 验证您的数据

struts2 提供了一些拦截器,你可以看看struts-defaultxml

您可以创建任意数量的拦截器并配置它们以根据您的要求执行,您只需要扩展 AbstractInterceptor 并在 intercept(ActionInvocation invocation) 方法中提供您的自定义逻辑 我建议您按照下面提到的链接获得更多概述

building-your-own-interceptor Struts2 Interceptors writing-interceptors

【讨论】:

    【解决方案2】:

    @rickgaurav 回答您的第一个问题。进行这样的登录操作

    <action name="login_action" class="loginAction class">
                <result name="success" type="chain">welcomeAction</result>
                <result name="input">/index.jsp</result>
                <result name="error">/index.jsp</result>
            </action>
    

    index.jsp 是你的登录页面

    并在登录拦截器中首先制作一个会话映射,您的会话属性将存储在其中

    Map<String, Object> sessionAttributes = invocation
                .getInvocationContext().getSession();
    

    之后使用此条件进行检查

    if (sessionAttributes == null
                    || sessionAttributes.get("userName") == null
                    || sessionAttributes.get("userName").equals("")) {
    
                return "login";
            }else{
    if (!((String) sessionAttributes.get("userName")).equals(null)){
    return invocation.invoke();
    }else{
    return "login";
    }
    

    对于您的第二个问题,假设您正在调用welcomeAction 以转到welcome.jsp 页面 所以你可以添加这样的动作

    <action name="welcomeAction" class="class">
            <interceptor-ref name="logininterceptor"></interceptor-ref>
    
    
    
    
                <result name="login" type="chain">loginaction</result>
            <result name="success" >/welcome.jsp</result>
    
        </action>
    

    希望这对你有用

    【讨论】:

    • action "welcomeaction"对应的action类的execute方法中应该写什么。
    • 在welcomeaction类的execute方法中,我只是简单的返回了成功。现在,当我尝试使用正确的凭据登录时,它会显示一条错误消息,提示 INFINITE RECURSION DETECTED。 loginAction...Welcomeaction...loginAcction.....我应该应用任何改进吗?
    • @rickgaurav 你能告诉我你的 struts.xml 文件吗???
    • 嘿,只需从您的“登录”操作中删除 行。
    • 我从登录操作中删除了该行。
    【解决方案3】:
    1. 在 Struts.xml 中这样写:

      <interceptors> <interceptor name="loginInterceptor" class="com.mtdc.interceptor.LoginInterceptor"></interceptor> <interceptor-stack name="loginStack"> <interceptor-ref name="loginInterceptor"></interceptor-ref> <interceptor-ref name="defaultStack"></interceptor-ref> </interceptor-stack> </interceptors>

    2.现在在你想检查会话的动作之后输入:&lt;interceptor-ref name="loginStack"&gt;&lt;/interceptor-ref&gt;

    3.我们在struts.xml中的LoginAction:`

    <action name="login_action" class="com.action.LoginAction">
    
          <result name="success">/welcome.jsp</result>
          <result name="input">/login.jsp</result>
          <result name="error">/login.jsp</result> 
    
      </action>
    

    `

    4.现在为 make com,interceptor.LoginInterceptor 定义 LOGin 拦截器:

    `
    
        public String intercept(ActionInvocation invocation) throws Exception {
    
                Map<String, Object> sessionAttributes = invocation
                        .getInvocationContext().getSession();
                if (sessionAttributes == null
                        || sessionAttributes.get("userName") == null
                        || sessionAttributes.get("userName").equals("")) {
    
                    return "login";
                } else {
    
                    if (!((String) sessionAttributes.get("userName")).equals(null)
                            || !((String) sessionAttributes.get("userName")).equals("")) {
    
                        return invocation.invoke();
                    } else {
    
                        return "login";
                    }
                }
            }
    
    `
    

    [5]。现在在您分配会话的地方创建登录操作类:

    ` 
    
        public String execute() {
    
            String result = LOGIN;
            UserLogin userlogin;
            try {
                userlogin = userlogindao.authenticateUser(signin_username, signin_password);
                if (userlogin != null && userlogin.getUsername() != null) {
    
                session.put("userID", userlogin.getUserId());
                session.put("userName", userlogin.getUsername());
    
    
                result = SUCCESS;
                } else {
    
                result = LOGIN;
                }
            } catch (Exception e) {
                result = LOGIN;
    
    
                e.printStackTrace();
            }
            return result;
            }
    
    `
    

    [6]。现在在您的登录页面上单击调用操作 LoginAction 的最后一步。

    【讨论】:

    • 感谢您的回答。您能否解释一下,您的拦截器代码中的每个 if 条件是做什么的?
    • 在第一个'If'中检查是否有会话属性为空?如果“是”,则返回“登录”并将您重定向到登录页面。第一个“如果”为假,然后转到其他地方,它检查会话属性不等于空,如果它为真,则调用调用意味着我们放置拦截器的操作将调用。是的,你只能通过一个 if..else.... 来编辑这个逻辑。你清楚了吗?
    【解决方案4】:

    是的,您可以使用拦截器。 制作一个 Action 类,它将像这样在会话中存储用户的 UserId / Username(用户通过身份验证后)。

    session.put("userID", userlogin.getUserId());
    

    之后创建一个拦截器类。拦截器

    public class LoginInterceptor implements **Interceptor** {  
    
    public String intercept(ActionInvocation invocation) throws Exception {
    

    使用获取会话属性

    sessionAttributes.get("userId");
    

    如果为null,则检查它不为null,然后返回login以将用户转发到登录页面 否则返回 invocation.invoke();继续操作。

    并在struts.xml文件中配置包内的拦截器

    <interceptors>
                <interceptor name="loginInterceptor" class=".....LoginInterceptor"></interceptor>
                <interceptor-stack name="loginStack">
                    <interceptor-ref name="loginInterceptor"></interceptor-ref>
                    <interceptor-ref name="defaultStack"></interceptor-ref>
                </interceptor-stack>
            </interceptors>
    

    你可以写成行动

    <action name="anything" class="anyclass" method="default">
                <interceptor-ref name="loginStack"></interceptor-ref>
    
        <result name="login">/index.jsp</result>
    
                <result name="success" type="redirect">success.jsp</result>
    
        </action>
    

    【讨论】:

    • 这种小东西不需要实现拦截器。
    • @prtk_shah 感谢您的回答。我试过了,你的回答。问题是,只要我输入我的登录凭据,拦截器就会被调用并检查是否设置了 sessionattribute 用户 ID,这显然是空的,因为我们还没有检查凭据。我想要一个仅在我的凭据被检查后调用拦截器的解决方案,即在我的操作被调用之后。如果我通过写 URL 直接打开欢迎页面 jsp,你能告诉我会发生什么吗?在这种情况下,我还能做任何将用户重定向到登录页面的事情吗?
    猜你喜欢
    • 2011-03-05
    • 1970-01-01
    • 1970-01-01
    • 2012-03-23
    • 1970-01-01
    • 1970-01-01
    • 2014-11-22
    • 2012-06-21
    • 2021-12-24
    相关资源
    最近更新 更多