FastJson-JSONField

前端之家收集整理的这篇文章主要介绍了FastJson-JSONField前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

学习摘要
https://github.com/alibaba/fastjson
http://www.jb51.cc/article/p-qkflvyfm-bkb.html

Maven依赖
仓库地址
http://repo1.maven.org/maven2/com/alibaba/fastjson/
选择版本、建议使用最新版本

<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>fastjson</artifactId>
    <version>1.1.37</version>
</dependency>

最常用的工具类和两个方法

JSON 序列化对象为json文本,包括普遍Javabean,Map,List,嵌套对象
JSON.toJSONString(Object object) 序列化对象
JSON.toJSONString(Object object,boolean prettyFormat),序列化对象,并以良好的格式呈现

例如

@Test
    public void testJSonBean() throws Exception {
        Model m = new Model(); //普通Java VO
        m.setName("xiele");
        m.setDate(new Date());
        m.setIg(1);
        m.setLg(1000L);
        System.out.println(JSON.toJSONString(m));
    }
    输出的文本:
    {"name":"xiele","date":1437487740477,"lg":1000,"ig":1}

    如果带上prettyFormat为true
    JSON.toJSONString(m,true)
    {
    "name":"xiele","date":1437487867654,"ig":1
}

配置一些辅助的序列化功能(SerialFeature)

public static final String toJSONString(Object object,SerializerFeature... features)

参考源码
public enum SerializerFeature {
    QuoteFieldNames,//序列化输出含引号的字段,默认
    UseSingleQuotes,//使用单引号而不是双引号序列化
    WriteMapNullValue,//空值是否输出,默认不输出null
    WriteEnumUsingToString,Enum输出枚举值
    UseISO8601DateFormat,//Date使用ISO8601格式输出日期
    WriteNullListAsEmpty,//list字段如果为null,输出为[],而不是null,默认不输出null
    WriteNullStringAsEmpty,//字符串类型为null,输出""(空串)
    WriteNullNumberAsZero,//数值字段如果为null,输出为0,而不是null
    WriteNullBooleanAsFalse,//Boolean字段如果为null,输出为false,而不是null
    SkipTransientField,//忽略@Transient注解过的字段
    SortField //按字段名称排序后输出
  }

用法

JSON.toJSONString(m,SerializerFeature.UseISO8601DateFormat)

定制序列化
在做网关开发时,为移动端提供的很多数据都需要简化处理,比如VO的key需要定制输出,可使用FastJson提供的@JSONField注解。
@JSONField有两种方式
1.在字段上
2.在属性getter方法
例如

public class VO {
      @JSONField(name="ID")
      private int id;
 }
 public class VO {
      private int id;

      @JSONField(name="ID")
      public int getId() { return id;}
 }

但是
在使用FastJson的@JSONField做定制时,偶尔不生效,也包含了继承的情况,有时候会出现结果不一致。
官方给出的解释是版本过低,升级到fastjson-1.1.42及其以后即可。
https://github.com/alibaba/fastjson/issues/176

需求是变化的,尽管有时候需要定制,有的终端需要定制,但是又需要复用发布出去的VO,但是需要解除由@JSONField定制带来的困扰。
解决办法,是通过反射找到VO的字段Field,然后得到其注解,并获取到注解的值,最后存入Map中,使得定制的名称和原来的字段名形成Key-Value绑定。再通过FastJson提供的NameFilter名称过滤器来过滤序列的名称

获取注解的值

@Test
    public void testGetFieldAnno() throws Exception {
        Map<String,String> map = Maps.newHashMap();
        Model m = new Model();
        Field[] fs =  m.getClass().getDeclaredFields();
        for (Field f : fs) {
            if (f.isAnnotationPresent(JSONField.class)) {
                JSONField jf = f.getAnnotation(JSONField.class);
                map.put(jf.name(),f.getName());
            }
        }
        System.out.println(JSON.toJSONString(map,true));
    }

过滤名称

@Test
    public void testMapJSonField()  {
        Model m = new Model();
        m.setName("xiele");
        m.setDate(new Date());
        m.setIg(1);
        m.setLg(1000L);

        final  Map<String,String> map = Maps.newHashMap();
        Field[] fs =  m.getClass().getDeclaredFields();
        for (Field f : fs) {
            if (f.isAnnotationPresent(JSONField.class)) {
                JSONField jf = f.getAnnotation(JSONField.class);
                map.put(jf.name(),f.getName());
            }
        }

        System.out.println(JSON.toJSONString(map,true));

        NameFilter filter = new NameFilter() {
            @Override
            public String process(Object source,String name,Object value) {
                // source是当前对象, name是key, value实在值
                return map.get(name);
            }
        };

        JSONSerializer jsonSerializer = new JSONSerializer();
        jsonSerializer.getNameFilters().add(filter); // 通过增加一个过滤器,为name和值进行过滤
        jsonSerializer.write(m);
        System.out.println(jsonSerializer.toString());
    }

除此之外,FastJson还提供了属性过滤器PropertyFilter、值过滤器ValueFilter,用法类似。

原文链接:https://www.f2er.com/json/289708.html

猜你在找的Json相关文章