0

我现在正在学习 Struts 2,并尝试创建一个登录尝试计数器,以在 x 次尝试失败后阻止任何进一步的登录尝试。

这是我的 login.jsp 的正文

<body>

<h1><s:property value="loginAttempts"/></h1>

<s:form action="login">
    <s:textfield name="username" label="Username" />
    <s:password name="password" label="Password"/>
<%-- <s:hidden name="loginAttempts"  value="<s:property value="loginAttempts"/>" /> --%>
    <s:set var="loginAttempts"><s:property value="loginAttempts"/></s:set>
    <s:submit value="login"/>
</s:form>

</body>

还有我的 Action 类(我不包括带有 getter 和 setter 的私有 var,但它们都在那里)

public String execute() throws Exception{

    if (username.equals("admin")&& password.equals("admin"))
    {   return SUCCESS;}
    else if (Integer.parseInt(getLoginAttempts())>2)
    {
        return "lockout";
    }
    else
    {   setLoginAttempts(String.valueOf(Integer.parseInt(getLoginAttempts())+1));
        return "fail";}
}

在最初调用 login.jsp 的操作中,我传入一个初始值

loginAttempts="0";

这很好用。当我在 login.jsp 页面上点击提交时,问题就来了。

我得到以下堆栈跟踪

java.lang.NumberFormatException: null 
java.lang.Integer.parseInt(Integer.java:417)
java.lang.Integer.parseInt(Integer.java:499)
com.struts.users.LoginAction.execute(LoginAction.java:17)
sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)

第 17 行是

else if (Integer.parseInt(getLoginAttempts())>2)

每次我点击提交按钮时,loginAttempt它都会将变量重置为NULL.

谢谢

编辑:我知道这可能不是这样做的正确方法,我可能应该在会话中这样做。但是我试图理解为什么它不起作用。

4

1 回答 1

0

一个struts2的动作不是持久的!每次请求发生时都会重新创建它。
您需要做的是实现该ServletRequestAware操作的接口,这将使您可以访问HttpServletRequest,然后您可以获取您的网络服务器存储的 http 会话对象并增加其值。请小心,因为这需要是线程安全的 - 您可能需要在更新值时锁定 http 会话。
另一种方法是在ServletContext其中存储一个Map用于登录尝试的用户名的对象。这可能更可靠。

评论中的一些澄清:

您的表单将其上的值发送(称为 POST)到您的网络服务器,struts2 然后获取此“POST 数据”并为您解释它 - 使用您操作的相关设置器使您可以使用此数据。
因此,为了发送登录尝试值,您的表单需要将其作为变量,因此需要一个<s:hidden>. 然后,您的操作应该有一个用于登录尝试的设置器;即带有签名的方法setLoginAttempts(int loginAttempts)
现在,当您的操作完成并发现请求无效时,您希望增加该变量并在操作中为其提供一个 getter。
现在,您的 JSP(由尝试失败时的操作呈现)可以从操作中读取该值并将其添加到用户将发送的 HTML 表单中。因此我提到了一个圆圈。
此方法不会增加您网站的安全性,因为该变量loginAttempts是从用户 POST 数据中读取的 - 用户可以发送它想要的任何内容,并且您的操作会将其读取为登录尝试的次数。
我希望这会有所帮助...

于 2013-02-15T16:00:59.597 回答