我有一个登录页面,与登录弹出,其中有用户名,密码和验证码。每次当我尝试使用ajax发布表单时(返回值是json),我会得到这样的错误:
com.opensymphony.xwork2.ognl。OgnlValueStack -错误设置表达式
'struts.token.name'
,值为'[Ljava.lang.String;@53401791'
ognl。OgnlException: source is null forgetProperty(null, "token")
和
login . jsp表单令牌B4KX7L4ER1FXK5BRJZJ19QTGG4EGRGME不匹配会话令牌null
<script>
var strutsToken = "<s:property value="#session['struts.tokens.token']" />";
</script>
和body内标签
<s:token/>
login .jsp (Popup for login)
<script>
var strutsToken = "<s:property value="#session['struts.tokens.token']" />";
</script>
<script>
$(document).ready(function () {
// For making new captcha image
var df = "Captcha?token=" + strutsToken + "&struts.token.name=token";
$("#IMA").attr("src", df); // IMA is id of captcha image
$('#mini').click(function () { // mini is id of submit button
$.post('Auth', {
username: document.getElementById('username').value,
pass: document.getElementById('pass').value,
Captcha: document.getElementById('Captcha').value,
token: strutsToken,
'struts.token.name': "token"
}, function (jsonResponse) {
if (jsonResponse.res == "1") {
console.log('valid');
window.location = "campaign/campaign_dashboard.jsp";
}
else if (jsonResponse.res == "2") {
console.log('valid');
window.location = "Main.jsp";
} else {
$('#result').text(jsonResponse.res);
}
}, 'json');
});
});
</script>
Struts.xml
<interceptor-stack name="myStack">
<interceptor-ref name="authenticationInterceptor" > </interceptor-ref>
<interceptor-ref name="cachingHeadersInterceptor" />
<interceptor-ref name="fileUpload" >
</interceptor-ref>
<interceptor-ref name="token"></interceptor-ref>
<interceptor-ref name="params">
<param name="params.excludeParams">
token,dojo..*,^struts..*,^session..*,^request..*,^application..*,^servlet(Request|Response)..*,parameters...*
</param>
</interceptor-ref>
<interceptor-ref name="defaultStack"/>
</interceptor-stack>
</interceptors>
<default-interceptor-ref name="myStack"/>
是什么阻止令牌正确传递给操作?
您需要将令牌参数从参数拦截器截获的参数中排除。
默认情况下,参数拦截器已经排除了:
这个拦截器可以通过设置它的excludeParams属性来强制忽略参数。此属性接受逗号分隔的正则表达式列表。当这些表达式中的任何一个与参数名匹配时,该参数将被拦截器忽略。Struts定义的拦截器栈已经排除了一些参数:
默认排除参数列表
dojo..*,^struts..*,^session..*,^request..*,^application..*, ^servlet(Request|Response)..*,parameters...*
默认情况下,正则表达式的^struts..*
部分将排除struts.token
和struts.token.name
。
你很可能已经在你的参数拦截器中覆盖了默认的被排除的参数,而没有扩展原来被排除的参数。
:
-
手动添加令牌参数的排除:
<interceptor-ref name="params"> <param name="excludeParams"> myStuff..*,struts.token,struts.token.name </param> </interceptor-ref>
-
或者更好,将您的自定义排除添加到原始列表中,而不是替换它:
<interceptor-ref name="params"> <param name="excludeParams"> myStuff..*,dojo..*,^struts..*,^session..*,^request..*,^application..*, ^servlet(Request|Response)..*,parameters...* </param> </interceptor-ref>
编辑
添加代码后,我可以看到一些错误:
- 删除
myStuff..*
,我把它作为一个占位符,你真正的定制,它是不需要的; - 把整个正则表达式放在一行,我把它分开只是为了提高答案的可读性;
- 你是在参数拦截器上设置参数排除,然后导入整个defaultStack,它本身包含另一个参数拦截器。你应该打开defaultStack标签并在那里设置排除(但这并不能解释问题,因为这意味着你没有覆盖默认排除…)。
- 而且FileUpload Interceptor已经在defaultStack中,所以你要运行两次。
然后试试:
<interceptor-stack name="myStack">
<interceptor-ref name="authenticationInterceptor" />
<interceptor-ref name="cachingHeadersInterceptor" />
<interceptor-ref name="token" />
<interceptor-ref name="defaultStack" />
</interceptor-stack>
如果不工作,尝试使用:
<interceptor-stack name="myStack">
<interceptor-ref name="authenticationInterceptor" />
<interceptor-ref name="cachingHeadersInterceptor" />
<interceptor-ref name="token" />
<interceptor-ref name="defaultStack">
<param name="params.excludeParams">
token,dojo..*,^struts..*,^session..*,^request..*,^application..*,^servlet(Request|Response)..*,parameters...*
</param>
</interceptor-ref>
</interceptor-stack>