a我考网

 找回密码
 立即注册

QQ登录

只需一步,快速开始

扫一扫,访问微社区

查看: 571|回复: 0

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

[复制链接]
发表于 2012-8-4 12:44:44 | 显示全部楼层 |阅读模式
Java认证之怎么样防止重复提交java解决, T8 f4 u# F- E4 a
B/S结构的软件开发中,特别是在越大型的分布式应用中体现的越明显,后端的处理往往会因为出现较多的时间消耗而引起延迟,这种延迟有可能过长而最终使用户认为是自己的操作错误,导致他们重新提交请求,由于任务的重复提交,服务器资源大部分被占用,情节严重可能出现类似死机现象。  g* Y1 Z3 ?* j2 k& `
预期达到目标:
* x6 L$ k4 u2 @3 s1、当用户进行的是Refresh/Reload/Back/Forward操作、以及先Back再Submit操作时,仅仅是reloading先前的结果页。' `/ N' D6 \: ?
2、当用户重复提交同一个任务操作时,后台服务接收并处理第一次提交的任务,后面提交不起作用(不转向也不提示)。* Q$ p1 k  {; E/ h& j$ f: Z- R$ p
3、该功能具有公用性。  f5 ]7 y: {1 E
基本形成思路:
# t6 y3 `" G0 A5 E- O3 S, r0 Q9 A1、在basic filter中实现公用性& }8 K  G1 p. j+ X7 _
if(true){//问题1:如何确定是否为重复提交
+ T7 A' ~$ ]. ~9 q6 G! J4 S4 x, m。..) V/ |( z! u0 p% k
chain.doFilter(request,response);2 A  n  Y9 V, b4 ~5 \/ L( R
}else{& C7 y' R- v- k; @# X* D
//问题2:如何实现不转向、不提示也不显示空白页
* @+ s  c( b6 v9 |9 ~}2 t, f2 M: ^/ C; k  A0 q
2、网上资料概括
3 r% m# ^. s. U6 Y; @a、提交表单后按钮变灰/隐藏提交按钮
, T% R! W: N" Q& A/ }b、在js里设置全局变量,提交后修改该变量的值,依据变量的值判断是否重复提交  s2 ?" D5 G4 U( i# ^$ S
var flag=true;3 D2 E7 H+ k( Y6 w' s# w: E
function checkForm(){6 Z  o% u) b2 \( Z
if (flag==false){4 n+ w' S) s& \& }9 [* h
return;2 l/ p# d' w. ?5 E1 Y' J0 ?
}) o, G% \* ~4 A. v* R/ }+ H( J
flag=false;
- F- l1 H0 }9 u3 L" Pdocument.form1.submit();; M& @! Q$ B( f$ W* U: l( O
}
1 D9 {8 M5 J- O1 K5 l+ q; D0 Ic、struts (webwork没有找到这个资料)! d  B' W$ Y- x' @+ \& A  Q3 Q1 o
//验证事务控制令牌,会自动根据session中标识生成一个隐含input代表令牌,防止两次提交% Y4 c# o/ Y) k; D) V
在action中:
2 M3 R+ L" b* P5 ^//! b1 [$ L2 L" I7 l' D
if (!isTokenValid(request))+ ^) d+ B- f9 Q. t+ d$ l
errors.add(ActionErrors.GLOBAL_ERROR,
  n( Q( b) O$ _. ]$ d- B' Y8 {new ActionError(“error.transaction.token”));
8 e: g9 b% l, t  O' Y6 ~resetToken(request); //删除session中的令牌2 ^- r" \) F/ I" V. b
action有这样的一个方法生成令牌华, ~5 J% A9 N2 x5 A+ z- g4 e+ _. B
protected String generateToken(HttpServletRequest request) {
/ ^4 _( {- n% Y1 W$ d4 fHttpSession session = request.getSession();# ~0 y! U/ D2 R! r

- x* {4 W8 J3 O, u) a% s; l% D
" I0 |) C3 C6 _* N' \- C7 ctry {2 e" k# ^& e* ]/ O; O+ w  K2 ~
byte id[] = session.getId().getBytes();4 x8 ~4 u: `* q- A5 Y/ I6 X* R9 g$ ~
byte now[] =# `8 u6 @5 W: q; c- b
new Long(System.currentTimeMillis()).toString().getBytes();) x7 ]8 [7 E9 P0 E2 C$ S/ ?
MessageDigest md = MessageDigest.getInstance(“MD5”);
, y: |  }8 i0 [$ T' |md.update(id);1 R/ H  b& K: A* J; j" x6 u# F' |
md.update(now);
5 n9 j+ a: H2 J4 U+ k1 Yreturn (toHex(md.digest()));7 I/ l, Q% H; W0 O: D8 H  s
} catch (IllegalStateException e) {
7 r' O8 N4 H- ?: e7 `return (null);
% p- P- I' l, `7 t+ r9 S) ^} catch (NoSuchAlgorithmException e) {! B0 y4 O  ~; e: l2 @
return (null);; X8 x5 U- m" Y2 y# u0 ]
}
* M" y0 |; B$ r/ g}. M9 I- k& ]6 Q/ w5 h2 [/ o4 m
d、用户使用浏览器时,可以经常使用向后的按钮,因此就有可能重复提交一个他们已经提交过的form,这样就会带来一个重复事务处理的问题。同样,一个用户也可能在接收到一个确认的页面之前按下停止的按钮,接着再次提交同一个form。对于这些情况,我们都想跟踪并且禁止这些重复的提交,我们可以使用一个控制servlet来提供一个控制点,以解决这个问题。. y1 ^. d. P' u7 q8 c
同步记号(Synchronizer (or Dvu) Token)
- b9 u: f' D* s! t! B" _+ |这个策略是为了解决重复的form提交问题。一个同步的记号被设置在一个用户的Session中,并且包含在返回到客户的每一个form中。当form被提交时,form中的同步标记就和Session中的同步标记作对比。在form首次提交的时候,这两个标记应该是一样的。如果标记不一样,那么该form就会禁止提交,一个错误就会返回给用户。在用户提交一个form时,如果按下浏览器中的后退按钮并尝试重新提交同一个form时,标记就会出现不匹配的现象。6 @3 W# k/ R) ~  O" u- ?
另一方面,如果两个标记值匹配,那么我们就可以确信整个流程是正确的。在这种情况下,; M, P0 A) G; ?4 X8 u. T+ p
另一方面,如果两个标记值匹配,那么我们就可以确信整个流程是正确的。在这种情况下,Session中的标记值就会被修改为一个新的值,同时允许提交该form。
$ M: J5 H8 U8 j% W你也可以使用这个策略来控制对某些页面的直接访问,就好象上面资源保护中描述的一样。例如,假设一个用户将某个应用的页面A收藏到收藏夹中,而页面A只允许通过页面B和C访问。当用户直接通过收藏夹来访问页面A,这时页面的访问顺序就是不正确的,这样同步标记将处在一个不同步的状态,或者它根本就不存在。不论怎样,访问都被禁止了。, j4 T7 }/ W- N+ N5 b# J0 \5 V( F
e、做一个hidden框,名字自己定,提交后得到这个值放入session,提交前判断session是否为空) O9 N; \7 q. U$ @
解决方案:- x5 Q/ f3 u1 w* d/ [  A' U
1、后台公共类中实现前台的Form中自动生成两个hidden文本功能,一个是作page是否重复提交判断,并由系统自动附上关键值(如struts采用的方案);另一个作为button是否重复提交判断(struts中好像没有)。由后台公共类实现界面两个hidden text自动生成的好处在于公用性。
9 p2 a' \6 ~% s& M3 z* u# s2、在basic filter中根据两个hidden text值判断是否为重复提交。' U9 L/ P( C- U. \$ C) u6 d
3、javascript中作一个公共方法,实现功能:如果需要判断是否重复提交,就给第二个hidden text附上关键值,并使该功能不可用。
回复

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-5-10 01:31 , Processed in 0.246099 second(s), 21 queries .

Powered by Discuz! X3.4 Licensed

© 2001-2017 Comsenz Inc.

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