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();
    }
不知是开发者秀逗了还是另有乾坤??

解决方案 »

  1.   

    在Struts 2中使用JSON Ajax支持 http://www.phome.asia/forum/thread/17482.html
      

  2.   

    struts2+jQuery+formValidator注册时ajax验证用户名和邮箱问题  
    http://www.phome.asia/forum/thread/22019.htmlStruts2+JQuery+JSON集成开发实例  
    http://www.phome.asia/forum/thread/22071.html
      

  3.   

    不知道楼主现在知道json的格式为/*{ ... }*/是什么原因了吗?看了你的帖子我也很想知道答案,我也正在想使用json到struts2中并进行输入校验。
    如果你有答案了,还得向你在这里请教一下了。
      

  4.   

    JSONValidationInterceptor encodes result surrounded by /**/ is for security issue.
    簡單的說,它不想回傳一個可以直接 eval 成物件的字串,所以用javascript的註解包起來,
    要使用的話,程式碼如下...
    var responseObject = eval("("+data.substring(data.indexOf("\/\*")+2, data.lastIndexOf("\*\/"))+")");
    詳細的情形,You can google 'JSON Hijacking'.
      

  5.   

    另外請問樓主一個問題,我的JSONValidationInterceptor都沒有回應,
    我去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>謝謝!!
      

  6.   

    JSONValidationInterceptor return none的result实际上就是不dispatcher或者redirect到url了。
    如果response中没有write出任何东西,页面中将不write出任何东西。不需要定义none的result。
    我先知道你如何一句response的stream中没有被write入任何东西