我现在正在学习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
。
由于
编辑:我明白这可能不是正确的做法,我应该用会话这样做。但是我试图理解它为什么不起作用。
答案 0 :(得分:0)
struts2动作不是持久的!每次请求发生时都会重新创建
您需要做的是为操作实现ServletRequestAware
界面,以便您访问HttpServletRequest
,然后您可以使用您的网络服务器存储的http会话对象,并在其上增加值。要小心,因为这需要线程安全 - 您可能需要在更新值时锁定http会话
另一种方法是在ServletContext
中有一个对象,用于存储Map
用户名以进行登录尝试。这可能更可靠。
评论中的一点澄清:
您的表单将其上的值(称为POSTing)发送到您的网络服务器,然后struts2接收此“POST数据”并为您解释它 - 使用您操作中的相关设置程序为您提供此数据。
因此,为了发送登录尝试值,您的表单需要将其作为变量,因此需要<s:hidden>
。那么你的行动应该有一个loginattempts的setter;即具有签名setLoginAttempts(int loginAttempts)
的方法
现在,当您的操作完成并发现请求无效时,您希望增加该变量并在操作中为其提供一个getter。
现在,您的JSP(由尝试失败的操作呈现)可以从操作中读取该值,并将其添加到用户将发送的HTML表单中。因此我提到了一个圆圈
从用户POST数据中读取变量loginAttempts
时,此方法无法添加到您网站的安全性 - 用户可以发送任何想要的内容,您的操作将读取该次数作为登录尝试次数。
我希望有帮助......