struts2拦截器过滤放行后ajax请求后参数丢了
放行后回到action相关的后台控制里,数据都没了。在拦截器里可以获取到AJAX的JSON参数,请问下怎么巴参数转发给放行的action中...
放行后回到action 相关的后台控制里,数据都没了。在拦截器里可以获取到AJAX的JSON参数,请问下怎么巴参数转发给放行的action中
展开
2个回答
展开全部
在Session过期时,执行页面的ajax请求时,无法正常跳转到session过期提示页面,系统直接hold在那里不动,只有点击左侧菜单时,系统才能跳转到session过期提示页面。
经过调研,发现是拦截器的处理问题,拦截器只拦截了Http请求,而没有拦截Ajax请求,才导致出现上述Bug。
下面是解决办法:
首先,优化拦截器:
[java]
/**
* 拦截器
* @author lyh
* @version 2013-11-1
* @see LoginFilter
* @since
*/
public class LoginFilter implements Interceptor
{
/**
* 序列号
*/
private static final long serialVersionUID = -4979037503367919375L;
/**
* 日志
*/
private static final Logger LOG = Logger.getLogger(LoginFilter.class);
/**
* ajax session超时返回值
*/
private static String AJAX_TIME_OUT = null;
/**
* ajax 请求无权限返回值
*/
private static String AJAX_NO_LIMIT = null;
/**
* ajax 请求异常返回值 (在每个ajax请求中处理)
*/
//private static String AJAX_EXCEPTION = null;
/**
* 放行url
*/
private static List<String> awayUrls = null;
static
{
AJAX_TIME_OUT = "ajaxSessionTimeOut";
AJAX_NO_LIMIT = "ajaxNoLimit";
//AJAX_EXCEPTION = "ajaxException";
awayUrls = new LinkedList<String>();
//awayUrls.add("/login!userLogin.action");
//awayUrls.add("/custom!toLogin.action");
awayUrls.add("/equipment!upLoad.action");
}
@Override
public String intercept(ActionInvocation invocation)
throws Exception
{
//获取request域中信息
HttpServletRequest req = ServletActionContext.getRequest();
//获得当前请求url
String url = req.getServletPath();
//获得请求类型
String type = req.getHeader("X-Requested-With");
//Object object = (Object)invocation.getAction();
//如果当前url在放行url集合内 则直接放行
if (!awayUrls.contains(url))
{
UserInfoBean userinfo = (UserInfoBean)req.getSession().getAttribute(
CommonConstant.AUTH_SESSION_USER_KEY);
if (userinfo == null)
{
LOG.debug("用户登录会话已过期!");
//ajax请求 session过期时 返回字符串
if ("XMLHttpRequest".equalsIgnoreCase(type))
{
PrintWriter printWriter = ServletActionContext.getResponse().getWriter();
printWriter.print(AJAX_TIME_OUT);
printWriter.flush();
printWriter.close();
return null;
}
//普通http请求 直接返回页面
else
{
return "sessionTimeOut";
}
}
else
{
//鉴权结果
boolean authFlag = false;
try
{
//执行鉴权
authFlag = userManager_Service.isUrlInUserLimit(userinfo.getU_phone_num(),
url);
}
catch (Exception e)
{
LOG.error(" 鉴权出现异常!异常信息:" + e.toString() + ":" + e.getMessage());
}
//鉴权通过则放行 否则拦截
if (authFlag)
{
return invocation.invoke();
}
//鉴权不通过
else
{
//ajax请求 session过期时 返回字符串
if ("XMLHttpRequest".equalsIgnoreCase(type))
{
PrintWriter printWriter = ServletActionContext.getResponse().getWriter();
printWriter.print(AJAX_NO_LIMIT);
printWriter.flush();
printWriter.close();
return null;
}
//其他Http请求 直接返回页面
else
{
return "noLimit";
}
}
}
}
else
{
return invocation.invoke();
}
}
@Override
public void destroy()
{
//do yourself
}
@Override
public void init()
{
//do yourself
}
}
上述拦截器考虑了Ajax和Http两种情况,Http请求被拦截时,直接跳转到指定的全局页面,而Ajax请求被拦截时则采用Js方式提示用户。
[html]
<package name="self-default" extends="json-default">
<interceptors>
<interceptor name="loginFilter" class="xx.xx.LoginFilter" />
<interceptor-stack name="mydefault">
<interceptor-ref name="defaultStack"/>
<interceptor-ref name="tokenSession">
<param name="includeMethods">add*,update*,modify*,upload*</param>
</interceptor-ref>
<interceptor-ref name="loginFilter" />
</interceptor-stack>
</interceptors>
<!-- 拦截器应用到全部action -->
<default-interceptor-ref name="mydefault"/>
<global-results>
<!-- 普通http请求时 系统出现异常返回到错误页 -->
<result name="exception">/file/smartmanager/public/globalException.jsp</result>
<!-- 普通http请求时 无操作权限 -->
<result name="noLimit">/file/smartmanager/public/noLimit.jsp</result>
<!-- 普通http请求时 session过期 -->
<result name="sessionTimeOut">/file/smartmanager/public/sessionTimeOut.jsp</result>
</global-results>
<global-exception-mappings>
<!-- 全局异常返回exception字符串 -->
<exception-mapping exception="java.lang.Exception" result="exception" />
</global-exception-mappings>
</package>
下面是一个简单的Action例子:
[java]
public class MyAction
{
/**
* Http请求
* @return
* @throws Exception
* @see
*/
public String httpReqMethod()
throws Exception
{
try
{
//do yourself
}
catch(Exception e)
{
//捕获异常时抛出 触发global-results中的exception 然后跳转到提示页面
throw e;
}
return "httpReqMethod";
}
/**
* Ajax请求
* @return
* @throws Exception
* @see
*/
public String ajaxReqMethod()
{
try
{
//do yourself
}
catch(Exception e)
{
//no throw
//此处在捕获异常时 添加提示信息至json 方便在页面展示
//ajaxMap.put("success", false);
//ajaxMap.put("opMsg", ResultMsg.CHANGE_PWD_ERROR);
}
return "ajaxReqMethod";
}
}
配置此Action的xml(此Action需要被拦截 故extends定义的拦截器self-default):
[html]
<package name="willPackage" extends="self-default" namespace="/">
<action name="my_*" class="xx.xx.MyAction" method="{1}">
<result name="httpReqMethod">/file/smartmanager/main/httpReqMethod.jsp</result>
<result name="ajaxReqMethod" type="json">
<param name="root">ajaxMap</param>
</result>
</action>
</package>
全局提示页面,globalException.jsp:
[html]
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>xxx管理系统</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<link rel="icon" href="file/img/rhy.ico" type="image/x-icon" />
<link rel="shortcut icon" href="file/img/rhy.ico" type="image/x-icon" />
<link rel="stylesheet" type="text/css" href="${pageContext.request.contextPath}/file/css/easyui.css" ></link>
<link rel="stylesheet" type="text/css" href="${pageContext.request.contextPath}/file/css/icon.css" ></link>
<script type="text/javascript" src="${pageContext.request.contextPath}/file/scripts/jquery-1.8.3.min.js"></script>
<script type="text/javascript" src="${pageContext.request.contextPath}/file/scripts/jquery.easyui.min.js"></script>
<script type="text/javascript" src="${pageContext.request.contextPath}/file/scripts/easyui-lang-zh_CN.js"></script>
<body>
<script type="text/javascript">
$(function(){
$.messager.alert('操作提示','系统内部异常!请联系系统管理员!','warning');
});
</script>
</body>
全局ajax配置publicSetup.js:
[javascript]
//全局ajax控制,用于session超时 无权限时 提示
$.ajaxSetup({
cache: false, //close AJAX cache
contentType:"application/x-www-form-urlencoded;charset=utf-8",
complete:function(XHR,textStatus){
var resText = XHR.responseText;
if(resText=='ajaxSessionTimeOut'){
sessionTimeOut();
}
else if(resText=='ajaxNoLimit'){
noLimit();
}
}
});
经过调研,发现是拦截器的处理问题,拦截器只拦截了Http请求,而没有拦截Ajax请求,才导致出现上述Bug。
下面是解决办法:
首先,优化拦截器:
[java]
/**
* 拦截器
* @author lyh
* @version 2013-11-1
* @see LoginFilter
* @since
*/
public class LoginFilter implements Interceptor
{
/**
* 序列号
*/
private static final long serialVersionUID = -4979037503367919375L;
/**
* 日志
*/
private static final Logger LOG = Logger.getLogger(LoginFilter.class);
/**
* ajax session超时返回值
*/
private static String AJAX_TIME_OUT = null;
/**
* ajax 请求无权限返回值
*/
private static String AJAX_NO_LIMIT = null;
/**
* ajax 请求异常返回值 (在每个ajax请求中处理)
*/
//private static String AJAX_EXCEPTION = null;
/**
* 放行url
*/
private static List<String> awayUrls = null;
static
{
AJAX_TIME_OUT = "ajaxSessionTimeOut";
AJAX_NO_LIMIT = "ajaxNoLimit";
//AJAX_EXCEPTION = "ajaxException";
awayUrls = new LinkedList<String>();
//awayUrls.add("/login!userLogin.action");
//awayUrls.add("/custom!toLogin.action");
awayUrls.add("/equipment!upLoad.action");
}
@Override
public String intercept(ActionInvocation invocation)
throws Exception
{
//获取request域中信息
HttpServletRequest req = ServletActionContext.getRequest();
//获得当前请求url
String url = req.getServletPath();
//获得请求类型
String type = req.getHeader("X-Requested-With");
//Object object = (Object)invocation.getAction();
//如果当前url在放行url集合内 则直接放行
if (!awayUrls.contains(url))
{
UserInfoBean userinfo = (UserInfoBean)req.getSession().getAttribute(
CommonConstant.AUTH_SESSION_USER_KEY);
if (userinfo == null)
{
LOG.debug("用户登录会话已过期!");
//ajax请求 session过期时 返回字符串
if ("XMLHttpRequest".equalsIgnoreCase(type))
{
PrintWriter printWriter = ServletActionContext.getResponse().getWriter();
printWriter.print(AJAX_TIME_OUT);
printWriter.flush();
printWriter.close();
return null;
}
//普通http请求 直接返回页面
else
{
return "sessionTimeOut";
}
}
else
{
//鉴权结果
boolean authFlag = false;
try
{
//执行鉴权
authFlag = userManager_Service.isUrlInUserLimit(userinfo.getU_phone_num(),
url);
}
catch (Exception e)
{
LOG.error(" 鉴权出现异常!异常信息:" + e.toString() + ":" + e.getMessage());
}
//鉴权通过则放行 否则拦截
if (authFlag)
{
return invocation.invoke();
}
//鉴权不通过
else
{
//ajax请求 session过期时 返回字符串
if ("XMLHttpRequest".equalsIgnoreCase(type))
{
PrintWriter printWriter = ServletActionContext.getResponse().getWriter();
printWriter.print(AJAX_NO_LIMIT);
printWriter.flush();
printWriter.close();
return null;
}
//其他Http请求 直接返回页面
else
{
return "noLimit";
}
}
}
}
else
{
return invocation.invoke();
}
}
@Override
public void destroy()
{
//do yourself
}
@Override
public void init()
{
//do yourself
}
}
上述拦截器考虑了Ajax和Http两种情况,Http请求被拦截时,直接跳转到指定的全局页面,而Ajax请求被拦截时则采用Js方式提示用户。
[html]
<package name="self-default" extends="json-default">
<interceptors>
<interceptor name="loginFilter" class="xx.xx.LoginFilter" />
<interceptor-stack name="mydefault">
<interceptor-ref name="defaultStack"/>
<interceptor-ref name="tokenSession">
<param name="includeMethods">add*,update*,modify*,upload*</param>
</interceptor-ref>
<interceptor-ref name="loginFilter" />
</interceptor-stack>
</interceptors>
<!-- 拦截器应用到全部action -->
<default-interceptor-ref name="mydefault"/>
<global-results>
<!-- 普通http请求时 系统出现异常返回到错误页 -->
<result name="exception">/file/smartmanager/public/globalException.jsp</result>
<!-- 普通http请求时 无操作权限 -->
<result name="noLimit">/file/smartmanager/public/noLimit.jsp</result>
<!-- 普通http请求时 session过期 -->
<result name="sessionTimeOut">/file/smartmanager/public/sessionTimeOut.jsp</result>
</global-results>
<global-exception-mappings>
<!-- 全局异常返回exception字符串 -->
<exception-mapping exception="java.lang.Exception" result="exception" />
</global-exception-mappings>
</package>
下面是一个简单的Action例子:
[java]
public class MyAction
{
/**
* Http请求
* @return
* @throws Exception
* @see
*/
public String httpReqMethod()
throws Exception
{
try
{
//do yourself
}
catch(Exception e)
{
//捕获异常时抛出 触发global-results中的exception 然后跳转到提示页面
throw e;
}
return "httpReqMethod";
}
/**
* Ajax请求
* @return
* @throws Exception
* @see
*/
public String ajaxReqMethod()
{
try
{
//do yourself
}
catch(Exception e)
{
//no throw
//此处在捕获异常时 添加提示信息至json 方便在页面展示
//ajaxMap.put("success", false);
//ajaxMap.put("opMsg", ResultMsg.CHANGE_PWD_ERROR);
}
return "ajaxReqMethod";
}
}
配置此Action的xml(此Action需要被拦截 故extends定义的拦截器self-default):
[html]
<package name="willPackage" extends="self-default" namespace="/">
<action name="my_*" class="xx.xx.MyAction" method="{1}">
<result name="httpReqMethod">/file/smartmanager/main/httpReqMethod.jsp</result>
<result name="ajaxReqMethod" type="json">
<param name="root">ajaxMap</param>
</result>
</action>
</package>
全局提示页面,globalException.jsp:
[html]
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>xxx管理系统</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<link rel="icon" href="file/img/rhy.ico" type="image/x-icon" />
<link rel="shortcut icon" href="file/img/rhy.ico" type="image/x-icon" />
<link rel="stylesheet" type="text/css" href="${pageContext.request.contextPath}/file/css/easyui.css" ></link>
<link rel="stylesheet" type="text/css" href="${pageContext.request.contextPath}/file/css/icon.css" ></link>
<script type="text/javascript" src="${pageContext.request.contextPath}/file/scripts/jquery-1.8.3.min.js"></script>
<script type="text/javascript" src="${pageContext.request.contextPath}/file/scripts/jquery.easyui.min.js"></script>
<script type="text/javascript" src="${pageContext.request.contextPath}/file/scripts/easyui-lang-zh_CN.js"></script>
<body>
<script type="text/javascript">
$(function(){
$.messager.alert('操作提示','系统内部异常!请联系系统管理员!','warning');
});
</script>
</body>
全局ajax配置publicSetup.js:
[javascript]
//全局ajax控制,用于session超时 无权限时 提示
$.ajaxSetup({
cache: false, //close AJAX cache
contentType:"application/x-www-form-urlencoded;charset=utf-8",
complete:function(XHR,textStatus){
var resText = XHR.responseText;
if(resText=='ajaxSessionTimeOut'){
sessionTimeOut();
}
else if(resText=='ajaxNoLimit'){
noLimit();
}
}
});
2018-08-04 · 知道合伙人互联网行家
关注
展开全部
你是用ajax调用add方法的,而你的add方法的返回是个redirect类型,这可能会发生意外结果。 一般ajax请求都通过json类型返回,否则在struts2里可能会得到不正常结果 你可以在jquery接收到json返回值以后,再在请求成功的函数里通过window.location来执行list访问请求,达到重定向效果 让action继承json-default包,或者自己加上json过滤器,返回类型是type="json"
本回答被提问者和网友采纳
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
推荐律师服务:
若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询