`

json-lib 使用总结--java对象转json字符串

 
阅读更多

前言

json-lib是java开发中比较常用的java bean和json相互转换的工具, 它可配置化的解析过程使用起来非常灵活。但官方文档比较简单,新手使用稍有困难。

本文将简单介绍java bean转化为json的使用方式、渲染过程,并针对常见的问题给出解决方案。至于将json转换为java bean将另有文章进行讲解。

基本

java对象序列化为json有以下几个static方法可以作为入口:

java对象转json:

JSONObject.from(Object bean)

JSONObject.from(Object bean, JsonCofnig cfg)

java集合转json:

JSONArray.from(Object bean)

JSONArray.from(Object bean, JsonCofnig cfg)

 还有两个接口可以转任何java元素,包括对象、集合、简单变量、甚至null值等等。

JSONSerializer.toJSON(Object bean)

JSONSerializer.toJSON(Object bean, JsonCofnig cfg)

接口接收两个参数, bean即要序列化为json的java对象,bean可以是简单对象,也可以是聚合对象, cfg即转换配置,可以告诉转换器如何将bean序列化为json。由于以上接口仅仅是转换的对象不同,使用方式完全一样,本文将只针对JSONObject.from(..)进行说明。

 

将Employee对象转换为json字符串:

Employee employee = new Employee("郑永生", 28, "M");
JSONObject obj = JSONObject.fromObject(employee);
System.out.println(obj.toString());

 输出结果如下:

{"age":28,"name":"郑永生","sex":"M"}

序列化过程

java bean序列化为json的方式由JsonConfig进行控制,如果没有指定JsonConfig, json-lib将会创建一个默认的JsonConfig。

开始解析bean时, json-lib会先从JsonConfig中查找当前bean类型对应的json解析器JsonBeanProcessor, 如果配置了解析器将使用配置的解析器解析当前bean对象,如果没有配置则使用默认的解析器来解析bean对象。默认解析器解析过程如下:

  1. 创建一个空的JSONObject对象
  2.  获取bean中可序列化的属性(按getter方法获取);
  3.  过滤掉由transient关键字修饰的属性(属性声明或getter声明上都不能有transient关键字, 可以在jsonConfig中关闭这这个功能);
  4. 如果在JsonConfig中给当前bean类型注册 了jsonPropertyFilter, 则执行这个过滤器,过滤掉不需要序列化的属性(jsonPropertyFilter稍后讲解) ;
  5. 如果注册了JsonValueProcessor则执行执行这个Processor, 对属性值进行处理(一般序列化日期时在这里进行);
  6. 如果注册了propertyNameProcessor则执行这个Processor,对属性名(对应json的key)进行处理(java属性和json key名称不一样可以在这里处理);
  7. 将key, value写入JSONObject对象.

解析器

如何将java对象用json标示,最终是由解析器来决定的。

json-lib提供以下几种解析器接口:

DefaultValueProcessor: 为java类型指定默认值,我们一般不需要实现这个接口,json-lib提供的默认实现基本上可以满足我们的需要。

JsonBeanProcessor:为java对象指定一个解析器,稍后举例说明。

JsonValueProcessor:为bean的值指定一个解析器,可以将bean中的值输出到json后使用另外的值表示,稍后举例说明

PropertyNameProcessor: 为bean的属性名指定一个解析器,可以将bean中属性名称输出到json后变成另一个名称。

 一个JsonConfig对象可以注册多个解析器,既可以为按bean的类型注册解析器,也可以给特定类型的某一个属性指定解析器。

过滤器

将java bean序列化为json时,有些属性不需要写到json中,这时需要将这些属性过滤掉。

json-lib提供了三种方式来完成这项工作:

  • 在java 类对属性或属性的getter方法用关键字transient修饰。如: private transient double salary;需要在JsonConfig对象中开启这个功能, jsonConfig.setIgnoreTransientFields(true);
  • 在JsonConfig中显示声明需要忽略的属性(推荐使用这种方式), jsonConfig.registerPropertyExclusion(Employee.class, "salary"), 该接口接收两个参数,一个是需要过滤的属性所属的java类, 一个是属性名称。
  • 使用PropertyFilter,这个方式最强大而且灵活,可以在序列化过程中根据bean的类型、名称甚至值进行过滤。

使用PropertyFilter 过滤,需要实现PropertyFilter接口:

public interface PropertyFilter {
   /**
    * @param source属性所属的java bean对象
    * @param name 属性名称
    * @param value 属性值
    * @return 如果不希望当前属性写入json,则返回true, 否则返回false
    */
   boolean apply( Object source, String name, Object value );
}

 将过滤器注册到JavaConfig:javaConfig.setJsonPropertyFilter(propertyFilter );

 

一般来说,一个JavaCofig只能注册一个过滤器,有时候我们可能需要多个过滤器联合完成属性的过滤,这时可以考虑json-lib提供的几个PropertyFilter的几个实现类:

AndPropertyFilter: 组合两个过滤器实例,当同时满足两个过滤器过滤条件时,属性才会被过滤;

OrPropertyFilter: 组合两个过滤器实例,当属性满足其中一个过滤器过滤条件时,属性就会被过滤;

NotPropertyFilter: 组合一个过滤器A,当属性满足过滤器A时,不对属性进行过滤,否则对属性进行过滤

CompositePropertyFilter: 组合多个过滤器,当属性满足其中一个过滤器过滤条件时,属性就会被过滤;

FalsePropertyFilter:所有属性都不会被过滤;

TruePropertyFilter: 所有属性都会被过滤(不知道这个有什么用, ^_^);

MappingPropertyFilter: 这个是抽象类,可以设置一组键值对存储的过滤器, 每读取到一个bean属性时都会在这一组过滤器中寻找一个过滤器进行过滤,具体使用哪一个过滤器由方法keyMatches来决定。

public abstract class MappingPropertyFilter implements PropertyFilter {
   private Map filters = new HashMap();
     /**
      *@param key 过滤器对应的key值
      *@param source bean属性所属的java类
      *@param name bean属性名称
      *@param value bean属性的值
      *@return 返回true时,将使用key指向的过滤器过滤bean属性
      */
     protected abstract boolean keyMatches( Object key,  
                            Object source, String name, Object value );
         ....
     }

 

 常见问题及解决办法:

日期格式化问题:

json-lib提供的默认日期格式化方法往往不能满足我们的要求,这时可以自定义一个JsonValueProcessor来解析日期:

JsonValueProcessor dateProcessor = new JsonValueProcessor() {
    @Override
    public Object processArrayValue(Object value, JsonConfig jsonConfig) {
        return processObjectValue(Object value, JsonConfig jsonConfig);
    }
    @Override
    public Object processObjectValue(String key, Object value,
					JsonConfig jsonConfig) {
        DateFormat df = new SimpleDateFormat("yyyy年MM月dd日");
	return df.format((Date)value);
    }
};
Employee employee = new Employee("郑永生", 28, "M");
JsonConfig cfg = new JsonConfig();
cfg.registerJsonValueProcessor(Date.class, dateProcessor);
System.out.println(JSONObject.fromObject(employee, cfg));

 输出结果如下:

 

{"age":28,"birthday":"2014年11月16日","name":"郑永生","sex": "M"}

 

属性值或属性名称的转化

转化属性名和转化属性值用法基本一样,所不同的是实现的解析器接口不同,这里只举例说明值的转化。将bean属性输出到json时用另外的值表示,如下:将性别的'M''F'转化为中文表示:

 

/**
 * 将性别转换为中文标示
 */
 JsonValueProcessor sexProcessor = new JsonValueProcessor() {
    @Override
    public Object processArrayValue(Object value, JsonConfig jsonConfig) {
        return value;
    }
    @Override
    public Object processObjectValue(String key, Object value,
					JsonConfig jsonConfig) {
        if ("M".equals(value)) {
		return "男性";
	} else if ("F".equals(value)){
		return "女性";
	} 
   }
};
Employee employee = new Employee("郑永生", 28, "M");
JsonConfig cfg = new JsonConfig();
cfg.registerJsonValueProcessor(Employee.class, "sex", sexProcessor);
System.out.println(JSONObject.fromObject(employee, cfg));

 bean与json结构不一样:

有时候bean和json的属性(key)并不是一一对应的,比如,bean中的name用一个string属性表示,而json中可能需要用firstName和lastName表示,这时可以用JsonBeanProcessor来实现:

JsonBeanProcessor processor = new JsonBeanProcessor() {
    @Override
    public JSONObject processBean(Object bean, JsonConfig jsonConfig) {
	    JSONObject json = new JSONObject();
	    Employee ee = (Employee)bean;
            String[] names = ee.getName().split("\\.");			
	    json.put("firstName", names[0]);
	    json.put("lastName", names[1]);
	    json.put("age", ee.getAge());
	    return json;

    }
};	
JsonConfig cfg = new JsonConfig();
cfg.registerJsonBeanProcessor(Employee.class, processor);
Employee employee = new Employee("乔治.华盛顿", 28, "M");
System.out.println(JSONObject.fromObject(employee, cfg));

   输出结果如下:

{"firstName":"乔治","lastName":"华盛顿","age":28, ...}

 

结束语

附件是一个完整的eclipse工程,里面有更详细的代码示例和依赖的jar包。应该可以直接运行。

分享到:
评论

相关推荐

    使用json-lib将java对象转换成json字符串

    标题中的“使用json-lib将java对象转换成json字符串”指的是在Java编程中,利用json-lib这个库来将Java对象转化为JSON格式的字符串。JSON(JavaScript Object Notation)是一种轻量级的数据交换格式,广泛用于前后端...

    json-lib-2.4-jdk15.jar下载

    它可以将Java对象转换成JSON字符串,也可以将JSON字符串转换成Java对象。json-lib体积小、无依赖,性能表现也不错,适合在各种Java项目中使用。 json-lib的主要功能有: 1. 简单易用:json-lib的API简单易于使用,一般只...

    使用json-lib实现json与Java对象的互转

    将 JSON 字符串反序列化为 Java 对象,可以使用 `JsonDeserializer`: ```java Person deserializedPerson = (Person) jsonSerializer.deserialize(jsonString, Person.class); ``` 3. **处理数组和集合**: ...

    json-lib-2.4-jdk15.jar

    3. **JSON到Java对象的反序列化**:反之,它也提供了将JSON字符串转化为Java对象的功能,例如`JSONObject.toBean()`和`JSONArray.toList()`方法,能够将JSON数据映射到Java对象或列表。 4. **XML和JSON之间的转换**...

    json-lib-2.2.3-jdk15.jar

    3. 序列化和反序列化:通过`fromObject()`和`toObject()`方法将Java对象序列化为JSON字符串,或从JSON字符串反序列化回Java对象。 4. 处理复杂结构:对于包含嵌套对象和数组的复杂结构,JSON-lib也能轻松应对,只需...

    json-lib应用所有jar

    JSON-lib是Java平台上的一个库,它提供了一种方便的方式来序列化和反序列化Java对象为JSON格式,以及从JSON字符串恢复Java对象。这个库在处理JSON数据时非常实用,特别是对于那些需要在服务器端和客户端之间进行数据...

    json-lib-2.1.jar和struts2-json-plugin-2.1.8.1.jar

    在Java世界里,`json-lib-2.1.jar` 是一个用于处理JSON的库,它提供了一系列的方法来将Java对象转换为JSON格式,以及将JSON字符串反序列化回Java对象。这个库支持多种Java类型,包括基本类型、集合、Map、自定义Java...

    json-lib-2.2.2-jdk15.jar

    1. **JSON序列化与反序列化**:json-lib允许将Java对象转换为JSON字符串,反之亦然。例如,你可以将一个Java的HashMap转换成JSON格式,便于在网络上传输,或者将接收到的JSON字符串解析成Java对象,便于进一步处理。...

    json-lib-2.4-jdk15和全部依赖jar包

    JSON库如`json-lib`则提供了将Java对象转换为JSON格式和从JSON字符串反序列化为Java对象的功能。`json-lib-2.4-jdk15`是JSON库的一个特定版本,专为JDK 1.5设计,确保在该环境下能够正常运行。 `json-lib`库主要...

    json-lib-2.3.jar

    4. 如果需要将JSON字符串反序列化回Java对象,可以使用`JSONObject.toBean()`或`JSONArray.toList()`方法。 在项目中,`lib`目录下的json-lib-2.3.jar文件应当被正确地添加到构建路径或依赖管理中,以确保程序能够...

    json-lib-2.4和相应的依赖包

    1. **JSON到Java对象转换**:通过JsonNode、JSONArray和JSONObject等类,json-lib可以解析JSON字符串并生成对应的Java对象。例如,一个JSON对象可以被映射为一个HashMap,而一个JSON数组则可以转换为ArrayList。 2....

    json-lib jar和所有依赖的jar

    1. 将Java对象(如:数组、集合、Map、自定义对象等)转换为JSON字符串。 2. 将JSON字符串反序列化回对应的Java对象。 3. 提供了多种数据类型转换的API,支持不同数据结构间的转换。 4. 支持XML与JSON之间的转换,...

    JSON-lib包json-lib-0.8.jar和json-lib-0.9.jar包

    `json-lib-0.8.jar`是JSON-lib的0.8版本,它可能包含基础的JSON转换功能,如将Java对象转换为JSON字符串,以及反向操作,即将JSON字符串解析回Java对象。此外,它可能还支持JSON数组和JSON对象的创建、读取和修改。...

    json-lib-2.4-jdk15.jar及其相关依赖

    在Java开发中,`json-lib`库提供了多种将Java对象序列化为JSON字符串的方法,包括: 1. **Java Bean到JSON**: 只需传入一个Java Bean对象,`json-lib`就能将其转换为JSON格式的字符串。 2. **Map到JSON**: 对于包含...

    json-lib-2.3-jdk15开发包和所有依赖包

    `json-lib`是一个Java库,它提供了将Java对象转换为JSON格式,以及从JSON字符串反序列化回Java对象的功能。`json-lib-2.3-jdk15`是这个库的一个特定版本,兼容JDK 1.5,这意味着它可以在运行JDK 1.5或更高版本的Java...

    json-lib-2.3-jdk15基础jar包合辑

    - **数据存储**:在持久化框架如Hibernate中,JSON Lib可以用于将Java对象转换成JSON字符串,方便存储到数据库的JSON字段。 - **前端交互**:后端开发中,通过JSON格式与前端JavaScript进行数据交互,JSON Lib简化了...

    json-lib-2.4-jdk15及其依赖jar包

    如果你接收到一个JSON字符串,你可以使用`JSONObject.toBean()`或`JSONArray.toList()`方法将它转换回相应的Java对象,如HashMap、ArrayList或其他自定义类的实例。 3. **处理数组和集合**:JSON-Lib支持将Java的...

    json-lib所用的jar包

    综上所述,`json-lib`依赖于这些库来提供完整的JSON转换功能,从Java对象到JSON字符串的序列化,以及从JSON字符串到Java对象的反序列化。在实际开发中,通过这些库的配合,开发者可以轻松地在服务器和客户端之间传递...

    json-lib.jar

    在Java中,处理JSON通常涉及两个主要任务:将Java对象转换为JSON字符串(序列化),以及将JSON字符串解析回Java对象(反序列化)。JSON-lib.jar提供了这样的功能,使得开发者能够方便地在Java对象和JSON格式之间进行...

Global site tag (gtag.js) - Google Analytics