JSON解析和序列化过程中注解应用,null值过滤

Jackson提供了一系列注解,方便对JSON序列化和反序列化进行控制,下面介绍一些常用的注解。

@JsonIgnore 此注解用于属性上,作用是进行JSON操作时忽略该属性。

@JsonFormat 此注解用于属性上,作用是把Date类型直接转化为想要的格式,

@JsonProperty 此注解用于属性上,作用是把该属性的名称序列化为另外一个名称,

@JsonSerialize(include=JsonSerialize.Inclusion.NON_NULL) 实体类前,如果属性为NULL则不参与序列化

@JsonInclude(Include.NON_NULL) ,该标记放在属性上,如果该属性为NULL则不参与序列化 ;如果放在类上边,那对这个类的全部属性起作用

具体取值有:
Include.Include.ALWAYS 默认 
Include.NON_DEFAULT 属性为默认值不序列化 
Include.NON_EMPTY 属性为 空(“”) 或者为 NULL 都不序列化 
Include.NON_NULL 属性为NULL 不序列化

Include.NON_NULL还可以在代码中:

ObjectMapper mapper = new ObjectMapper();

mapper.setSerializationInclusion(Include.NON_NULL); 

User user = new User(1,"",null); 

String outJson = mapper.writeValueAsString(user); 

System.out.println(outJson);

通过该方法对mapper对象进行设置,所有序列化的对象都将按改规则进行系列化 。

注意:只对VO起作用;对Map List不起作用

当使用com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter转换返回数据为json时,会省略掉为空为null的属性值。

在springmvc中的配置为:

解决办法在spingmvc.xml配置json转换器时加上对空和null的处理,配置如下:

QuotoFieldNames表示返回的json数据的key值加上双引号。

<mvc:annotation-driven>
        <mvc:message-converters>
            <bean
                class="com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter">
                <description>JSON转换器</description>
                <property name="supportedMediaTypes">
                    <list>
                        <value>application/json;charset=UTF-8</value>
                        <value>text/html;charset=UTF-8</value>
                    </list>
                </property>
                <property name="features">
                    <array>
                        <value>QuoteFieldNames</value>
                        <value>WriteDateUseDateFormat</value>
                        <!-- 将Collection类型字段的字段空值输出为[] -->
                        <value>WriteNullListAsEmpty</value>
                        <!-- 将字符串类型字段的空值输出为空字符串 "" -->
                        <value>WriteNullStringAsEmpty</value>
                        <!-- 将Boolean类型字段的空值输出为false -->
                        <value>WriteNullBooleanAsFalse</value>
                    </array>
                </property>
            </bean>
        </mvc:message-converters>
</mvc:annotation-driven>
package org.outman.dms.server;
import java.util.Date;  
import com.fasterxml.jackson.annotation.*;  
  
public class User {  
    private String name;  
      
    //不JSON序列化年龄属性  
    @JsonIgnore   
    private Integer age;  
      
    //格式化日期属性  
    @JsonFormat(pattern = "yyyy年MM月dd日")  /	@JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
    private Date birthday;  
      
    //序列化email属性为mail  
    @JsonProperty("mail")  
    private String email;  
      
    public String getName() {  
        return name;  
    }  
    public void setName(String name) {  
        this.name = name;  
    }  
      
    public Integer getAge() {  
        return age;  
    }  
    public void setAge(Integer age) {  
        this.age = age;  
    }  
      
    public Date getBirthday() {  
        return birthday;  
    }  
    public void setBirthday(Date birthday) {  
        this.birthday = birthday;  
    }  
      
    public String getEmail() {  
        return email;  
    }  
    public void setEmail(String email) {  
        this.email = email;  
    }
	@Override
	public String toString() {
		return "User [name=" + name + ", age=" + age + ", birthday=" + birthday
				+ ", email=" + email + "]";
	}  
}  
  
/**

 * 自定义响应结构
 */
public class JsonUtils {

    // 定义jackson对象
    private static final ObjectMapper MAPPER = new ObjectMapper();

    static{
        //转换 不包含Null值
        MAPPER.setSerializationInclusion(Include.NON_NULL);
    }
    /**
     * 将对象转换成json字符串。
     * <p>Title: pojoToJson</p>
     * <p>Description: </p>
     * @param data
     * @return
     */
    public static String objectToJson(Object data) {
        try {
            String string = MAPPER.writeValueAsString(data);
            return string;
        } catch (JsonProcessingException e) {
            e.printStackTrace();
        }
        return null;
    }
    
    /**
     * 将json结果集转化为对象
     *
     * @param jsonData json数据
     * @param clazz 对象中的object类型
     * @return
     */
    public static <T> T jsonToPojo(String jsonData, Class<T> beanType) {
        T t = null;
        try {
            t = MAPPER.readValue(jsonData, beanType);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return t;
    }
    
    /**
     * 将json数据转换成pojo对象list
     * <p>Title: jsonToList</p>
     * <p>Description: </p>
     * @param jsonData
     * @param beanType
     * @return
     */
    public static <T>List<T> jsonToList(String jsonData, Class<T> beanType) {
        JavaType javaType = MAPPER.getTypeFactory().constructParametricType(List.class, beanType);
        
        List<T> t = null;
        try {
            t = MAPPER.readValue(jsonData, javaType);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return t;
    }
    
}

fastjson工具类使用:

public static final Object parse(String text); // 把JSON文本parse为JSONObject或者JSONArray

public static final JSONObject parseObject(String text); // 把JSON文本parse成JSONObject

public static final <T> T parseObject(String text, Class<T> clazz); // 把JSON文本parse为JavaBean

public static final JSONArray parseArray(String text); // 把JSON文本parse成JSONArray

public static final <T> List<T> parseArray(String text, Class<T> clazz); //把JSON文本parse成JavaBean集合

public static final String toJSONString(Object object); // 将JavaBean序列化为JSON文本

public static final String toJSONString(Object object, boolean prettyFormat); // 将JavaBean序列化为带格式的JSON文本

public static final Object toJSON(Object javaObject); 将JavaBean转换为JSONObject或者JSONArray。

@JSONField(name=”SOMETHING”)

@JSONField(format="yyyy-MM-dd HH:mm:ss")格式化日期

@JSONType的使用

@JSONType(includes = {"name","sex"})

@JSONType(ignores ={"id", "sex"})

:注意和@JSONField不同的是,@JSONType是配置在类上的,而@JSONField是配置在字段和方法上的。

JSONObject.DEFFAULT_DATE_FORMAT="yyyy-MM-dd";//设置日期格式

JSONObject.toJSONString(Object object, SerializerFeature... features)

Fastjson的SerializerFeature序列化属性

QuoteFieldNames———-输出key时是否使用双引号,默认为true 

WriteMapNullValue——–是否输出值为null的字段,默认为false 

WriteNullNumberAsZero—-数值字段如果为null,输出为0,而非null 

WriteNullListAsEmpty—–List字段如果为null,输出为[],而非null 

WriteNullStringAsEmpty—字符类型字段如果为null,输出为”“,而非null 

WriteNullBooleanAsFalse–Boolean字段如果为null,输出为false,而非null

属性过滤:

在不需要转换的属性上添加@JSONField(serialize=false)

或自定义过滤器

1.
PropertyPreFilter filter = new PropertyPreFilter() {
        // 第三个参数,表示当前要转换json的属性
     public boolean apply(JSONSerializer serializer, Object object, String name) {
           if("group".equals(name)){
             // 当转换到group属性的属性,不进行json的转换
              return false;
            }
            return true;
     }
 };

2.
 SimplePropertyPreFilter filter = new SimplePropertyPreFilter();
    //属性排斥集合,强调某些属性不需要或者一定不能被序列化
   Set<String> excludes = filter.getExcludes().add("name");
   
   //属性包含集合,强调仅需要序列化某些属性.具体用哪一个,看实际情况.此处我用的前者

   //Set<String> includes = filter.getIncludes();

String result = JSONObject.toJSONString(object, filter);//object是Java对象

如果List集合中存入相同引用的对象
fastjson默认的情况下是进行循环检测的,去除掉死循环调用的方式
可以使用JSON.toJSONString(p,SerializerFeature.DisableCircularReferenceDetect) 去除循环检测,但是就会出现死循环的效果

多层转换

        JSONObject jsonObj = JSONObject.fromObject(goodsJson);    
        Map<String, Class> classMap = new HashMap<String, Class>();    
        classMap.put("DATA", DataInfoDto.class);    
        classMap.put("goodsInfos", GoodsInfoDto.class);      
        classMap.put("expressInfos", ExpressInfoDto.class);      
        // 将JSON转换成DeliveryInfoDto      
        DeliveryInfoDto delivery = (DeliveryInfoDto) JSONObject.toBean(jsonObj,      
        DeliveryInfoDto.class, classMap); 
 DeliveryInfoDto 中有DataInfoDto实体类,DataInfoDto中用GoodsInfoDto和ExpressInfoDto实体类

部分json转对象

import org.codehaus.jackson.annotate.JsonAutoDetect.Visibility;
import org.codehaus.jackson.annotate.JsonMethod;
import org.codehaus.jackson.map.DeserializationConfig;
import org.codehaus.jackson.map.ObjectMapper;
 
public class JacksonFoo
{
  public static void main(String[] args) throws Exception
  {
    String jsonInput = "{ \"aaa\":\"111\", \"bbb\":\"222\", \"ccc\":\"333\" }";
 
    ObjectMapper mapper = new ObjectMapper().setVisibility(JsonMethod.FIELD, Visibility.ANY);
    mapper.configure(DeserializationConfig.Feature.FAIL_ON_UNKNOWN_PROPERTIES, false);
 
    Test test = mapper.readValue(jsonInput, Test.class);
  }
}
 
class Test
{
  String aaa;
  String bbb;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值