代码改变世界

URL与RequestDispatcher

2004-08-21 23:58  FantasySoft  阅读(...)  评论(...编辑  收藏
        今天照例继续自己的网站建设之旅,原本以为可以大有进展,结果又是被一个问题弄得很郁闷。通常在一个表单元素(form)中,action属性值定义了接收及处理表单元素的URL,而这个URL是会被显示在IE的地址栏中的。特别的,在WebWork中是由.action去处理用户提交表单,如<form action="register.action" method="post">,那么当用户点击submit按钮提交了表单之后,register.action 也就出现在IE 的地址栏中了,尽管处理业务逻辑的代码会将request分发(dispatch)到新的页面,但是IE的地址栏并没有因此而改变,并没有出现新的页面对应的URL。正是因为这一点,如果用户在register.action执行成功之后,再次刷新页面的话,就会重新发送对register.action的请求。但是这个时候,用户先前注册的动作已经成功了,这样一个新的请求相当于将相同的id重复注册了两次,这样我的程序也就会不留情面的抛出一个“此ID已经被注册”的信息了。说到这个问题,可以分成两个方面去讨论了。一个就是如何将URL进行屏蔽,第二个就是RequestDispatcher本身存在的问题。
        面对这个问题的时候,我能够想到的第一个办法就是将URL屏蔽,也就是说不让.action出现在URL中,用户如果还想执行一次register.action的话就不得不再次回到注册的页面,并且点击submit按钮去实现了。尽管这样做是不可能防止用户直接在地址栏输入URL去执行register.action的,但是,至少防止了误操作。然而这样的想法,我现在还没有找到实现的方式。
        另外的一个方面就是RequestDispatcher本身实现的问题。在xwork.xml文件中的result节点,type的属性通常有以下几种:dispatcher,redirect,velocity,xslt和chain。从文档上可以看到,dispatcher和redirect都是重定位到一个新的URL,其最大的区别在于redirect并不会将form的数据传递至目标URL,而dispatcher则是可以的。其实从WebWork的源码也可以看出,dispatcher类型对应了RequestDispatcher.forward方法,而redirect类型则是HttpServletResponse.sendRedirect方法。事实上,forward方法确实是不会使得其参数中包含的URL在IE地址栏中显示出来的。这样做也是可以理解的,毕竟如果将URL显示出来的话,一旦用户刷新了页面,那么原先dispatch的request也就随之消失了,这也是程序设计者不想看到的。那么有没有两者之间的平衡点呢?这个问题,只能留待你我共思索了。