00:00
我们来看如何使用session来避免表单的重复提交,那首先呢,我们需要看一下什么叫表单的重复提交。这里边一定是什么呀,一定是在表单提交的过程中会发生的问题,于是呢,我们来写一个。文件夹。好。新建一个JSP。好,随便写一个表单。Method。嗯,写一个字段。
01:09
写一个提交按钮。写完好了,受理请求的呢,叫talking c,这C拿过来。Do post请求。嗯。嗯。好了,这里边儿呢,我们来写一句话。
02:02
写个string的name等于request,点先获取请求参数。然后啊,第比方说写个name加name,然后呢,注意我通过转发的方式给你想应一个页面request.get requestt。根目录下的token下边的。播我的request response。还不来?在这个页面下新建一个JSP。长成这样。H4,告诉他是什么呀?这是一个成功页面。
03:02
保存好了,我们看一下效果。好,注意我写个椎骨sum。Cocono。这是不是一个相对路径啊,是吧,这是一个相对路径的问题,因为你在这个页面上写的话,不是相对于这个路径吗?所以说我们写一个绝对路径。嗯。盖。Contact the path。斜杠这个就好了。回退刷新爱对过。好,成功注意。
04:00
成功了,成功之后的话呢,我这样我在成功页面啊,我来刷新这个成功页面,我一刷新的时候,大家看是不是会有一个提示啊,他说如果要再次显示网页,Web服务器,Web浏览器需要重新发送以前您提交的信息。我再刷一下。大家看这是不是又提了一次表单呢?懂这意思吧,哎,这个时候又提交了一次表单,这个就是我们所谓的表单的重复提交。那为什么会出现这种情况呢?有的时候可能由于这个呃,网络速度比较慢啊,或者说是服务器当时响应速度比较慢的问题,比方说我来写一个这样的一句话,小碎一会儿睡两秒。再看。保存你看一下就知道了。
05:02
回退刷新。And,硅谷?好,注意我点一下它没动,我又没来得及。我点一下没动,我又点了一下还没动,我又点了一下好了,于是这个表单是不是就重复提交了,重复提交的危害是比较大的,第一个。重复提交的话呢,会加重服务器的负担。那比方说哎,我在这个里边的话呢,我不只是打印它了啊,比方说我去访问数据库服务器了。啊,我要去访问数据库服务器的话,那我这块我是不是还得去得去连数据库服务器啊,那整个这个速度响应的话呢,会越来越慢,而且你一不小心的这个重复提交,比方说我们在这个结账的时候,你点了一个提交,你点了好几次,那你可能是提了好几次订单。
06:06
都会有这样的问题,所以说的话呢,我们应该避免这个表单的重复提交,那我们先需要看一下什么情况下会有这个表单的重复提交问题。记录一下。表单的重复提交。我们先来说重复提交的情况。刚才我们具体看到的一种情况。哎,表单提到一个,而又通过请求转发的方式写上了一个JSP或者是一个HTML,但这个时候呢,在地址栏里边还在保存着那个路径,这个时候我在目标页面点刷新的时候,就是一个表单的重复提交情况。
07:18
在。表单提交到一个。So。而。又通过请求转发。The。方式响应。了一个JSP或者是HTML页面,然后呢,这个时候啊。一栏里边。
08:07
还。保留着的那个路径,因为我只发了一次请求嘛,然后呢,我在响应。页面点击刷新。啊,这就是一个。重复提交的情况。第二种情况。在响应页面没有到达时,我重复提交,那复点击那个提交按钮,什么情况下会出现这种情况,在我有网络延时的情况下说在响应。
09:03
页面没有。到达时。重复点击提交按钮,这也是一个表单重复提交的情况,这是一种,我们再来看一下第三种情况。我重五点刷新肯定会。慢吗?肯定会,因为你放心他也不来,然后的话呢,我多点几次,这个时候你多点的每一次都是重复提交,这个会或者是或者是回馈啊,我这个英文发了一下,然后呢,我写S硅谷看点一次,再点一次,再点一次,这也算。好,还有一种什么,还有一种什么情况下也算呢,注意看哈,我直接点返回。然后我点提交,说这个算不算。
10:01
再说一遍哈,看着。我直接通过返回,回到这个页面,我点提交这个算不算这个也算为啥嘞。还有一种我返回之后的话呢,这个页面我来点刷新,然后我再提交这个算不算。这个不算,诶同学说的挺好的,为什么这个不算,那个算呢?大家想我这块点刷新这个算法肯定的嘛,跟我回馈这个我点提交效果是不一样的,所以说这个也算。三种说我点击返回,点击那个返回键,然后呢,我再点击提交,这也算是一个表单的重复提交,点击返回,然后呢,再点击。
11:00
怎么样?提交,这也算是一个表单的重复提交,那什么情况不算是单的重复提交呢?我们来看一下,我返回这个页面,然后我刷新了我再提交,这是不是就不算了呀,因为我这个这个页面刷新的话,跟我重新开一个是不是一样啊,我重新开一个。然后我写一个艾特硅谷,我提交,这肯定不算吧。那我这个刷新跟我重新看页面不一样吗?但是这个我点过来。然后我再返回,我再点。他跟。跟我直接在这块点刷新是不是一样的,所以说这个是不是。重复提交的情况,什么时候不算呢?说我点返回,然后我刷新了原表单页面再提交,这个不分,因为我点返回。
12:11
我在刷新,我不是相当于开了一个新页面吗?所以说他不算。点击返回。然后呢,返回之后我干什么呀,我刷新了原页面。再点击提交。这个不算是表单的重复提交。我们回过头来再看一下。我们讲的。呃,表单重复提交的情况的第一种情况。在表单提交到一个solve,而survey又通过请求转发的方式想一个GSP或者是HTML,注意这个是请求转发。
13:06
那如果是重镜像的话,会怎么样呢?我们来看一下。Response send。爸。你看这盖子。Token下边的success。保存这个情况下算什么。挑战。好了,我点它。我这个时候点也算,但是问题是啊,我再返回再点这还算。
14:00
这个还算,但问题是我目标页面点是我不算看见了吗?因为我目标页面要是刷新的话,这个是不是已经到这个GSP了,这个不算看清了吧,这个不算,但是你返回我再点。和我这块反复点提交这个算。这个算这个时候的话呢,我们就看到了,为什么我们说用这个呃。请求的重定向,它可以避免重复提交呢,因为你这个目标页面是不是已经变成这点GSP了呀,所以说这个时候就不算了。我们再重新说一遍啊,三种情况算是表单的重复提交,第一种情况说在表单提交到一个service。而这个serve呢,通过转发的方式想了一个JP或者是一个HTML,此时这个地址栏保存的是那个serve地址,这个时候你点刷新的话就算或者是。
15:08
在响应页面还没有到到达的时候,我重复点击提交按钮,这个肯定是,或者是点返回再点提交,这个也是好了,不是的,是什么呢?是呃。我返回了,然后刷新原表单页面再提交,这个不算好了第三个。第三个我们要说的是如何避免表单的重复提交。好了,既然这三种情况算式表现重复提交的话,我们看如何避免呢?很明显我们不希望出现这样的情况。我直接告诉你,哎,你重复提交了,你就不要提交。我如何避免啊?我们举一个例子哈。这是我们公司以前发生过的一个真实的例子。
16:01
公司那个时候呢,有500多人。以前在这个过年啊,过节啊,特别是这个中秋的时候呢,发月饼都是这么发,就是呃,管后勤这个哥们儿把月饼买来,然后呢,由这个后勤的这个部长来管,然后他把这个月饼分给各个部门,让各个部门的这个管行政的这个女生带着几个老爷们是吧,把这个月饼领回来,然后完了回去发,那这个时候什么当后勤的这个人把这个月饼交给这个行政主管的时候,各个部门这个行政主管的时候,把数数,把数数对了,OK,你一发就可以,然后如果你要是部门要弄丢的话,我就再不管了,那回到部门的话,一个一个点,基本上没问题。有一年来了一个,嗯,新的管后勤的一个,他还不是部长,但是这个哥们儿吧,就挺有那个那个那个江湖的那个那个意思的啊,就是说诶,我想把公司这个人呢都认识一遍。
17:05
他这个想法的话呢,其实也还行,然后呢,他就跟底下的这些同事就说了是吧,说月饼这边不耐发,咱们让每个员工都过来拿,然后的话呢,我们每个员工我们都认识认识。好了,想这么一个招,那员工如何来拿这个月饼呢?于是的话呢,他想了一个方法,就是每个人发了一个票,发了一个月饼票。你凭凭票过来取月饼。大家觉得这个时候会出什么问题啊?我凭票拿月饼,这个时候确实出现这个问题了,是吧,有的哥们把那个票整丢了。他没领着月饼票丢了的话呢,可能被另外一个已经领月饼的哥们拿到了,他拿两张票领了两次月饼。拿票领吗?我有票就可以领。好了,然后的话呢,这个时候就是,诶,我有两张票可以拿。
18:00
两次月饼,那如何可以避免有的这个同事拿两张票可以领两次月饼呢?大家考虑一下。啊,把那个月饼票什么的,月饼票月饼月饼票做一个标记是吧,无论是贴照片啊,还是写名字啊,反正月饼票需要做一个标记,你把那个票拿到的话,我得那个票和你的这个身份比对一下吧,比方说那个票上边,呃是用这个是跟你刻的,跟你的员工号一样,只有他俩一致的话才可以,不一致的话就不行,这是不是就完了,这个时候你下一次还拿票过来领的话,我一看。我发现,哎,你的这个票上面那个号和你这个本身员工号不一样,对不起,你领不了。这就可以了,那同学说,那我到时候比方说我把那哥们的那个那个员工卡借过来,然后你去领呗,那员工卡的话,员工卡上面还有照片,这是七,就算没有照片的话,他一查就能看出,诶都已经领过了,然后完了那哥们说我没领着,那就说你的员工卡是不是借下来了,这个时候一查就查出来了,所以说避免一个员工领两次月饼的方法就是。
19:18
在发那个月饼票的时候,票上需要做一个标记就可以,那我们这个也一样。看哈什么,我要想避免表单重复提交的话,我就得在表单提交之前为表单做一个标记,然后呢,到目标so里边去验证那个标记,跟你当时说那个标记一不一样一样的话,受理请求,而且把那个标记撕毁。不一样的话。我就不受理请求,告诉你重复了,当然这个时候怎么样,需要把那个标记撕毁,就像我们是吧,你拿着票去领月饼了,那你这个票怎么样,我需要没收,你下一次要再领的话,不行,我告诉你这个票失效,阅兵已经领了。
20:07
这样就可以,所以说呢,这个基本的思路他是这样的说在表单。中做一个。标记,然后呢,哎,提交到时。检查标记是否存在切是否和与定义的标记一致。若一致。则。受理请求。并。销毁。周记。如果一致受理请求,而且销毁标记。
21:03
若不一致。或没有标记这怎么了?则直接响应这个提示,提示信息,比方说同步提交。哎,这就是我们的基本思路。看一下啊,在表单中呢,做一个标记。然后呢,我提到这个service的时候啊,我检查这个标记和你预定义的一不一样,当然了,你要没有的话肯定不行了,是吧,如果要是一样的话,受理请求销毁标记,如果不一样或者没有标记的话,对不起,直接告诉你重复了,就这么干,那我们实现呢。回到这个页面来,我怎么来做标记啊?做一个标记,而且呢,我这个里边我还能我还能看着吧,那个标记是啥样的吧,那咋做呀。
22:08
过来看,说我需要做个标记,大家说。这让我怎么做标记啊?我怎么做这个标记啊?说作为一个标记的话,我只需要写一个隐藏域,你不带个标记吗?很明显那个标记你不能那没人看着是吧?哎,写个T点,写个Y6。写个什么呢?写个值,比方说我随便写一个啊,写个at硅谷写了好了,我写完这个啊,我加了一个隐藏域,然后呢,我到目标页面啊,我说只要你看看有没有这个hidden,比方value啊,啊这name name叫token。就token,然后呢,我获取这个token这个值。
23:00
啊,这个值叫X硅谷,如果有这个值的话就行,没有这个值的话就不行,这么说可行吗?很试试啊,很事实,不是中标记吗?于是spend token等于request.that perter,对,Perter啊。获取完了,获取完之后啊,If if什么呢?说这个值是at,硅谷点ES。他等,然后OK,这个时候有个问题,就是我得轻。清除标记。出问题了,你怎么清除啊?怎么清楚啊?同学说派里边应该有个学说,木什么?这是不是没吹给的移除属性,我现在我说是不是请求参数啊,我们没有一个办法去清除掉这个请求参数,清除不了。
24:07
清除不了,所以说我没有办法去直接去清除这个请求参数写吧。对啊,没有方法。清除。固定的请求参数清除不了,就算是你清除的话,你想哈,我一回退,我再提交,这个家伙是不是又有了,所以说靠这个不靠谱,这样也不行。那你那你那你标记怎么办呢。那说这还不行呢,你说你怎么办呢?我还真有那个标记。我怎么办呢?隐藏玉没好用哈,我们想用了隐藏玉不行。我们说方案,第一个方案。
25:01
这样啊,提供一个隐藏域,类似于这样的方式。No see。叫仅提供一个延长。这个呢不行。No,是吧,行不通,为什么呢?因为因为这个道理。因为我们没有办法去清除这个请求参数,而且呢。而且呢,在我点击这个回退以后,我再提交是不是又又有那隐藏预览他写死的呀,所以说这方不行。还有什么?那标记隐藏域不行,我还可以往哪放啊?把。标记放在中。
26:04
这个可以吗?这不行了啊,这个暂时先住吧。好了,这个不成,好了,那标记放里边。写request点。Attribute叫什么呢?叫。Token好了,比方说叫top value吧。Token value。嗯,标记放这个里边了,我们知道这个属性是不是可以移除啊,然后我这块我这么写这个不行了哈,拿掉了。这么写等于request.get attribu。然后呢,说if if。
27:05
Token。不等于空OK受理请求,然后的话什么了N我是不是可以移除啊。捋筷子,点铝木,我去溜达。Book。Else else,告诉什么呀?response.sendre gotn.JSP告什么中提交了ctrl c return,看看这发行吗?大家觉得?嗯。H4,对不起,已经提交过了,大家说这个方法行吗?醒醒啊。这个行不行,对我们来说很重要。
28:03
想想。刷新。给我来了这个top.gp哦,我没写那个绝对路径是吧,你看我第一次进去之后,直接给我跑这来了啊。C。过来再看一遍哈。回退发新AAA。是直接跑这来了,我这个已经刷新了。这个明显没好用,为什么没好用啊?能想明白吗?啊,因为我们知道。这个很重要哈。看着。
29:02
这块我是不是往请求域里边放了一个属性啊,于是我在刷新这个页面的时候。这个request这个主动就放完了吧,那我再点提交,这是不是一个新的请求了。这个新的请求,我刚才放这个属性在我新的这个请求里面没有吧,是不是没有啊,所以说这个talk是不是获取不着啊,有没有。这个很重要,大家这个必须要理解啊,再看一遍。回退刷新,看着我就不写了啊,直接跑。是不是闹啊,因为什么,因为我这个页面我一刷新的话,然后一响应我这个请求是不是结束了呀,所以说我再点提交的时候。刚才的这个请求里边放那个属性,我在这个搜是不是获取不着啊,这是两个请求,所以说第二种情况往request里边放啊也不行。
30:08
说no行不通,因为什么呢?因为啊表单页面。刷新后。已经被销毁,再提交,再提交。表单是一个。新的request,所以说这个不行,这个必须要知道为什么。第三个,那request不行的话,我们靠谁了?靠三什么把标记放在。三审中。这个是肯定是可以的。
31:02
看看过来。显高。Session a。木雕的长啥样呢?放个。等于点这个是可以的。这个是可以的,好吧。对抗。嗯。刷新。ABC我点我点,我点点点。大家看是不是跟我重复了这个内幕,是不是不是只打一次,这个时候我再刷一样的。
32:01
也会打一个空,这个时候他什么是典型的啊,这个时候不会打了,这个时候目标这个是不是已经变成点GP了,这个时候我们可以有效的避免表单的同步提交,所以说的话呢,这个表单同步提交需要借助于谁呢?需要借助于这个session。哎,这个轴是可以,但目前这种方案的话呢,不完美,为什么不完美啊,你是不是往30里边放了一个固定的值啊,哎,我们希望这个值是一个随机的值,再说一遍啊,我希望这个值随机的值,我不但要这,不但希望这个值有,而且还希望。这个值跟我那个,嗯,目标那个值是一致的,什么意思呢?我不但希望这个三星里边有值,而且我能够把这个值获取到,而且这个值还跟当时放那个随机值是一致的,这个时候更抱歉。
33:01
它不会出现一些意外的情况,因为你这个时候怎么呢,我毕竟是用了这个session,然后的话呢,我放了一个属性,我们保不齐我们在这个写开发的时候的话呢,我们真的往赛车里边放了这么一个属性,这就不好办了。所以说我不但要放,我还要放一个随机纸,比方说我放这么一个纸。我放了一个new days。点。Get time加。嗯。我放了这么一个值,好了,我放这么一个值的话,那问题出来了是吧,我现在的话呢,我希望我能看到这个值,我不但是放了,而且我还能够知道什么呀,而且我还能够知道说诶你放的这个值。
34:03
这里边儿是吧,我取的这个值跟放的一不一样啊。那。不等于空。而且。而且什么呢?ton.equals什么什么什么这个什么什么什么,靠自个写不好使了吧。咱哪知道那个值是几啊,你比方说我这个页面回馈哎,我刷新一下,然后我一会儿才提交的,你看这个值。源文件。啊,看不着。在这呢,这个值是不是一个随机值啊,那这个时候的话,我再提交,刚才那个时间我完全不知道是几了,怎么办,这个时候跟他配合的应该是一个。隐藏玉。就是说哎,我不但有塞,我还有这个直视级怎么写呢,这么写看着。
35:02
首先我会有这样的一个string。Hon value等于它。CTRLC。加它,然后呢,我这块还写了一个value值。抱歉。我这块也来帮他。嗯。那这个就可以放上边了啊,放上就可以呗,这X。本周V拿过来把这个呢干掉。好了,这回我再刷新,又键又文键,这值是几,这个值是不是它呀。哎,这个只长成这样CTRLC,然后什么呢?然后我在这里边啊,我这么办。
36:01
啊,首先呢,我获取这个值,然后我再获取那个真正的talking value,看怎么获取呢。先写一个吧,再写一个。Y等于request get。Token好了。这个时候刚好哈,这两个呢,这两个方法一起放这了。它是什么呀?这个是不是获取那个属性值叫三身的属性值,这个是获取请求参数吧,好,我写一个你看。那我们希望的是,它不但这样,而且还相等。高外,这多好啊。
37:07
就是这个时候的话呢,不但有,而且值还一样,我刷新写了你看。价值是不一样吗?我在刷。我要再刷新的话,应该给我响应那个错误页面了啊。没有反应了啊,这已经是GP了是吧,这个时候看不着那个效果好了,我发我这样的话可以。大家看是不是重复提交啊,再看一遍,我回馈我直接点刷新。这个时候是不是直接就重复了,为什么呀。再看我回退,我直接刷新,这样是重复吧,跟我跟我开始讲的一样吗?为什么是重复啊。
38:05
为什么呀,因为我通过回退的方式回来,我这个页面应该是缓存吧,这个时候这个账号代码数没执行啊,我是不是没往30里面去放值啊,嗯,这个代码不执行,它不往里面放值,而我目标页面是不是已经把这个30是不是已经移除了,所以说这个条件不满足,但是我回来之后我再刷一下就可以了。哎,这个时候呢,我们就充分的解决了这个表单的重复提交问题,于是呢,我们把这个步骤写一下,看第一个步骤说在原表单页面原表单。页面生成。一个随机值,这个值呢,必须需要具有充分的随机性。
39:03
比方说,这个值叫top。然后把还是在。在原。表单页面。把token值。放入。Session属性中。还有。在原表单页面把N值放入到隐藏域,隐藏域中OK好了。然后呢,哎,提交表单,然后看在目标的。
40:08
Sol中怎么了获取?和。隐藏域中的。涛根植。好了,然后呢,比较。比较两个值是否一致,说若一致。受理请求。受理请求,然后妾妾什么呀?切,把三身欲中的N属性清除。好了,若不一致,若。
41:00
不一致则直接响应提示页面,告什么呀?告表单已经重复提交过了。不提交。哎,这个就是整个的步骤,原表单需要干这样的一件事,需要干这样的一件事,我们需要明白这个道理是神马意思。就是我不但要做标记,我还要知道这个标记是什么,然后目标页面我把这个清除就可以了,这就是我们整个的这个,嗯,表单重复提交。什么是表单重复提交,什么不是,以及如何进行解决。大家看一下。我们再来看一下我们刚才提供的这个实现的方式,我们看一看,嗯,我有哪些地方,我可以给它写成一些方法或者是类,然后呢,以后可以得以重用,因为我每次都这样写的话,有点麻烦看啊,首先生成一个token的一个随机值,实际上我这个时间呢。
42:15
这个时间呢,这个值不是那么的随机。所以说生成随机值这个感觉不怎么好。再来。再来,然后呢,放session里边,放隐藏域里面,那我在这个目标GSPM,目标so里边做的这些代码,我们都可以给它放在一些方法里面,那于是呢,无论是STRAS1还是stra two,还是spring Mac都提供了。处理表单提交的主件,我们把一那个主件拿出来看一下源代码,那个源代码跟我们目前写的这个几乎是一样的。D盘。
43:02
Java。Open source struts1。Src就是源码哈。Call sc。扎G阿帕奇。要求有一个token processor,这个呢,就是STRESS1里面处理token的这个处理器类token processor看一下源码。看一看这个源码的话呢,我们是不是马上就可以用。这里边儿的话呢,有好些方法,我CTRL。CTRLC我直接在本地呢,建这样的一个。然后呢,把这个复制过来。
44:05
但复制过来的话呢,会有一些错,错的话呢,我们一个一个排第一个错是报名是不是不对啊。高明。他需要一个什么呢?需要一个global,咱没有干掉。好,其他这些东西的话都有。看高。Processor,你看见这一行的话,你会觉得它是什么?Previous sta貌似是单立的吧,这不是么?Single time单子模式,然后呢,啊,Previous,什么时间戳前一个值啊,Protected,它是通过protected的方式呢,来这个隐藏这个构造器的,然后它S返回这个值往后翻看什么呀,Is talking value。看我这个是不是满足重复提交我们方法,我们一会再说吧,把这扣单掉啊错。
45:07
这边有一个global talkingn key,这个talkingn key是什么我们不知道,我们暂时我们也写一个固定的talking key。这么写吧。CTRL1。上去创建一个常量的token key。又是一个叫。Transaction talking上去。写一个常量,一会我把这常量我都指我一个一个填一下哈,这个写完了应该。保存。还有错吗?还有一个啊。这个去掉就可以了,保存好了,那我这个植物怎么写呢?这个我就叫他。
46:00
刘备是些常量嘛。这个我就它这个呢,我就叫他。写完了好了,实际上这两个值的话呢,我们确实是可以找到啊,这哪个里边啊,他说有个globals。Global貌似还不在这个里边,应该是在这个。上级包里边儿,这里边儿有个global。这里面放的都是一些什么呀?放的都是一些常量。RF。Token。这什么呀?这是什么?Transaction talking key,呱点token,还有一个吧。很赚F下一个F3。还有一个他key就是加上什么,加上这个包名,加上它,所以说这是个常量,我们这样写的话呢,并不影响任何的操作,下面的话呢,我们来看一下这些方法,看这些方法我们有没有能够直接直接用的,好吧,看outline。
47:09
我们看。首先呢,它有一个方法就产生什么,产生一个token,实际上这个就是产生一个。Token的一个随机字符串,这个字符串怎么产生的呢?它传入一个什么呀,传入一个request,看到了吧,Request,然后的话呢,获取了一个session,它真正产生这个字符串叫的是generate token方法,这个方法。这个方法看怎么产生呢,人家这个字符串的话,保证是一个随机的字符串。The。好,怎么能保证这个学习的字符串呢?大家看啊,这是传播的什么呀,3ID吧,这是当前的系统时间说如果当前这个时间跟前一个时间等的话,当前这个加加,然后现在这个时间等于当前这个时间,这个时候的话呢,就是为了让这个时间不重时间不重复,然后的话呢,做了一个什么呀。
48:13
把这个时间又做了这样的一个算法是吧,然后的话呢,把这个字符串返回,反正就是我们能看到这块返回这个字符串的确是会是很复杂的一个字符串,具体是怎么做的,用的是MD5算法,用的是MD5算法来返回一个字符串,MD5呢是字符串加密的一种方式,而且是不可逆的。就是说你不能够通过这个算法把一个字符串反推回来,这个是这个值是几,所以说这个session ID本身就比较随机了,系统之间它俩在一起混合成MD5返回一个字符串的话,这肯定是一个随机的字符串,所以说这块的话呢,就帮我们产生这个字符串的,然后看save token是干什么呀。
49:03
把产生这个随机字符串放到session里面,拿这个做键。好了,Reces token,怎么reces呢?是不是就目啊,从section中移除,这两步我们刚才都都做过,这个是把这个字符串放到赛程里边,这个是从赛程中移除再看。He talking va。看什么呢?看这个呃,是不是重复提交点,它主要看这看这方法怎么写呢?首先我先获取session。如果三身是空的话,那我不受理请求,是这样吧,你三身都没有的话,那肯定不行,我而且我教这个方法是什么呀?是request get session for,再来,然后呢,呃,我尝试从session里边来获取这个放入的这个session域的这个属性,如果这个属性没有的话也不行。
50:06
往后看。然后怎么呢?然后我从如果这个属性值要是有的话,我从请求参数里边获取这个请求参数的值,如果这个值要是没有的话,还不行,否则我进行比较,这个实际上就是我们现在写的这个代码。那我现在的话呢,我来用它来写一下,你看这个代码是不是会容易一些呢。到。Index。咋写呢?这个就不要了。我还不忍心给他写没哈。OK,然后呢,这块需要写一下。因为啊,以前的写法是怎么写啊,以前的写法它是这样的,以前我们这个to s是结合抓to标签来用的,呃,Stra标签来用的,我们现在没有标签,所以说呢,我们做一个简单的改动,这个这个方法save token,我让他把这个值返回。
51:10
String。煤炭。Con,好了,我这样返回,然后你回来,回到这儿来,我来写一个。Con processor.get.save con request,我这样写完之后的话,这步要起几个作用啊?这不起两个作用吧,首先我会产生一个随机值吧,而且这个方法是不是还让我把这个值放到session里边来,是这样吧,但是的话呢,刚才我们看这个代码有一个要求,要求是这样的,我要求get to这个talking key必须是他。CTRLC再看一遍啊,我这是参数名,必须这么写。
52:06
陈树民。对不起,好了,报目标我也不用像刚才写的这么复杂了,这些我都不要。本周第。这么写。嗯。不尔直。嗯。Value等于token processor,点点is ton,传一个request if,如果可用的话。我怎么了,我就给他移除,如果可用的话,我就把那个移除什么移除。How can processor.get instant点移除半掉。然后呢啊,我受理请求,否则告诉他不行,这个还是要写的啊,去哪个页面吗?CTRLCCTV。
53:11
干掉,这个就是我们重构之后的代码,看效果。这样吧,It's talking。这块的话呢,我打个断点。然后呢,我在保存的时候,我也打一个断点save在这。好了两处。还有其他的啊,其他的干掉。回来,第八个跑起来。看一下有了这个top process的话,我们这个样子真的不一样吗?刷新一下。不能看。
54:01
过来看它呢,会产生一个token,它这个token值哈。好,好复杂的一个值,看后边吧,AF444,而且这个若干长,我们能够保证这个值肯定是一个随机值,肯定是一个随机值,好了,然后呢,下一步我干什么呀,我是不是把这个值放塞程里边来。好了,这个键我们看到了,这个键叫transaction talking p啊这一步过完过完,刚才我们看了一个值,我们回到我们的这个页面上右键。这文件这个值是不是这个什么AF444啊啊,而且这个是ton k好了我提交请求。好,这个时候的话呢,我们看那个抄根是不是可用的,于是往下一行一行来。三神是有的,没问题,好save的是不是从三神获取那个值啊,这就是AF444,然后再来,如果这个不是空,嗯,往下走。
55:07
然后呢,这个是request大头meter吧,看这个值这俩值是不是一样啊,我一比较能过的话就可以,那肯定可以过呀,过了。没问题,受理请求了,好了,我再提交一次。同步提交吗?啊,这个同步不了是吧,回退点他提交。好了,这回看这是个什么情况。是不是空啊,为啥是空啊?刚才那个我是不是已经了,我是不是已经移除了呀,所以说这块这个就是空。那后边的就不用找了,这个是空怎么了。是不是return for了,那这个1RETURN for的话,我们再回到这个里边来,这个return for的话,它是不是要走这个39行了呀。
56:02
过来不39行吗?我直接响应这个token.jp页面点过来你看。直接就是这个页面告诉你已经重复提交过了,那你看我们有这么一个主件的话,我这样用是不是舒服多了呀?诶这个就是我们所谓的叫面向组件编程,他给我们写了一个talk processor,我们写代码的时候直接这样子就可以,比方说我们现在没用框架是吧,我直接把这个改一下,这里边的话呢,我写一个它我们要求这里边这个name必须是ton key,或者说这个值的话呢,必须是这是这个里边to跟K指定的这个常量值,哪呢?它你也可以加加点东西,比方说com点,哎,硅谷点它都可以反,但是这个值。这个值必须跟它一样,CTRLC,然后这块你这么写。
57:03
这是name,然后的话呢,这是value这一块,这样放的话呢,这个里边这个值,这个值无所谓,这个值对我们来说是透明的吧,我们用的时候并不知道有这样一个值,我们在sol里边,我们只我们只需要知道哦,我有这样一个方法,我这个方法能够验证是不是重复提交就可以了,那整个这个代码的话呢,就下来了,这就是。TRUS1里边的实现stra to跟里边的实现和这个类似,只要把这个搞清楚,在学stra two的重复提交,在学是MVC的冲期焦,道理都是一样的。来吧,我发下去,大家把这个源代码也看一下。
我来说两句