JavaWeb中HttpSession中表单的重复提交示例
表单的重复提交
- 重复提交的情况:
①.在表单提交到一个Servlet,而Servlet又通过请求转发的方式响应了一个JSP(HTML)页面,此时地址栏还保留着Servlet的那个路径,在响应页面点击“刷新”。
②.在响应页面没有到达时,重复点击“提交按钮”
③.点击返回,再点击提交
- 不是重复提交的情况:点击“返回”,“刷新”原表单页面,再点击提交。
- 如何避免表单的重复提交:在表单中做一个标记,提交到Servlet时,检查标记是否存在且和预定义的标记一样,若一致,则受理请求,并销毁标记,若不一致或没有标记,则直接响应提示信息:“重复提交”
①仅提供一个隐藏域不行:<inputtype="hidden"name="token"value="lsy">
②把标记放在Request中,行不通,表单页面刷新后,request已经被销毁,再提交表单是一个新的request的。
③把标记放在Session中,可以
1.在原表单页面,生成一个随机值token
2.在原表单页面,把token值放入session属性中
3.在原表单页面,把token值放入到隐藏域
4.在目标的Servlet中:获取session和隐藏域中的token值
比较两个值是否一致,受理请求,且把session域中的token属性清除,若不一致,则直接响应提示页面:“重复提交”
我们可以通过Struts1中写好的类TokenProcessor来重构代码,面向组件编程
packagecom.lsy.javaweb; importjavax.servlet.http.HttpServletRequest; importjavax.servlet.http.HttpSession; importjava.security.MessageDigest; importjava.security.NoSuchAlgorithmException; publicclassTokenProcessor{ privatestaticfinalStringTOKEN_KEY="TOKEN_KEY"; privatestaticfinalStringTRANSACTION_TOKEN_KEY="TRANSACTION_TOKEN_KEY"; /** *Thesingletoninstanceofthisclass. */ privatestaticTokenProcessorinstance=newTokenProcessor(); /** *Thetimestampusedmostrecentlytogenerateatokenvalue. */ privatelongprevious; /** *ProtectedconstructorforTokenProcessor.Use *TokenProcessor.getInstance()toobtainareferencetotheprocessor. */ protectedTokenProcessor(){ super(); } /** *Retrievesthesingletoninstanceofthisclass. */ publicstaticTokenProcessorgetInstance(){ returninstance; } /** *<p> *Return<code>true</code>ifthereisatransactiontokenstoredinthe *user'scurrentsession,andthevaluesubmittedasarequestparameter *withthisactionmatchesit.Returns<code>false</code>underanyofthe *followingcircumstances: *</p> * *<ul> * *<li>Nosessionassociatedwiththisrequest</li> * *<li>Notransactiontokensavedinthesession</li> * *<li>Notransactiontokenincludedasarequestparameter</li> * *<li>Theincludedtransactiontokenvaluedoesnotmatchthetransaction *tokenintheuser'ssession</li> * *</ul> * *@paramrequest *Theservletrequestweareprocessing */ publicsynchronizedbooleanisTokenValid(HttpServletRequestrequest){ returnthis.isTokenValid(request,false); } /** *Return<code>true</code>ifthereisatransactiontokenstoredinthe *user'scurrentsession,andthevaluesubmittedasarequestparameter *withthisactionmatchesit.Returns<code>false</code> * *<ul> * *<li>Nosessionassociatedwiththisrequest</li> *<li>Notransactiontokensavedinthesession</li> * *<li>Notransactiontokenincludedasarequestparameter</li> * *<li>Theincludedtransactiontokenvaluedoesnotmatchthetransaction *tokenintheuser'ssession</li> * *</ul> * *@paramrequest *Theservletrequestweareprocessing *@paramreset *Shouldweresetthetokenaftercheckingit? */ publicsynchronizedbooleanisTokenValid(HttpServletRequestrequest,booleanreset){ //Retrievethecurrentsessionforthisrequest HttpSessionsession=request.getSession(false); if(session==null){ returnfalse; } //Retrievethetransactiontokenfromthissession,and //resetitifrequested Stringsaved=(String)session.getAttribute(TRANSACTION_TOKEN_KEY); if(saved==null){ returnfalse; } if(reset){ this.resetToken(request); } //Retrievethetransactiontokenincludedinthisrequest Stringtoken=request.getParameter(TOKEN_KEY); if(token==null){ returnfalse; } returnsaved.equals(token); } /** *Resetthesavedtransactiontokenintheuser'ssession.Thisindicates *thattransactionaltokencheckingwillnotbeneededonthenextrequest *thatissubmitted. * *@paramrequest *Theservletrequestweareprocessing */ publicsynchronizedvoidresetToken(HttpServletRequestrequest){ HttpSessionsession=request.getSession(false); if(session==null){ return; } session.removeAttribute(TRANSACTION_TOKEN_KEY); } /** *Saveanewtransactiontokenintheuser'scurrentsession,creatinga *newsessionifnecessary. * *@paramrequest *Theservletrequestweareprocessing */ publicsynchronizedStringsaveToken(HttpServletRequestrequest){ HttpSessionsession=request.getSession(); Stringtoken=generateToken(request); if(token!=null){ session.setAttribute(TRANSACTION_TOKEN_KEY,token); } returntoken; } /** *Generateanewtransactiontoken,tobeusedforenforcingasingle *requestforaparticulartransaction. * *@paramrequest *Therequestweareprocessing */ publicsynchronizedStringgenerateToken(HttpServletRequestrequest){ HttpSessionsession=request.getSession(); returngenerateToken(session.getId()); } /** *Generateanewtransactiontoken,tobeusedforenforcingasingle *requestforaparticulartransaction. * *@paramid *auniqueIdentifierforthesessionorothercontextinwhich *thistokenistobeused. */ publicsynchronizedStringgenerateToken(Stringid){ try{ longcurrent=System.currentTimeMillis(); if(current==previous){ current++; } previous=current; byte[]now=newLong(current).toString().getBytes(); MessageDigestmd=MessageDigest.getInstance("MD5"); md.update(id.getBytes()); md.update(now); returntoHex(md.digest()); }catch(NoSuchAlgorithmExceptione){ returnnull; } } /** *ConvertabytearraytoaStringofhexadecimaldigitsandreturnit. * *@parambuffer *Thebytearraytobeconverted */ privateStringtoHex(byte[]buffer){ StringBuffersb=newStringBuffer(buffer.length*2); for(inti=0;i<buffer.length;i++){ sb.append(Character.forDigit((buffer[i]&0xf0)>>4,16)); sb.append(Character.forDigit(buffer[i]&0x0f,16)); } returnsb.toString(); } }
以上所述是小编给大家介绍的JavaWeb中HttpSession中表单的重复提交示例,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对毛票票网站的支持!