a我考网

 找回密码
 立即注册

QQ登录

只需一步,快速开始

扫一扫,访问微社区

查看: 662|回复: 0

[专业语言] Java认证之怎么样防止重复提交java解决

[复制链接]
发表于 2012-8-4 12:44:44 | 显示全部楼层 |阅读模式
Java认证之怎么样防止重复提交java解决  X% }$ o4 Y3 a; P3 d8 e1 e
B/S结构的软件开发中,特别是在越大型的分布式应用中体现的越明显,后端的处理往往会因为出现较多的时间消耗而引起延迟,这种延迟有可能过长而最终使用户认为是自己的操作错误,导致他们重新提交请求,由于任务的重复提交,服务器资源大部分被占用,情节严重可能出现类似死机现象。9 m7 }5 I1 ~( y
预期达到目标:
8 @8 d& p) P! X) v% ~* }1、当用户进行的是Refresh/Reload/Back/Forward操作、以及先Back再Submit操作时,仅仅是reloading先前的结果页。4 K6 Y( x# V6 C9 h9 F3 F
2、当用户重复提交同一个任务操作时,后台服务接收并处理第一次提交的任务,后面提交不起作用(不转向也不提示)。, i& L5 F4 s( G8 C% t4 ^$ \% W3 E% p
3、该功能具有公用性。
4 B# y7 L: n, O' o1 J+ e, n7 `基本形成思路:  ~1 j# f$ r- [0 I5 |( m
1、在basic filter中实现公用性
" m; o% i0 w0 v- Wif(true){//问题1:如何确定是否为重复提交
+ J. B! w" e' g6 S。..' s; `$ I5 r+ l6 T3 b
chain.doFilter(request,response);* e. a9 h! u6 k
}else{8 {, {0 l. K8 Q/ F( N3 e" Q! J
//问题2:如何实现不转向、不提示也不显示空白页
* f7 j. K! d$ Z5 J3 T}
/ ?! H' a" I5 v9 F  U% t2、网上资料概括& a% |  k+ {3 |( J2 u
a、提交表单后按钮变灰/隐藏提交按钮
5 R. e8 V3 A1 Fb、在js里设置全局变量,提交后修改该变量的值,依据变量的值判断是否重复提交
& }1 b0 F4 Y2 h7 mvar flag=true;+ f: r9 `8 f# M" P8 ?8 |+ Y7 d6 I
function checkForm(){
% y1 W) c. p  C% P3 D# J. ]if (flag==false){
/ `+ C1 i3 @- u. q: u- ?return;
, f6 H( J, A/ i  S1 c}
  h& Y7 C- m' J' S' C9 r+ Dflag=false;
; P4 N1 B# x* Xdocument.form1.submit();) L  ?/ ]% s: |+ k* `6 q( c" x
}# c1 i+ j7 a) L7 H3 H8 c" v
c、struts (webwork没有找到这个资料)* L; D! X$ \: i6 G3 x5 I: {
//验证事务控制令牌,会自动根据session中标识生成一个隐含input代表令牌,防止两次提交
$ O- [' z& d1 q在action中:
$ }$ M/ \7 w7 n//
6 W2 l2 t. }5 @* v" f. P; v5 l! Rif (!isTokenValid(request))2 ^  z3 H/ A, q- \/ E( X
errors.add(ActionErrors.GLOBAL_ERROR,/ U2 S& r1 H$ k& P- p# E% B
new ActionError(“error.transaction.token”));- }) ]9 x# i; r6 J- {+ ^: `2 m
resetToken(request); //删除session中的令牌* ]7 W4 _9 [5 H$ V5 \
action有这样的一个方法生成令牌华
) ^1 ~5 ?  a+ |3 D6 }1 hprotected String generateToken(HttpServletRequest request) {6 k1 I6 n4 O. U$ Y; P
HttpSession session = request.getSession();
# N8 t, d8 \6 Z4 D4 {1 l' [
5 [$ F+ J- e8 W: V, l+ _- c
( i. z6 m; `5 y9 o! y/ Xtry {0 l% j3 q' M! s, o5 e
byte id[] = session.getId().getBytes();
) S! ]% ~. @$ |. P& p, Mbyte now[] =
: s4 ~7 v3 O( s6 x5 Q7 unew Long(System.currentTimeMillis()).toString().getBytes();
) d; g; \- p' D1 Y. {5 v" OMessageDigest md = MessageDigest.getInstance(“MD5”);
% b3 C' A4 C& q' `md.update(id);' t. o2 x0 j2 ^# S7 Z
md.update(now);& T) R/ |! D/ _) S6 ]! x
return (toHex(md.digest()));
5 Y4 L0 b2 ^# f1 W9 n} catch (IllegalStateException e) {
) S- K$ v5 A% g2 s* areturn (null);
. E, {7 l( M. r9 B} catch (NoSuchAlgorithmException e) {
3 v* R" e/ g3 D' k: l( d2 a. sreturn (null);
7 X: U( x' m9 {5 h, b3 {  j( ^}
+ A; ~$ r7 P3 _6 K}& s# K! Z* @; u" z- i
d、用户使用浏览器时,可以经常使用向后的按钮,因此就有可能重复提交一个他们已经提交过的form,这样就会带来一个重复事务处理的问题。同样,一个用户也可能在接收到一个确认的页面之前按下停止的按钮,接着再次提交同一个form。对于这些情况,我们都想跟踪并且禁止这些重复的提交,我们可以使用一个控制servlet来提供一个控制点,以解决这个问题。
8 y! _" e; c0 ?6 N. a同步记号(Synchronizer (or Dvu) Token)& T' l8 R9 F- _" C3 B
这个策略是为了解决重复的form提交问题。一个同步的记号被设置在一个用户的Session中,并且包含在返回到客户的每一个form中。当form被提交时,form中的同步标记就和Session中的同步标记作对比。在form首次提交的时候,这两个标记应该是一样的。如果标记不一样,那么该form就会禁止提交,一个错误就会返回给用户。在用户提交一个form时,如果按下浏览器中的后退按钮并尝试重新提交同一个form时,标记就会出现不匹配的现象。
' G8 B; Z: n1 d7 Z另一方面,如果两个标记值匹配,那么我们就可以确信整个流程是正确的。在这种情况下,
$ V& S4 g0 ~/ I7 m另一方面,如果两个标记值匹配,那么我们就可以确信整个流程是正确的。在这种情况下,Session中的标记值就会被修改为一个新的值,同时允许提交该form。
8 Q: s/ [2 r! H7 |+ v7 V  _7 A( R* H你也可以使用这个策略来控制对某些页面的直接访问,就好象上面资源保护中描述的一样。例如,假设一个用户将某个应用的页面A收藏到收藏夹中,而页面A只允许通过页面B和C访问。当用户直接通过收藏夹来访问页面A,这时页面的访问顺序就是不正确的,这样同步标记将处在一个不同步的状态,或者它根本就不存在。不论怎样,访问都被禁止了。+ B( F2 L& `6 e6 A
e、做一个hidden框,名字自己定,提交后得到这个值放入session,提交前判断session是否为空7 w" f) \5 m' e! R) [1 _. R) C' q
解决方案:# [9 V  u2 D' M5 d$ }0 D
1、后台公共类中实现前台的Form中自动生成两个hidden文本功能,一个是作page是否重复提交判断,并由系统自动附上关键值(如struts采用的方案);另一个作为button是否重复提交判断(struts中好像没有)。由后台公共类实现界面两个hidden text自动生成的好处在于公用性。
8 B' {7 _  Y7 L/ S2、在basic filter中根据两个hidden text值判断是否为重复提交。
3 R2 j, L7 j4 n# I3、javascript中作一个公共方法,实现功能:如果需要判断是否重复提交,就给第二个hidden text附上关键值,并使该功能不可用。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

Archiver|手机版|小黑屋|Woexam.Com ( 湘ICP备18023104号 )

GMT+8, 2024-9-27 19:52 , Processed in 0.163594 second(s), 22 queries .

Powered by Discuz! X3.4 Licensed

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表