Ajax的请求在struts2中怎么实现跳转
我前台用的ext,所有请求都是Ajax的请求,然后我后台用的struts,配置了一个全局的权限拦截器。如果未登录就自动跳转到登陆界面。也配置了全局的跳转。
<global-results>
<resultname="login"type="redirect">/login.jsp</result>
</global-results>
但是因为是Ajax的请求,所以界面并不跳转。但是都可以在后台输出跳转
2010-05-1317:05:49,281DEBUG(org.apache.struts2.dispatcher.ServletRedirectResult:57)-RedirectingtofinalLocation/graduation/login.jsp
用firedebug也有跳转到login.jsp的一个get方法。
后来想在拦截器里面直接用后台的代码跳转。
HttpServletRequestreq=(HttpServletRequest)ctx.get(StrutsStatics.HTTP_REQUEST);
HttpServletResponseresp=(HttpServletResponse)ctx.get(StrutsStatics.HTTP_RESPONSE);
resp.sendRedirect(req.getContextPath()+"/login.jsp");
或者是req.getRequestDispatcher("/login.jsp").forward(req,resp);
但是都会在后台报错:严重:Servlet.service()forservletdefaultthrewexception
java.lang.IllegalStateException
atorg.apache.catalina.connector.ResponseFacade.sendError(ResponseFacade.java:407)
atorg.apache.struts2.dispatcher.Dispatcher.sendError(Dispatcher.java:770)
atorg.apache.struts2.dispatcher.Dispatcher.serviceAction(Dispatcher.java:505)
atorg.apache.struts2.dispatcher.ng.ExecuteOperations.executeAction(ExecuteOperations.java:77)
atorg.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter.doFilter(StrutsPrepareAndExecuteFilter.java:91)
atorg.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
atorg.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
atorg.springframework.orm.hibernate3.support.OpenSessionInViewFilter.doFilterInternal(OpenSessionInViewFilter.java:198)
atorg.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:76)
atorg.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
atorg.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
atorg.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
atorg.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:175)
atorg.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:128)
atorg.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
atorg.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
atorg.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:263)
atorg.apache.coyote.http11.Http11Processor.process(Http11Processor.java:844)
atorg.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:584)
atorg.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:447)
atjava.lang.Thread.run(Thread.java:619)
请教高手啦、、、、、
------------------------------------------------------------------------------------------------------------------
问题补充:
andyjackson写道
既然你是用ajax请求那么无论他如何跳转都没有用,他会将数据一大堆返回,还不方便ajax请求,你最好是在ajax的onsucess中手动跳转
我是配置的一个登陆验证逻辑,给所有的action都加了一个,如果在Ajax中跳转当然可以,但是我得把每个请求都加个跳转,很麻烦,有好的办法么?
------------------------------------------------------------------------------------------------------------------
问题补充:
我是这样子做的啊、
xiaolongfeixiang写道
Java代码
后来想在拦截器里面直接用后台的代码跳转。
后来想在拦截器里面直接用后台的代码跳转。
在Interceptor中不能直接resp.sendRedirect(req.getContextPath()+"/login.jsp");
因为下一个Interceptor无法被调用。所以会报错
你可以这样:
Xml代码
<global-results>
<resultname="login">/login.jsp</result>
</global-results>
<global-results>
<resultname="login">/login.jsp</result>
</global-results>
采纳的答案
2010-05-13yy629(资深程序员)
由于你的请求都是采用Ajax的,所以每次发起ajax请求,虽然拦截器判断出未登录跳转到登录页面,那么,这次ajax请求的结果就是这个页面(具体的说,这次请求返回的就是登录页面的源代码),所以浏览器不会发生跳转.通过在请求完成事件处理函数中判断返回的文本是不是登录页面的源码(比如检查返回值中是否包含<title>用户登录</title>,这个和登录页面有关了),如果包含,则top.location.href='登录页面的url'
--------------------------------------------------------------------------------
提问者对于答案的评价:
谢谢大家的热心解答,Ajax请求确实不能单纯的用拦截器进行跳转,必须得在Ajax请求中设个回调处理,虽然麻烦,但是好像只能这样,偷懒不成啦。参考fireinjava兄台的处理可以。
问题答案可能在这里→寻找更多解答
秀一下我们的Runesv10业务平台,欢迎拍砖。
掌控上传进度的AJAXUpload
如何控制访问页面,filter可以吗?
SSH的项目中有没有判断session是否为空的过滤器之类的东西
如何实现struts2拦截器失败自动跳转
其他回答
既然你是用ajax请求那么无论他如何跳转都没有用,他会将数据一大堆返回,还不方便ajax请求,你最好是在ajax的onsucess中手动跳转
andyjackson(初级程序员)2010-05-13
不方便ajax处理
andyjackson(初级程序员)2010-05-13
Java代码
后来想在拦截器里面直接用后台的代码跳转。
后来想在拦截器里面直接用后台的代码跳转。
在Interceptor中不能直接resp.sendRedirect(req.getContextPath()+"/login.jsp");
因为下一个Interceptor无法被调用。所以会报错
你可以这样:
Xml代码
<global-results>
<resultname="login">/login.jsp</result>
</global-results>
<global-results>
<resultname="login">/login.jsp</result>
</global-results>
xiaolongfeixiang(资深架构师)2010-05-13
讲讲解决思路:
1,使用filter过滤器,直接sendRedirect是完全可以的。(就如你下面的代码是完全正确的)
Java代码
HttpServletRequestreq=(HttpServletRequest)ctx.get(StrutsStatics.HTTP_REQUEST);
HttpServletResponseresp=(HttpServletResponse)ctx.get(StrutsStatics.HTTP_RESPONSE);
resp.sendRedirect(req.getContextPath()+"/login.jsp");
HttpServletRequestreq=(HttpServletRequest)ctx.get(StrutsStatics.HTTP_REQUEST);
HttpServletResponseresp=(HttpServletResponse)ctx.get(StrutsStatics.HTTP_RESPONSE);
resp.sendRedirect(req.getContextPath()+"/login.jsp");
为什么不能使用拦截器和上面同样的代码,这跟拦截器的实现机制有关系的,我们知道在struts中一个重要的机制是AOP编程,拦截器就是用AOP思想来实现的。所以同样的代码在filter中可以使用,而在拦截器中不可使用。
2,使用拦截器实现,但是逻辑稍微有点复杂。
===========================================
大体思路是这样的:在拦截器中设置一个标识(表示是否登录),在loginaction中获取该标志,根据该标志的值进行跳转。(上面的代码依然可以用)
可以参考这个实现:http://www.blogjava.net/max/archive/2006/12/06/85925.html
Anddy(架构师)2010-05-13
引用
我是这样子做的啊、
你设置的是redirect,改为默认的dispatcher就好了
xiaolongfeixiang(资深架构师)2010-05-13
AJAX请求是不可能在服务端完成跳转的,它只能将文本信息传回到客户端。你可以这么做,如果验证失败的话让拦截器将失败信息以一定的json格式写入输出流中,然后在js里为
Ext.ajax添加requestcomplete事件监听,对返的XMLHttpRequest进行解析,如果responseText属性是验证失败的json串则在客户端通过window.location进行跳转;因为Ext.ajax是个单例对象,所以一个页面只需配置一次即可,多个页面的话你就得每个页面都复制了
chemzqm(资深程序员)2010-05-13
我弄过
你也可以在interceptor里面getRootWin().location="http://....";