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;
}