@JSONField的一些使用基础

文章1:@JSONField的一些使用基础

1、@JSONField介绍

fastjson是阿里巴巴出品的快速解析json的一个工具,

@JSONField就是里面为数不多的注解之一.也是最为重要的注解.它的内容如下:

/*
 * Copyright 1999-2017 Alibaba Group.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.alibaba.fastjson.annotation;
 
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
 
import com.alibaba.fastjson.parser.Feature;
import com.alibaba.fastjson.serializer.SerializerFeature;
 
/**
 * @author wenshao[szujobs@hotmail.com]
 */
@Retention(RetentionPolicy.RUNTIME)
@Target({ ElementType.METHOD, ElementType.FIELD, ElementType.PARAMETER })
public @interface JSONField {
    /**
     * config encode/decode ordinal
     * @since 1.1.42
     * @return
     */
    int ordinal() default 0;
 
    String name() default "";
 
    String format() default "";
 
    boolean serialize() default true;
 
    boolean deserialize() default true;
 
    SerializerFeature[] serialzeFeatures() default {};
 
    Feature[] parseFeatures() default {};
    
    String label() default "";
    
    /**
     * @since 1.2.12
     */
    boolean jsonDirect() default false;
    
    /**
     * Serializer class to use for serializing associated value.
     * 
     * @since 1.2.16
     */
    Class<?> serializeUsing() default Void.class;
    
    /**
     * Deserializer class to use for deserializing associated value. 
     * 
     * @since 1.2.16 
     */
    Class<?> deserializeUsing() default Void.class;
 
    /**
     * @since 1.2.21
     * @return the alternative names of the field when it is deserialized
     */
    String[] alternateNames() default {};
 
    /**
     * @since 1.2.31
     */
    boolean unwrapped() default false;
}

其中里面最常用的属性是:name,format,serialize,deserialize,serializeUsing,deserializeUsing

2、fastjson编程式如何使用以及痛点

一般最常见的是这两个方法:

JSON.toJSONString(object):序列化对象,生产字符串
JSON.parse(text):反序列化对象,字符串转json

对于一般的没有什么变更的操作来说,这两个其实够用了.

但有时候情况会有些特殊,比如说:某个字段我想转成json时换个键名.或者我忽略某个字段等特殊操作,如果用编程式开发的话实在是有些烦闷的.比较坑爹.用注解的方式就很不错.

采用注解:

一个简单的demo如下:

public class JSonTest {
 
	private String id ="111";
	
	private String name ="tom ";
 
    private Date date = new Date();
 
    ...getter/setter
}
	

public static void main(String[] args) {
		System.out.println(JSON.toJSONString(new JSonTest()));
}

如果此时我想将这个类转成json,但要像"userid:111,name:tom"注意是userid,而不是id,那么这样既可.

    @JSONField(name="userid")
	private String id ="111";
	
	private String name ="tom ";

打印结果:{"date":1561545203036,"name":"tom ","userid":"111"}

加上这个注解使用name属性不止可以由类转成json,还可以解决由于json转成类时字段不一致的问题。

如果我还想将userid放到前面形成{,"userid":"111","name":"tom "}这样呢?如下即可,ordinal是用来排序的.

    @JSONField(name="userid",ordinal=0)
	private String id ="111";
	@JSONField(ordinal=1)
	private String name ="tom ";

如果我在序列化的时候想过滤掉name这个字段怎么做呢?如下:

    @JSONField(serialize = false)
	private String name ="tom ";

如果我在反序列化的时候想过滤掉呢?如下:

    @JSONField(deserialize = false)
    private String desc="abc";

如果我想让我的date时间变成特殊格式呢?

    @JSONField(format = "yyyy-MM-dd")
	private Date date = new Date();

如果我想在生成json或者解析json时获得的对象名字前面都加上"aaa"呢?这就需要具体的定制了.下面是解析和生成结合到了一起

    @JSONField(deserializeUsing = 
    NameDeserializer.class,serializeUsing=NameDeserializer.class)
    private String name ="tom ";
    class NameDeserializer implements ObjectDeserializer,ObjectSerializer{
 
		@Override
		public <T> T deserialze(DefaultJSONParser parser, Type type,
				Object fieldName) {
			String val = (String) parser.parse();
			return (T) ("aaa " + val);
		}
 
		@Override
		public int getFastMatchToken() {
			// TODO Auto-generated method stub
			return 0;
		}
 
		@Override
		public void write(JSONSerializer serializer, Object object,
				Object fieldName, Type fieldType, int features)
				throws IOException {
			
			serializer.write("aaa " + object);
		}
		
	}

原文地址:https://blog.csdn.net/dmw412724/article/details/93761161

文章2:FastJson中@JSONField注解使用

最近做项目中,使用了json格式在服务器之间进行数据传输。但是发现json格式数据不符合JAVA中的变量定义规则,并且难以理解,因此需要在后台中做二次处理,将数据处理成我们系统中定义的格式。

思路:

    1. 定义需要返回的bean,bean中定义需要返回的数据

    2. 获取到需要处理的JSON字符串

    3. 将JSON字符串转换为bean, 再将转换后的bean返回给客户端。

由于json中的key与bean中的属性不能匹配,因此在转换过程中出现了部分属性为null的情况。经过查看官方文档,发现可以使用@JSONField进行解释,但是并没有详细的使用说明。

@JSONField的作用对象:

1. Field
2. Setter 和 Getter方法

注:FastJson在进行操作时,是根据getter和setter的方法进行的,并不是依据Field进行。

Show me the code:

一、作用Field

@JSONField作用在Field时,其name不仅定义了输入key的名称,同时也定义了输出的名称
代码如下:

import com.alibaba.fastjson.JSONObject;  
import com.alibaba.fastjson.annotation.JSONField;  
  
public class Person {  
    @JSONField(name="name")  
    private String name;  
      
    @JSONField(name="age")  
    private String age;  
      
    @JSONField(name="desc")  
    private String desc;  
      
    public String getName() {  
        return name;  
    }  
    public void setName(String name) {  
        this.name = name;  
    }  
    public String getAge() {  
        return age;  
    }  
    public void setAge(String age) {  
        this.age = age;  
    }  
    public String getDesc() {  
        return desc;  
    }  
    public void setDesc(String desc) {  
        this.desc = desc;  
    }  
      
    public void setNAME(String NAME) {  //没有生效,字段上注解中的name的值为"name",则setter为setName
        this.name = NAME;  
    }  
      
    public void setAGE(String AGE) {  //没有生效,字段上注解中的name的值为"name",则setter为setAge
        this.age = AGE;  
    }  
      
    public void setDESC(String DESC) {  //没有生效,字段上注解中的name的值为"name",则setter为setDesc
        this.desc = DESC;  
    }  
      
    public String toString() {  
        return JSONObject.toJSONString(this);  
    }  
}
import org.java.json.fastjson.bean.Person;  
import org.junit.Before;  
import org.junit.Test;  
  
import com.alibaba.fastjson.JSONObject;  
  
public class PersonTest {  
  
    private Person person;  
      
    /**  
     * 初始化对象  
     */  
    @Before  
    public void setUp() {  
        person = new Person();  
        person.setName("xianglj");  
        person.setAge("20");  
        person.setDesc("只是一个测试");  
    }  
      
    @Test  
    public void test() {  
        String jsonStr = JSONObject.toJSONString(person);  
        System.out.println("bean to json:" + jsonStr);  
          
        //改变json的key为大写  
        jsonStr = jsonStr.toUpperCase();  
          
        System.out.println("需要转换的json:" + jsonStr);  
        person = JSONObject.toJavaObject(JSONObject.parseObject(jsonStr), Person.class);  
        System.out.println("json to bean:" + person.getName());  
    }  
}

输出如下:

bean to json:{"age":"20","desc":"只是一个测试","name":"xianglj"}  
需要转换的json:{"AGE":"20","DESC":"只是一个测试","NAME":"XIANGLJ"}  
json to bean:null  

从上面我们可以看出,当@JSONField作用在Fileld上时,定义了输入和输出,如果我们传输过来的json格式不符合这个格式时,则不能够正确转换。

二、作用在setter和getter方法上

顾名思义,当作用在setter方法上时,就相当于根据 name 到 json中寻找对应的值,并调用该setter对象赋值。

当作用在getter上时,在bean转换为json时,其key值为name定义的值。实例如下:

import com.alibaba.fastjson.JSONObject;  
import com.alibaba.fastjson.annotation.JSONField;  
  
public class Product {  
  
    private String productName;  
    private String desc;  
    private String price;  
      
    @JSONField(name="name")  
    public String getProductName() {  
        return productName;  
    }  
      
    @JSONField(name="NAME")  
    public void setProductName(String productName) {  
        this.productName = productName;  
    }  
      
    @JSONField(name="desc")  
    public String getDesc() {  
        return desc;  
    }  
      
    @JSONField(name="DESC")  //测试代码中对jsonStr有一个toUpperCase的操作。就会这与"DESC"匹配
    public void setDesc(String desc) {  
        this.desc = desc;  
    }  
      
    @JSONField(name="price")  
    public String getPrice() {  
        return price;  
    }  
      
    @JSONField(name="PRICE")  
    public void setPrice(String price) {  
        this.price = price;  
    }  
      
    public String toString() {  
        return JSONObject.toJSONString(this);  
    }  
      
}
import org.java.json.fastjson.bean.Product;  
import org.junit.Test;  
  
import com.alibaba.fastjson.JSONObject;  
  
/** 
 * 对fastjson中的JSON转换做一个测试 
*/  
public class JsonObjectTest {  
  
    public static void main(String[] args) {  
        Product product = new Product();  
        product.setProductName("产品");  
        product.setDesc("这是一个产品");  
        product.setPrice("22.3");  
          
        String jsonStr = JSONObject.toJSONString(product);  
        System.out.println("转换为json:" + JSONObject.toJSONString(product));  
          
        //jsonStr = jsonStr.toUpperCase();  
        System.out.println(jsonStr);  
          
        product = JSONObject.toJavaObject(JSONObject.parseObject(jsonStr), Product.class);  
        System.out.println(product.toString());  
    }  
      
    @Test  
    public void test() {  
        Product product = new Product();  
        product.setProductName("产品");  
        product.setDesc("这是一个产品");  
        product.setPrice("22.3");  
          
        String jsonStr = JSONObject.toJSONString(product);  
        System.out.println("转换为json:" + JSONObject.toJSONString(product));  
          
        jsonStr = jsonStr.toUpperCase();  
        System.out.println(jsonStr);  
          
        product = JSONObject.toJavaObject(JSONObject.parseObject(jsonStr), Product.class);  
        System.out.println(product.toString());  
    }  
}

输出如下:

转换为json:{"desc":"这是一个产品","name":"产品","price":"22.3"}  
{"DESC":"这是一个产品","NAME":"产品","PRICE":"22.3"}  
{"desc":"这是一个产品","name":"产品","price":"22.3"}  

有了这个注解之后,我们在转换bean时,就不需要在手工方式,为不能转换的属性进行赋值。即使以后返回数据反生变化,也能够快速的进行修改。不用修改大片代码。只需要修改注解name值就可以了。

原文地址:https://www.cnblogs.com/softidea/p/5681928.html

  • 9
    点赞
  • 59
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值