Chinaunix首页 | 论坛 | 博客
  • 博客访问: 533429
  • 博文数量: 135
  • 博客积分: 3568
  • 博客等级: 中校
  • 技术积分: 1942
  • 用 户 组: 普通用户
  • 注册时间: 2006-10-19 17:52
文章分类

全部博文(135)

文章存档

2012年(29)

2011年(41)

2010年(26)

2009年(12)

2008年(9)

2007年(12)

2006年(6)

分类: Java

2010-03-14 23:03:33

打包下载 :test.json_lib.zip

Test.java

/**
 * Json-lib 的使用示例,Person Bean应该将使用到的种种数据类型都考虑到了。
 *
 * 因项目需要,需使用C#写的ActiveX控件与Java Web服务器端通过JSON来传递数据。
 * 但是,XStream 无法满足要求,它无法将List按照Array对待,无法将Map按照Bean对待。
 *
 * 所以使用JSON-lib,可能是开源代码无利可图的原因吧,也就版本发布及时,其他的,比如
 * JavaDoc,网站上的使用说明等非常非常的少。下面这个例子则介绍了如何使用Json-lib的
 * 扩展机制将Date类型按指定格式序列化,和反序列化,以及将byte[]按照Base64进行序列化
 * 和反序列化。
 *
 * 网上也有推荐使用 jsontools,和gson的,但是时间、精力有限,未做详查!
 *
 * @author btpka3@163.com
 * @date 2010/03/14
 */


package test.json_lib;

import java.util.Arrays;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import net.sf.ezmorph.object.DateMorpher;
import net.sf.json.JSONObject;
import net.sf.json.JsonConfig;
import net.sf.json.util.CycleDetectionStrategy;
import net.sf.json.util.JSONUtils;

public class Test {

    public static void main(String[] args) {
        testJson();
    }

    /**
     *


     * 当运行以下代码代码时,大家会期待怎样的结果呢?(直接数据Date对象,而不是包含 Date类型字段的JavaBean)
     *


     *


     * 结果是,不是 "yyyy-MM-dd HH:mm:ss.SSS z" 格式的字符串,而是 JsDateJsonBeanProcessor 生成的
     * javascript Object (以"{"开始,以"}"结束),为什么呢?是否是因为无法
     * 将单独的一个字符串表达为一个JSON表示的字符串?所以就启用 JsonBeanProcessor 将其表示为一个JSON表示的Object?
     *


     *


     * 应该与 JsonBeanProcessor、JsonValueProcessor 这两个接口有关。分别有自带的
     * 关于日期转换的实现:JsDateJsonValueProcessor、JsDateJsonBeanProcessor,其中
     * JsDateJsonValueProcessor 內部是依靠 JsDateJsonBeanProcessor 实现。可是却在
     * Json-lib的源代码里找不到他们何时被注册的。所以我无法将其unregister。
     *


     *
     */
    public static void testDate() {
        JsonConfig jsonConfig = new JsonConfig();
        jsonConfig.registerJsonValueProcessor(Date.class,
                new DateJsonValueProcessor());
        JSONObject descJsonObj = JSONObject.fromObject(Calendar.getInstance()
                .getTime(), jsonConfig);
        System.out.println(descJsonObj.toString(2));
    }

    public static void testJson() {
        Person son = new Person();
        Person mom = new Person();

        son.setName("SSS");
        son.setAge(25);
        son.getAge();
        son.setMale(true);

        Calendar calendar = Calendar.getInstance();
        calendar.add(Calendar.YEAR, -son.getAge());
        calendar.set(Calendar.MONTH, 8);
        calendar.set(Calendar.DAY_OF_MONTH, 9);
        calendar.set(Calendar.HOUR_OF_DAY, 9);
        calendar.set(Calendar.MINUTE, 9);
        calendar.set(Calendar.SECOND, 9);
        son.setBirthday(calendar.getTime());
        son.setAlias(new String[] { "SSS0", "SSS00", "SSS000" });
        son.setImageData(new byte[] { 1, 2, 3, 4, 5, 10, 20, 30, 40, 50 });
        son.setFavors(Arrays.asList(new String[] { "Listening music",
                "Sleeping", "Play games", " test \n\t<>,\"\"_'ABC'&&|| " }));

        Map<String, String> addrs = new HashMap<String, String>();
        addrs.put("Work", "Beijing");
        addrs.put("School", "Shandong");
        addrs.put("Home", "Henan");
        son.setAddrs(addrs);
        son.setParent(mom);

        mom.setName("MMM");
        mom.setAge(50);
        mom.setMale(false);
        calendar = Calendar.getInstance();
        calendar.add(Calendar.YEAR, -mom.getAge());
        mom.setBirthday(calendar.getTime());
        mom.setAlias(new String[] { "MMM0", "MMM00", "MMM000" });
        mom.setImageData(new byte[] { 6, 7, 8, 9, 0, 60, 70, 80, 90, 100 });
        mom.setFavors(Arrays.asList(new String[] { "Enjoy cate", "Chatting",
                "Shopping" }));
        addrs = new HashMap<String, String>();
        addrs.put("Work", "Viliage");
        addrs.put("School", "Viliage");
        addrs.put("Home", "Viliage");
        mom.setAddrs(addrs);
        mom.setChild(son);

        System.out.println("\n-------------Son:");
        System.out.println(son);
        
        ///////////// 序列化 /////////////////////////////////////////////////

        
        JsonConfig jsonConfig = new JsonConfig();
        // 因为 mom 和 son 之间通过 setChild() 和 setParent() 相互引用,从而造成

        // 环状引用,需要指定相应的解决机制,这里为使用 null 或者 空的 array 解决。

        jsonConfig.setCycleDetectionStrategy(CycleDetectionStrategy.LENIENT);
        // 注册我们的 Date 序列化类

        jsonConfig.registerJsonValueProcessor(java.util.Date.class,
                new DateJsonValueProcessor());
        // 注册我们的 byte[] 序列化类

        jsonConfig.registerJsonValueProcessor(byte[].class,
                new ByteArrayJsonValueProcessor());
        // 序列化

        JSONObject toJsonObj = JSONObject.fromObject(son, jsonConfig);
        String json = toJsonObj.toString(2);

        System.out.println("\n-------------toJSON:");
        System.out.println(json);

        
        
        ///////////// 反序列化 /////////////////////////////////////////////////

        
        // 注册我们需要的 Date 格式的反序列化类

        JSONUtils.getMorpherRegistry().registerMorpher(
                new DateMorpher(new String[] { "yyyy-MM-dd HH:mm:ss.SSS z" }));
        // 注册我们将 base64字符串反序列化为 byte[] 的类

        JSONUtils.getMorpherRegistry()
                .registerMorpher(new MyByteArrayMorpher());
        // 反序列化

        JSONObject fromJsonObj = JSONObject.fromObject(json);
        Person newSon = (Person) JSONObject.toBean(fromJsonObj, Person.class);
        
        System.out.println("\n-------------fromJSON:");
        System.out.println(newSon);
    }

}

Person.java

package test.json_lib;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Map;

public class Person {
    private String name;
    private int age;
    private boolean male;



    private Date birthday;
    private String[] alias;
    private byte[] imageData;
    private List<String> favors;
    private Map<String, String> addrs;
    private Person parent;
    private Person child;
    private Object nullObject = null;

    public String toString() {
        StringBuilder buf = new StringBuilder();
        buf.append("name\t= " + name);
        buf.append("\nage\t=" + age);
        buf.append("\nmale\t=" + male);
        SimpleDateFormat smf = new SimpleDateFormat("yyyy/MM/dd");
        buf.append("\nbirthday\t=" + smf.format(birthday));
        buf.append("\nalias\t=");
        for (String s : alias) {
            buf.append(s);
            buf.append(", ");
        }
        buf.append("\nimageDate\t=");
        for (byte b : imageData) {
            buf.append(b);
            buf.append(", ");
        }
        buf.append("\nfavors\t=" + favors);
        buf.append("\naddrs\t=" + addrs);
        buf.append("\n\nparent\n" + parent);
        return buf.toString();
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public boolean isMale() {
        return male;
    }

    public void setMale(boolean male) {
        this.male = male;
    }
    
    public Date getBirthday() {
        return birthday;
    }

    public void setBirthday(Date birthday) {
        this.birthday = birthday;
    }

    public String[] getAlias() {
        return alias;
    }

    public void setAlias(String[] alias) {
        this.alias = alias;
    }

    public byte[] getImageData() {
        return imageData;
    }

    public void setImageData(byte[] imageData) {
        this.imageData = imageData;
    }

    public List<String> getFavors() {
        return favors;
    }

    public void setFavors(List<String> favors) {
        this.favors = favors;
    }

    public Map<String, String> getAddrs() {
        return addrs;
    }

    public void setAddrs(Map<String, String> addrs) {
        this.addrs = addrs;
    }

    public Person getParent() {
        return parent;
    }

    public void setParent(Person parent) {
        this.parent = parent;
    }

    public Person getChild() {
        return child;
    }

    public void setChild(Person child) {
        this.child = child;
    }

    public Object getNullObject() {
        return nullObject;
    }

    public void setNullObject(Object nullObject) {
        this.nullObject = null;
    }

}

 

DateJsonValueProcessor.java

package test.json_lib;

import java.text.SimpleDateFormat;

import net.sf.json.JsonConfig;
import net.sf.json.processors.JsonValueProcessor;
/**
 * [Java -> JSON] java.util.Date -> "yyyy-MM-dd" etc. string <br/>
 *
 * Json-lib默认的Java -> JSON的日期表示格式与java经常用的大相径庭,所以使用此
 * 扩展来将Date格式化为字符串。
 * 
 *
 * @author btpka3
 */
public class DateJsonValueProcessor implements JsonValueProcessor {
    private String dateFormat = "yyyy-MM-dd HH:mm:ss.SSS z";

    @Override
    public Object processArrayValue(Object value, JsonConfig jsonConfig) {
        return null;
    }

    @Override
    public Object processObjectValue(String key, Object value,
            JsonConfig jsonConfig) {
        SimpleDateFormat sdf = new SimpleDateFormat(dateFormat);
        return sdf.format(value);
    }

    public String getDateFormat() {
        return dateFormat;
    }

    public void setDateFormat(String dateFormat) {
        this.dateFormat = dateFormat;
    }
}

 

MyByteArrayMorpher.java

package test.json_lib;

import net.sf.ezmorph.MorphException;
import net.sf.ezmorph.array.AbstractArrayMorpher;
import net.sf.ezmorph.array.ByteArrayMorpher;

import org.apache.commons.codec.binary.Base64;
import org.apache.commons.lang.builder.EqualsBuilder;

public class MyByteArrayMorpher extends AbstractArrayMorpher {
    private ByteArrayMorpher _morpher = new ByteArrayMorpher();

    public MyByteArrayMorpher() {
        super(false);
    }

    public MyByteArrayMorpher(byte defaultValue) {
        super(true);
        _morpher = new ByteArrayMorpher(defaultValue);
    }

    public boolean equals(Object obj) {
        if (this == obj) {
            return true;
        }
        if (obj == null) {
            return false;
        }

        if (!(obj instanceof MyByteArrayMorpher)) {
            return false;
        }

        MyByteArrayMorpher other = (MyByteArrayMorpher) obj;
        EqualsBuilder builder = new EqualsBuilder();
        if (isUseDefault() && other.isUseDefault()) {
            builder.append(getDefaultValue(), other.getDefaultValue());
            return builder.isEquals();
        } else if (!isUseDefault() && !other.isUseDefault()) {
            return builder.isEquals();
        } else {
            return false;
        }
    }

    public byte getDefaultValue() {
        return _morpher.getDefaultValue();
    }

    public int hashCode() {
        return _morpher.hashCode();
    }

    public boolean supports(Class clazz) {
        return String.class.equals(clazz) || clazz.isArray();
    }

    @Override
    public Object morph(Object array) {
        Object byteArray = null;
        try {
            byteArray = _morpher.morph(array);
        } catch (MorphException e) {
            if (array instanceof String) {
                byteArray = Base64.decodeBase64((String) array);

            } else {
                throw new MorphException("argument is not an array or "
                        + "invalid Base64 string : " + array.getClass());
            }
        }
        return byteArray;
    }

    @Override
    public Class morphsTo() {
        return _morpher.morphsTo();
    }
}

ByteArrayJsonValueProcessor.java

package test.json_lib;

import org.apache.commons.codec.binary.Base64;

import net.sf.json.JsonConfig;
import net.sf.json.processors.JsonValueProcessor;

/**
 * [Java -> JSON] byte[] -> Base64 String

 *
 * byte[]一般用来存储二进制的数据格式,如DB的BLob字段等,所以两个服务器间用JSON来
 * 数据交换的时候,最好就是用Base64等通用转码格式转义成可识别的字符串(Xstream就是
 * 这样做的),可是JSON-lib里却是以整形数组([101,200,35])这样的格式保存的,所以比
 * Base64编码后的数据(用来表示数据的字符数$)要长,且不方便处理。
 *
 * @author btpka3
 */

public class ByteArrayJsonValueProcessor implements JsonValueProcessor {

    @Override
    public Object processArrayValue(Object value, JsonConfig jsonConfig) {
        // FIXME 不知道这个做什么用的,何时被调用

        return null;
    }

    @Override
    public Object processObjectValue(String key, Object value,
            JsonConfig jsonConfig) {
        // 用Apache Commons Codec 来进行标准的,未扩展的Base64转码

        //(当然有参数可以指定是否启用扩展,详情请用Google百度一下 "Base64")

        return Base64.encodeBase64String((byte[]) value);
    }

}


阅读(1859) | 评论(1) | 转发(0) |
给主人留下些什么吧!~~

chinaunix网友2010-09-20 19:06:31

写这么多废话,干什么。。