• HttpServletResponse 返回的json数据不是json字符串,而是json对象


    今天在改一个bug

    情况:

      在spring boot中写了一个类Result ,用来统一封装 各个API响应结果 , 其中重写了toString()方法来返回 json字符串 。

      在正常情况下,从其它API 返回给前端的结果都是json字符串,前端可以正确解析

      但遇到一些异常的情况,返回给前端的结果却是json对象数据,key少了双引号,前端无法正确解析

    从一开始调试到后面网上查找各种资料,想过有可能是注解、方法重写、调用等方面出错,但都难以找到根源

    直到后面看到一篇文章说到write() 方法对结果的处理问题,才有所悟,并调试确定了根源

    其他能够正确返回json 字符串的,是因为 RestController 注解自动将对象转成了json字符串

    而 response.getWriter().write() 是直接将json对象写进去,并没有自动转换成json字符串格式

     1     private void responseResult(HttpServletResponse response, Result<?> result) {
     2         response.setCharacterEncoding("UTF-8");
     3         response.setHeader("Content-Type", "application/json");
     4         response.setHeader("Access-Control-Allow-Credentials", "true");
     5         response.setHeader("Access-Control-Allow-Methods", "GET, POST");
     6         response.setHeader("Access-Control-Allow-Origin", "*");
     7         response.setHeader("Access-Control-Max-Age", "3600");       
     8 //        response.setHeader("Content-type", "application/json;charset=UTF-8");
     9         response.setStatus(HttpServletResponse.SC_OK);
    10         response.setContentType("application/json;charset=UTF-8");
    11 //        ServletOutputStream out = null;
    12         PrintWriter writer=null;
    13         try {
    14             // JSON.toJSONString(result)要获取完整的json字符串,每一个字段都要有set和get方法,不然会缺少某个字段
    15 //            response.getWriter().write(JSON.toJSONString(result));
    16             writer=response.getWriter();
    17 //            writer.write(result.toString());
    18             writer.write(JSON.toJSONString(result));
    19             writer.flush();
    20         } catch (IOException ex) {
    21             logger.error(ex.getMessage());
    22         }finally {
    23             if(writer!=null) {
    24                 writer.close();
    25             }
    26         }
    27     }

    而至于重写的toString()方法为什么没有直接返回json字符串

     1       @Override
     2       public String toString() {
     3           Map<String, Object> resultMap=new ConcurrentHashMap<String, Object>();
     4           resultMap.put("code", code);
     5           resultMap.put("result", result);
     6           resultMap.put("msg", msg);
     7           if(data!=null) {
     8               resultMap.put("data", data);
     9           }else {
    10              resultMap.put("data", "");
    11           }
    12           return JSON.toJSONString(resultMap, SerializerFeature.WRITE_MAP_NULL_FEATURES);
    13       }

     现在终于找到问题了

    resultMap:{result=false, msg=访问token无效, code=401, data=}
    JSON.toJSONString(resultMap):{"result":false,"msg":"访问token无效","code":401,"data":""}
    JSON.toJSONString(resultMap, SerializerFeature.WRITE_MAP_NULL_FEATURES):{result:false,msg:"访问token无效",code:401,data:""}

    可以看到  JSON.toJSONString(resultMap, SerializerFeature.WRITE_MAP_NULL_FEATURES)  返回的字符串中,key 是没有双引号的 

    这个算是 com.alibaba.fastjson 的一个坑吧

      

    参考:

    Spring的ResponseBody和RestController注解返回的json数据不是json字符串,而是json对象...   https://blog.csdn.net/weixin_33890526/article/details/87167889 

    Object与json字符串的相互转换   https://blog.csdn.net/justry_deng/article/details/80780175  

    fastjson:SerializerFeature属性使用   https://blog.csdn.net/zxl2016/article/details/80987414  

    共同学习,共同进步,若有补充,欢迎指出,谢谢!

  • 相关阅读:
    VS使用技巧
    写的一个简单定时器(非独立线程)
    C/C++技巧
    【转载】R6034错误,C Runtime Error
    C/C++面试题(一)
    常用的coco2d-x游戏开发工具(转)
    AndroidJNI 调用JAVA(转)
    Android SDK +Eclipse+ADT+CDT+NDK 开发环境在windows 7下的搭建
    简单的字符串压缩--C代码
    SQLite: sqlite_master(转)
  • 原文地址:https://www.cnblogs.com/dengguangxue/p/11249918.html
Copyright © 2020-2023  润新知