日期:2014-05-16  浏览次数:20335 次

JSONValidationInterceptor的一个bug, 返回的json数据竟然被注释了

/* { "fieldErrors": {"password":["密码长度为3-20字符"]}} */

上面就是校验出错时JSONValidationInterceptor返回给我的结果,竟然被/* {} */包围。

这样产生的问题是:使用JQuery这样的ajax框架时,如果设置了返回数据类型dataType=json,? jQuery会自动解析返回的字符串成为json对象,倒霉的是,非良构的json字串会被jQuery忽略掉,从而导致回调方法永远不会被执行。

查看源码发现问题在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();
    }

?请看

sb.append("/* { ");

sb.append("} */");

这确实是个bug,倒不是开发人员故意而为之,在struts2.2.2会被fix掉。

http://struts.1045723.n5.nabble.com/jira-Created-WW-3545-JSONValidationInterceptor-Returns-Invalid-quot-true-quot-json-Do-not-put-javascn-td3550970.html

如果你只能用2.2.2以前的版本,那就重新自定义这个interceptor,把上面的代码改为

?

sb.append(" { ");

sb.append(" } ");

即可。