JSONValidationInterceptor是struts2自带包里面声明的自带拦截器,用于将校验结果转化成为json字符串输出到页面中。最近看了其中的源码发现其输出的字段前有总是有“/* {} */”带着,而这样的格式又不能正确转化成为json对象,必须将其处理掉以后再转换才行,甚是奇怪,不知有哪位大大知道struts2的开发者是何用意?
附上相关源代码。
protected String doIntercept(ActionInvocation invocation) throws Exception {
HttpServletResponse response = ServletActionContext.getResponse();
HttpServletRequest request = ServletActionContext.getRequest(); Object action = invocation.getAction();
String jsonEnabled = request.getParameter(VALIDATE_JSON_PARAM); if (jsonEnabled != null && "true".equals(jsonEnabled)) {
if (action instanceof ValidationAware) {
// generate json
ValidationAware validationAware = (ValidationAware) action;
if (validationAware.hasErrors()) {
if (validationFailedStatus >= 0)
response.setStatus(validationFailedStatus);
response.setCharacterEncoding("UTF-8");
response.getWriter().print(buildResponse(validationAware));//请查看下面的代码
response.setContentType("application/json");
return Action.NONE;
}
} String validateOnly = request.getParameter(VALIDATE_ONLY_PARAM);
if (validateOnly != null && "true".equals(validateOnly)) {
//there were no errors
response.setCharacterEncoding("UTF-8");
response.getWriter().print("/* {} */");//无结果时居输出次字符串
response.setContentType("application/json");
return Action.NONE;
} else {
return invocation.invoke();
}
} else
return invocation.invoke();
}下面是buildResponse方法的代码 protected String buildResponse(ValidationAware validationAware) {
//should we use FreeMarker here?
StringBuilder sb = new StringBuilder();
sb.append("/* { "); if (validationAware.hasErrors()) {
//action errors
if (validationAware.hasActionErrors()) {
sb.append("\"errors\":");
sb.append(buildArray(validationAware.getActionErrors()));
} //field errors
if (validationAware.hasFieldErrors()) {
if (validationAware.hasActionErrors())
sb.append(",");
sb.append("\"fieldErrors\": {");
Map<String, List<String>> fieldErrors = validationAware
.getFieldErrors();
for (Map.Entry<String, List<String>> fieldError : fieldErrors
.entrySet()) {
sb.append("\"");
//if it is model driven, remove "model." see WW-2721
sb.append(validationAware instanceof ModelDriven ? fieldError.getKey().substring(6)
: fieldError.getKey());
sb.append("\":");
sb.append(buildArray(fieldError.getValue()));
sb.append(",");
}
//remove trailing comma, IE creates an empty object, duh
sb.deleteCharAt(sb.length() - 1);
sb.append("}");
}
} sb.append("} */");
/*response should be something like:
* {
* "errors": ["this", "that"],
* "fieldErrors": {
* field1: "this",
* field2: "that"
* }
* }
*/
return sb.toString();
}
不知是开发者秀逗了还是另有乾坤??
附上相关源代码。
protected String doIntercept(ActionInvocation invocation) throws Exception {
HttpServletResponse response = ServletActionContext.getResponse();
HttpServletRequest request = ServletActionContext.getRequest(); Object action = invocation.getAction();
String jsonEnabled = request.getParameter(VALIDATE_JSON_PARAM); if (jsonEnabled != null && "true".equals(jsonEnabled)) {
if (action instanceof ValidationAware) {
// generate json
ValidationAware validationAware = (ValidationAware) action;
if (validationAware.hasErrors()) {
if (validationFailedStatus >= 0)
response.setStatus(validationFailedStatus);
response.setCharacterEncoding("UTF-8");
response.getWriter().print(buildResponse(validationAware));//请查看下面的代码
response.setContentType("application/json");
return Action.NONE;
}
} String validateOnly = request.getParameter(VALIDATE_ONLY_PARAM);
if (validateOnly != null && "true".equals(validateOnly)) {
//there were no errors
response.setCharacterEncoding("UTF-8");
response.getWriter().print("/* {} */");//无结果时居输出次字符串
response.setContentType("application/json");
return Action.NONE;
} else {
return invocation.invoke();
}
} else
return invocation.invoke();
}下面是buildResponse方法的代码 protected String buildResponse(ValidationAware validationAware) {
//should we use FreeMarker here?
StringBuilder sb = new StringBuilder();
sb.append("/* { "); if (validationAware.hasErrors()) {
//action errors
if (validationAware.hasActionErrors()) {
sb.append("\"errors\":");
sb.append(buildArray(validationAware.getActionErrors()));
} //field errors
if (validationAware.hasFieldErrors()) {
if (validationAware.hasActionErrors())
sb.append(",");
sb.append("\"fieldErrors\": {");
Map<String, List<String>> fieldErrors = validationAware
.getFieldErrors();
for (Map.Entry<String, List<String>> fieldError : fieldErrors
.entrySet()) {
sb.append("\"");
//if it is model driven, remove "model." see WW-2721
sb.append(validationAware instanceof ModelDriven ? fieldError.getKey().substring(6)
: fieldError.getKey());
sb.append("\":");
sb.append(buildArray(fieldError.getValue()));
sb.append(",");
}
//remove trailing comma, IE creates an empty object, duh
sb.deleteCharAt(sb.length() - 1);
sb.append("}");
}
} sb.append("} */");
/*response should be something like:
* {
* "errors": ["this", "that"],
* "fieldErrors": {
* field1: "this",
* field2: "that"
* }
* }
*/
return sb.toString();
}
不知是开发者秀逗了还是另有乾坤??
http://www.phome.asia/forum/thread/22019.htmlStruts2+JQuery+JSON集成开发实例
http://www.phome.asia/forum/thread/22071.html
如果你有答案了,还得向你在这里请教一下了。
簡單的說,它不想回傳一個可以直接 eval 成物件的字串,所以用javascript的註解包起來,
要使用的話,程式碼如下...
var responseObject = eval("("+data.substring(data.indexOf("\/\*")+2, data.lastIndexOf("\*\/"))+")");
詳細的情形,You can google 'JSON Hijacking'.
我去trace code發現有產生json string,但是就是沒有write 我的response stream
我覺得應該是我的 struts.xml 有寫錯
JSONValidationInterceptor 最後回傳了 Action.NONE
所以是不是需要定義一個none的result ?
另外需要定義一個 input 的 result 嗎?
<action name="UserListAction" class="com.walkgame.cosmo.action.UserListAction">
<result type="freeer">/WEB-INF/pages/user/userlist.ftl</result>
<result name="json" type="json">
<param name="root">userlist</param>
<param name="includeProperties">\[\d+\]\.email,\[\d+\]\.nickName,\[\d+\]\.roleID</param>
</result>
<result name="none" type="json">/WEB-INF/pages/usermag.ftl</result>
<result name="input">/WEB-INF/pages/usermag.ftl</result>
</action>謝謝!!
如果response中没有write出任何东西,页面中将不write出任何东西。不需要定义none的result。
我先知道你如何一句response的stream中没有被write入任何东西