在struts项目开发过程中经常碰到一种情况,当页面已经改变了,浏览器中的地址没有发生变化.举个简单的例子, 在登陆页面中点击登陆的进入主画面,到进入各个具体的其他叶面。浏览器地址栏显示的是 app/login.do,
在struts配置文件中是这样配置的<action path="/login" type="com.action.loginAction" name="loginForm scope="request" parameter="method">
<forward name="success" path="/login.jsp"/>
</action>
.................. 为什么一个Action URL,例如login.do在浏览器的地址栏内不变呢?
原因就在于浏览器显示的是最后被给定的URL。当一个URL被提交后,在某一个组件返回一个相应给浏览器之前,你的应用可能转发请求多次。所有这些都发生在服务器端,浏览器并不知道发生了什么事。当一个Http相应被放回时,它并没有包含地址信息,所以浏览器仅仅显示用来作为初始请求的地址。这也可以解释在有框架的页面中,点击浏览器上的后退按钮,不能正常后退的原因。 言归正传,如果要浏览器中显示的是程序的物理地址,如:app/login.jsp,Struts中只要用 redirect方式就可以做到,但是也有点问题: 就是这会导致 request里面保存的变量丢失 比如登陆后我会把用户名和用户密码存起来。在登陆的Action中如下处理:
request.setAttribute("user",user);
request.setAttribute("password",password);
....
response.sendRedirect(/login.jsp);
注意,如果是用redirect方式,在页面就无法得到用户名和用户密码了. forward方式仅是容器中控制权的转向,在客户端浏览器地址栏中不会显示出转向后的地址;redirect方式则是完全的跳转,浏览器将会得到跳转的地址,并重新发送请求链接。这样,从浏览器的地址栏中可以看到跳转后的链接地址。
所以,forward方式更加高效,在前者可以满足需要时,尽量使用forward()方法,并且,这样也有助于隐藏实际的链接。
在有些情况下,比如,需要跳转到一个其它服务器上的资源,则必须使用sendRedirect()方法。这也就意味着数据不能通过请求上下文传递到页面,必须通过URI来传递。
2.struts的ActionForward类
ActionForward是Struts的核心类之一,其基类仅有4个属性:name,path,redirect,classname。
在基于Struts的Web应用程序开发过程中,Action操作完毕后程序会通过Struts的配置文件struts-config.xml链接到指定的ActionForward,传到Struts的核心类ActionServlet,ActionServlet使用ActionForward提供的路径,将控制传递给下一个步骤。ActionForward控制接下来程序的走向。ActionForward代表一个应用的URI,它包括路径和参数,例如:
path=“/login.do?method=init&id=10” ActionForward的参数除了在struts-config.xml和页面中设置外,还可以通过在Action类中添加参数,或重新在Action中创建一个ActionForward。 在ActionForward中有一个重要的属性redirect,当redirect=false时,将保存存储在http请求和请求上下文中的所有内容,仅在同一个应用中可用。当redirect=true时,Web客户端进行一次新的http请求,请求的资源可以在同一个应用中,也可以不在,原来的请求参数不再保存,原来的请求上下文也被清除,新的http请求仅包含ActionForward的path属性里所包含的参数。如果在同一个应用中,用户会话的上下文会被维护。
|