A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

本帖最后由 大蓝鲸Java 于 2017-12-1 12:34 编辑

【南京校区】JAVA中JSON格式数据的使用


JSON是一种轻量级的数据交换格式。在我们的JAVA WEB开发中,前后台的数据交互,就是用的JSON传输的。关于JSON的语法规则也很简单。这里我们就不在赘述了。接下来我们主要来谈谈我们JSON数据在浏览器端和服务器端的使用,重点说说我们JAVA中如何解析json数据,并给大家介绍一些我们开发中常用的JSON解析工具。
JSON数据的处理

1、浏览器端
       在浏览器端js中可以直接声明我们的json对象
              定义json数组:var jsonArr =[123,"abc",{"name":"root","password":"123456"}];
              定义json对象:var jsonUser ={"id":"123","username":"jack","password":"123456","nickname":"贝爷"};
       同时在js中我们可以实现json对象与字符串的互相转换
              Json对象转字符串:JSON.stringify();
              Json字符串转Json对象:JSON.parse();

2、服务器端
服务器端对json数据的操作无外乎两种:
       一、将java中的对象转化为json字符串,响应到浏览器端
       二、从浏览器端接受json格式的字符串,解析字符串
在开发中常用的JSON解析工具有fastjson、jackson、gson、jsonlib等,下面简单介绍下这些工具的使用

FastJson使用简介
FastJson是阿里巴巴(马云粑粑)提供的一个开源的JSON解析工具,号称是最快的JSON解析工具,具体快不快还要用了之后再能说啊。
FastJson的maven依赖:
[Java] 纯文本查看 复制代码
<dependency>
             <groupId>com.alibaba</groupId>
             <artifactId>fastjson</artifactId>
             <version>1.2.41</version>
</dependency>


FastJson对于json的操作提供了如下几种情形:
情形一、Java对象转Json字符串(重点操作
[Java] 纯文本查看 复制代码
JSONObject.toJSONString(obj);
JSONObject.toJSONString(obj, SerializeFilter):SerializeFilter可用来过滤掉不需要转成json的属性
对于Java对象转Json字符串存在以下问题需要解决:
1、忽略属性
使用SerializeFilter类过滤
   
[Java] 纯文本查看 复制代码
SerializeFilter filter = new PropertyFilter() {[align=left]                @Override[/align][align=left]                public boolean apply(Object arg0, String arg1, Object arg2) {[/align][align=left]                        if ("id".equals(arg1)) {[/align][align=left]                                return false;[/align][align=left]                        }[/align][align=left]                        return true;[/align][align=left]                }[/align]        };

2、日期类型格式化
[Java] 纯文本查看 复制代码
//方式一、使用注解
@JSONField(format="yyyy-MM-dd")
private Date birthday;
//方式二、配置默认日期格式化
JSONObject.DEFFAULT_DATE_FORMAT="yyyy-MM-dd";
SerializerFeature.WriteDateUseDateFormat

情形二、Java对象转Json对象(不建议操作):
[Java] 纯文本查看 复制代码
JSONObject.toJSON(list);
JSONArray.toJSON(list);
JSON.toJSON(list);

情形三、Json对象转Json字符串
[Java] 纯文本查看 复制代码
json2.toJSONString();
json2.toString();

情形四、Json对象转Java对象(不推介使用)
[Java] 纯文本查看 复制代码
JSONObject.toJavaObject(json, clazz);
JSON.toJavaObject(json, clazz);
JSONArray.toJavaObject(json, clazz);
json对象.toJavaObject(clazz);

情形五、Json字符串转java对象(重点操作
   Ø直接转化为javaBean对象
[Java] 纯文本查看 复制代码
String userJsonStr = "{'id':'111','username':'tom','password':'123456','birth_day':'1990-09-09'"[/align]+ ",'car':{'cid':'1111','cname':'BMW740Li','color':'red'},"
+ "'orders':[{'oid':'1','oname':'订单一'},{'oid':'2','oname':'订单二'}]}";
User parse = JSON.parseObject(userJsonStr,User.class);
User user = JSON.parseObject(userJsonStr, new TypeReference<User>() {});

  Ø 转化为javaBean的list集合
[Java] 纯文本查看 复制代码
String userJsonStr = "[{'id':'111','username':'tom','password':'123456','birthday':'1990-09-09',"
                                + "'car':{'cid':'1111','cname':'BMW740Li','color':'red'},"
                                + "'orders':[{'oid':'1','oname':'订单一'},{'oid':'2','oname':'订单二'}]},"
                                + "{'id':'112','username':'jerry','password':'123456','birthday':'1990-08-08',"
                                + "'car':{'cid':'1112','cname':'BenzS600L','color':'white'},"
                                + "'orders':[{'oid':'1','oname':'订单一'},{'oid':'2','oname':'订单二'}]}]";
    List<User> list = JSON.parseArray(userJsonStr, User.class);
    List<User> list2 = JSON.parseObject(userJsonStr,new TypeReference<List<User>>(){});

  Ø转化为javaBean的map集合
[Java] 纯文本查看 复制代码
String userJsonStr = "{'user':{'id':'111','username':'tom','password':'123456','birthday':'1990-09-09',"
                                + "'car':{'cid':'1111','cname':'BMW740Li','color':'red'},"
                                + "'orders':[{'oid':'1','oname':'订单一'},{'oid':'2','oname':'订单二'}]}}";
    Map<String, User> map = JSON.parseObject(userJsonStr, new TypeReference<Map<String, User>>(){});


情形六、Json字符串转Json对象(JSONArray和JSONObject)
[Java] 纯文本查看 复制代码
String userJsonStr = "{'id':'111','username':'tom','password':'123456','birth_day':'1990-09-09'"
                                + ",'car':{'cid':'1111','cname':'BMW740Li','color':'red'},"
                                + "'orders':[{'oid':'1','oname':'订单一'},{'oid':'2','oname':'订单二'}]}";
    JSONObject jsonObject = JSON.parseObject(userJsonStr);

Jackson使用简介
        jackson是一个高效的JSON解析工具,jackson提供了一个ObjectMapper类来完成JSON解析Jackson的maven依赖:
[Java] 纯文本查看 复制代码
<dependency>
                        <groupId>com.fasterxml.jackson.core</groupId>
                        <artifactId>jackson-databind</artifactId>
                        <version>2.9.2</version>
                </dependency>
                <dependency>
                        <groupId>com.fasterxml.jackson.core</groupId>
                        <artifactId>jackson-core</artifactId>
                        <version>2.9.2</version>
                </dependency>
                <dependency>
                        <groupId>com.fasterxml.jackson.core</groupId>
                        <artifactId>jackson-annotations</artifactId>
                        <version>2.9.2</version>
                </dependency>

JSON生成器:生成JSON字符串
[AppleScript] 纯文本查看 复制代码
ObjectMapper objectMapper = new ObjectMapper();
String valueAsString = objectMapper.writeValueAsString(user);

        1、忽略属性
编码方式:
[XML] 纯文本查看 复制代码
        // 处理过滤属性
//  FilterProvider fp = new SimpleFilterProvider().addFilter("productFilter",
//   SimpleBeanPropertyFilter.filterOutAllExcept("id", "name")); //只包含id与name
      FilterProvider fp = new SimpleFilterProvider().addFilter("productFilter",
      SimpleBeanPropertyFilter.serializeAllExcept("id", "name")); //不包含id与name
      mapper.setFilters(fp);//定义完这些后还需要在对应的类上使用@JsonFilter("productFilter")注解

注解方式:
[Java] 纯文本查看 复制代码
//@JsonIgnoreProperties({ "id", "releaseDate" })
public class Product {
        // @JsonIgnore
        private int id;
        private String name;
        private double price;


        2、日期类型格式化
编码方式:
[Java] 纯文本查看 复制代码
objectMapper.setDateFormat(new SimpleDateFormat("yyyy年MM月dd日"));

注解方式:
[Java] 纯文本查看 复制代码
@JsonFormat(pattern="yyyy-MM-dd")
private Date birthday;


JSON解析器:解析json字符串
[Java] 纯文本查看 复制代码
String userJsonStr = "{\"id\":\"111\",\"username\":\"tom\",\"password\":\"123456\",\"birthday\":\"1990-09-09\""
                                + ",\"car\":{\"cid\":\"1111\",\"cname\":\"BMW740Li\",\"color\":\"red\"},"
                                + "\"orders\":[{\"oid\":\"1\",\"oname\":\"订单一\"},{\"oid\":\"2\",\"oname\":\"订单二\"}]}";
         try {
                  ObjectMapper objectMapper = new ObjectMapper();
                  User user = objectMapper.readValue(userJsonStr, User.class);
                  User user2 = objectMapper.readValue(userJsonStr, new TypeReference<User>() {});
              } catch (IOException e) {
                    e.printStackTrace();
              }


JSONlib使用简介
        Jsonlib操作json数据主要是通过两个对象JSONObject和JSONArray来实现的
Jsonlib的maven依赖:
[XML] 纯文本查看 复制代码
<dependency>
                        <groupId>net.sf.json-lib</groupId>
                        <artifactId>json-lib</artifactId>
                        <version>2.4</version>
                        <classifier>jdk13</classifier>
                </dependency>
                <dependency>
                        <groupId>net.sf.json-lib</groupId>
                        <artifactId>json-lib</artifactId>
                        <version>2.4</version>
                        <classifier>jdk13-javadoc</classifier>
                </dependency>
                <dependency>
                        <groupId>net.sf.json-lib</groupId>
                        <artifactId>json-lib</artifactId>
                        <version>2.4</version>
                        <classifier>jdk13-sources</classifier>
                </dependency>
Java对象转json字符串
[Java] 纯文本查看 复制代码
JSONObject jsonObject = JSONObject.fromObject(arr);
JSONArray jsonArray = JSONArray.fromObject(arr);

        1、忽略属性
[Java] 纯文本查看 复制代码
JsonConfig jsonConfig = new JsonConfig();
                // 方式一:
                jsonConfig.setExcludes(new String[]{"id","username"});
                // 方式二:
                jsonConfig.setJsonPropertyFilter(new PropertyFilter() {
                @Override
                public boolean apply(Object arg0, String name, Object arg2) {
                        if("id".equals(name)){
                                 return true;
                          }
                          if("username".equals(name)){
                                return true;
                          }
                          return false;
                 }
          });      JSONObject jsonObject = JSONObject.fromObject(user,jsonConfig);

        2、格式化日期类型
[Java] 纯文本查看 复制代码
// 方式一、处理指定列
    jsonConfig.registerJsonValueProcessor("birthday", new JsonValueProcessor() {
              @Override
              public Object processArrayValue(Object value, JsonConfig jsonConfig) {
                       return null;
               }
              @Override
               public Object processObjectValue(String key, Object value, JsonConfig jsonConfig) {
                       SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
                       return simpleDateFormat.format(value);
               }});
                // 方式二、处理指定类型
      jsonConfig.registerJsonValueProcessor(Date.class, new JsonValueProcessor() {
              @Override
              public Object processObjectValue(String key, Object value, JsonConfig jsonConfig) {
                     SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
                     return simpleDateFormat.format(value);
            }
              @Override
               public Object processArrayValue(Object value, JsonConfig jsonConfig) {
                       return null;
               }
      });
     jsonConfig.setCycleDetectionStrategy(CycleDetectionStrategy.LENIENT);


Json字符串转java对象
[Java] 纯文本查看 复制代码
String userJsonStr = "{'id':'111','username':'tom','password':'123456','birthday':'1990-09-09'"
                                + ",'car':{'cid':'1111','cname':'BMW740Li','color':'red'},"
                                + "'orders':[{'oid':'1','oname':'订单一'},{'oid':'2','oname':'订单二'}]}";
JSONObject jsonObject = JSONObject.fromObject(userJsonStr);
Map<String, Class> map = new HashMap<String,Class>();
map.put("orders", Order.class);//User类中有一个orders属性List<Order>,Jsonlib在解析它的时候不知道应该如何转换,这里是明确的告诉jsonlib如何去处理orders属性的值。
User user = (User) JSONObject.toBean(jsonObject, User.class,map);


Gson使用简介
    GSON是Google开发的Java API,用于转换Java对象和Json对象。
GSON的maven依赖:
[XML] 纯文本查看 复制代码
<dependency>
                        <groupId>com.google.code.gson</groupId>
                        <artifactId>gson</artifactId>
                        <version>2.8.2</version>
                </dependency>
Java  对象转换为 JSON 字符串
[Java] 纯文本查看 复制代码
Gson gson = new GsonBuilder().create();
                String userTest = gson.toJson(user);

        1、忽略属性
[Java] 纯文本查看 复制代码
// gson解析时会默认忽略没有值的属性,调用serializeNulls(),gson解析的字符串中没有值的属性也会展示出来
Gson gson = new GsonBuilder().serializeNulls().create();
String userTest = gson.toJson(user);
 // 调用excludeFieldsWithoutExposeAnnotation(),Gson在解析成json字符串时,只会解析那些有@Expost注解的字段
 Gson gson = new GsonBuilder().excludeFieldsWithoutExposeAnnotation().create();
 String userTest = gson.toJson(user);
 // 指定gson在解析时,不解析指定修饰符的属性。不过这个基本没什么用,因为我们javaBean的属性的修饰符一般默认都是private
  Gson gson = new GsonBuilder().excludeFieldsWithModifiers(Modifier.PROTECTED).create();
  String userTest = gson.toJson(user);
 // 使用ExclusionStrategy定制字段排除策略
  new GsonBuilder().setExclusionStrategies(new ExclusionStrategy() {
         @Override
         // 根据属性名称忽略
         public boolean shouldSkipField(FieldAttributes f) {
                 if("id".equals(f.getName())){
                       return true;//获取id属性
                   }
                 return false;
         }
          @Override
          //根据属性类型忽略
         public boolean shouldSkipClass(Class<?> clazz) {
                   return false;
           }
 });

        2、格式化日期类型
[Java] 纯文本查看 复制代码
Gson gson = new GsonBuilder().setDateFormat("yyyy-MM-dd").create();
String userTest = gson.toJson(user);



JSON字符串转化为java对象
[Java] 纯文本查看 复制代码
String userJsonStr = "{\"id\":\"111\",\"username\":\"tom\",\"password\":\"123456\",\"birthday\":\"1990-09-09\""
                                + ",\"car\":{\"cid\":\"1111\",\"cname\":\"BMW740Li\",\"color\":\"red\"},"
                                + "\"orders\":[{\"oid\":\"1\",\"oname\":\"订单一\"},{\"oid\":\"2\",\"oname\":\"订单二\"}]}";
Gson gson = new GsonBuilder().create();
User user = gson.fromJson(userJsonStr, User.class);


不同的JSON解析工具性能测试(测试结果仅供参考!!)
测试情形:User对象转JSON字符串,循环执行10万次,重复测试200次,记录评价耗时
测试结果:
       FastJson:30ms
       Jackson :45ms
       Gson     :180ms
       Jsonlib  :880ms
测试情形:JSON字符串转User对象,循环执行10万次,重复测试200次,记录平均耗时
测试结果:
       FastJson:370ms
       Jackson :175ms
       Gson     :990ms
       Jsonlib  :1120ms
通过上述测试我们可以大概了解,四种JSON解析工具,Fastjson和Jackson的效率是最高的(说明阿里还是很n牛B的!!),Gson次之,Jsonlib的效率是最差的。
关于性能测试的代码有点多就不在帖子里面写咯。想看的,附件就是哦!!









test.rar

2.8 KB, 下载次数: 80

3 个回复

正序浏览
不明觉厉!哈哈哈哈哈
回复 使用道具 举报
郭俊峰老师 来自手机 高级黑马 2017-12-3 16:26:34
藤椅
关于JSON的那点事
回复 使用道具 举报
这个没毛病  必须会
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马