Jackson Json 快速入门

Jackson Json 快速入门

Java对象转换为Json

总体来说,从Java到Json,Jakson提供了三种方式:Java对象、JsonNode Tree、Json流。因为是要快速入门,所以下文中主要使用第一种方式,也就是通过ObjectMapper实现从Java到Json以及从Json到Java的功能。详细教程传送门;基本上是使用ObjectMapper的write型API。

POJO的转换

创建User类:

将其转换为字符串并输出到控制台,结果如下:

public class User {
	protected String name;
	protected int id;
	public User(){
	}

	public String getName() {
		return name;
	}

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

	public int getId() {
		return id;
	}

	public void setId(int id) {
		this.id = id;
	}

	@Override
	public String toString() {
		return "User{" +
				"name='" + name + '\'' +
				", id=" + id +
				'}';
	}
}

public static void main(String[] args){
    	User user=new User();
		user.setId(666);
		user.setName("落花流水存心阁");
		String userJson=writer.writeValueAsString(user);
		System.out.println(userJson);
}

//输出
{
  "name" : "落花流水存心阁",
  "id" : 666
}

多态条件下的转换

创建User类的子类VIP以及SuperVIP类:

public class SuperVIP extends User {
	private String[] privileges;

	public String[] getPrivileges() {
		return privileges;
	}

	public void setPrivileges(String[] privileges) {
		this.privileges = privileges;
	}

	public SuperVIP(String[] privileges) {
		this.privileges = privileges;
	}

	public SuperVIP() {
	}

	@Override
	public String toString() {
		return "SuperVIP{" +
				"privileges=" + Arrays.toString(privileges) +
				", name='" + name + '\'' +
				", id=" + id +
				'}';
	}
}
public class VIP extends User{
	private String privilege;

	public VIP() {
	}

	public VIP(String privilege) {
		this.privilege = privilege;
	}

	public String getPrivilege() {
		return privilege;
	}

	public void setPrivilege(String privilege) {
		this.privilege = privilege;
	}

	@Override
	public String toString() {
		return "VIP{" +
				"privilege='" + privilege + '\'' +
				", name='" + name + '\'' +
				", id=" + id +
				'}';
	}
}
public static void main(String[] args){
String basicPrivilege="超大容量";
		VIP vip=new VIP(basicPrivilege);
		vip.setId(777);
		vip.setName("落花流水存心阁");
		String vipJson=writer.writeValueAsString(vip);
		System.out.println(vipJson);

//		writer.writeValue(System.out,vip);
//		System.out.println("我不会出现");

		String superPrivilege="高速下载";
		String[] privileges=new String[2];
		privileges[0]=basicPrivilege;
		privileges[1]=superPrivilege;
		SuperVIP superVIP=new SuperVIP(privileges);
		superVIP.setId(888);
		superVIP.setName("落花流水存心阁");
		String superVipJson=writer.writeValueAsString(superVIP);
		System.out.println(superVipJson);

		String privilegeJson=writer.writeValueAsString(privileges);
		System.out.println(privilegeJson);
}

//输出
{
  "name" : "落花流水存心阁",
  "id" : 777,
  "privilege" : "超大容量"
}
{
  "name" : "落花流水存心阁",
  "id" : 888,
  "privileges" : [ "超大容量", "高速下载" ]
}

集合转换

创建User的List,然后将其转换为Json字符串,输出到控制台:

public static void main(String[] args){
    List<User> users=new ArrayList<>(3);
	users.add(user);
	users.add(vip);
	users.add(superVIP);
    System.out.println(mapper.writeValueAsString(users));
}
//输出
[{"name":"落花流水存心阁","id":666},{"name":"落花流水存心阁","id":777,"privilege":"超大容量"},{"name":"落花流水存心阁","id":888,"privileges":["超大容量","高速下载"]}]

会发现这里虽然结果ok,但是这样的Json是无法反序列化的,因为使用Jackson并不知道该Json字符串同类的关联,也就无法创建对象了。

为User类添加关于类型的注释并在序列化时提供相关信息:

@JsonTypeInfo(use =JsonTypeInfo.Id.CLASS, property = "@class")
@JsonSubTypes({ @Type(value = VIP.class, name = "vip"), @Type(value = SuperVIP.class, name = "supervip") })
public class User{}

public static void main(String[] args){
	List<User> users=new ArrayList<>(3);
	users.add(user);
	users.add(vip);
	users.add(superVIP);
	String usersJson=mapper.writerFor(new TypeReference<List<User>>() {
}).writeValueAsString(users);
	System.out.println(usersJson);
}

输出:

[{"@class":"com.xiaomo.util.json.example.fast_understand.User","name":"落花流水存心阁","id":666},{"@class":"com.xiaomo.util.json.example.fast_understand.VIP","name":"落花流水存心阁","id":777,"privilege":"超大容量"},{"@class":"com.xiaomo.util.json.example.fast_understand.SuperVIP","name":"落花流水存心阁","id":888,"privileges":["超大容量","高速下载"]}]

因为泛型在编译的时候擦除了类信息,所以这里使用了TypeReference这一在运行时标记目标List类别的对象;

Json转换为Java对象

我们将上一节的输出,作为这一节的输入~ 相应的,我们使用ObjectMapperd对象的read系API。

转换为POJO

操作比较常规,传入相对应的class对象即可:

String userJson="{\n" +
		"  \"@class\" : \"com.xiaomo.util.json.example.fast_understand.User\",\n" +
		"  \"name\" : \"落花流水存心阁\",\n" +
		"  \"id\" : 666\n" +
		"}";
//转换为POJO
User user=objectMapper.readValue(userJson,User.class);
System.out.println("普通用户的用户名:"+user.getName());

多态条件的转换

String vipJson="{\n" +
		"  \"@class\" : \"com.xiaomo.util.json.example.fast_understand.VIP\",\n" +
		"  \"name\" : \"落花流水存心阁\",\n" +
		"  \"id\" : 777,\n" +
		"  \"privilege\" : \"超大容量\"\n" +
		"}";
String superVipJson="{\n" +
		"  \"@class\" : \"com.xiaomo.util.json.example.fast_understand.SuperVIP\",\n" +
		"  \"name\" : \"落花流水存心阁\",\n" +
		"  \"id\" : 888,\n" +
		"  \"privileges\" : [ \"超大容量\", \"高速下载\" ]\n" +
		"}";

//多态条件下的转换
User vip=objectMapper.readValue(vipJson,User.class);
System.out.println("VIP的用户名:"+vip.getName());
System.out.println("通过父类反序列化的VIP是不是VIP:"+(vip instanceof VIP));
SuperVIP superVIP=objectMapper.readValue(superVipJson,SuperVIP.class);
System.out.println("SuperVIP的权限:");
for(String s:superVIP.getPrivileges()){
	System.out.println(s);
}

这里,我们使用的是含类信息的Json字符串,此时可以传入父类的class。因为Json字符串里已经包含了Jackson所需要的创建对象的信息。

如果使用不含类信息的Json字符串,则应该使用对应类的class对象。

集合转换

String userListJson="[{\"@class\":\"com.xiaomo.util.json.example.fast_understand.User\",\"name\":\"落花流水存心阁\",\"id\":666},{\"@class\":\"com.xiaomo.util.json.example.fast_understand.VIP\",\"name\":\"落花流水存心阁\",\"id\":777,\"privilege\":\"超大容量\"},{\"@class\":\"com.xiaomo.util.json.example.fast_understand.SuperVIP\",\"name\":\"落花流水存心阁\",\"id\":888,\"privileges\":[\"超大容量\",\"高速下载\"]}]\n";

//有类信息的集合转换
List<User> userList=objectMapper.readValue(userListJson,new TypeReference<List<User>>(){});
System.out.println("集合转换结果");
for(User u:userList){
	System.out.println(u);
}

集合转换时,需要注意的是使用含有类信息的Json字符串,同时与序列化一样,需要传入标志集合泛型类别的TypeReference;

Jackson Json 注解

注:以下具体代码示例见 Ignore fields in JSON using Jackson

  1. 类级别的忽略字段注解:@JsonIgnoreProperties
  2. 字段级别的忽略注解:@JsonIgnore

注:以下具体代码示例见 Json annotations and dynamic beans

  1. 关联Java字段和Json属性的注解:@JsonProperty
  2. 指定反序列化时所使用的构造函数的注解:@JsonCreator
  3. 指定处理无法和Java字段对应的Json属性的getter与setter方法,多用于反序列化时处理多余或者不想处理的Json属性:@JsonAnyGetter和@JsonAnySetter

注:以下具体代码示例见 Jackson List serializationJson Polymorphism

  1. 在Json字符串中存储类信息的注解:@JsonTypeInfo,使用于父类,指定类信息的属性名以及对应属性值的值。@JsonSubTypes,使用于父类,指定子类;

需要注意的是:使用ObjectMapper对象输出Json结果时,可以指定输出流,但是输出后Jackson(JsonFactory)将尝试关闭该流;所以如何指定System.out为输出流,则以后out流关闭,控制台再也看不到结果。以下为源代码中writeValue的注释:

Note: method does not close the underlying stream explicitly
here; however, {@link JsonFactory} this mapper uses may choose
to close the stream depending on its settings (by default,
it will try to close it when {@link JsonGenerator} we construct
is closed).

项目源码免费获取 个人博客,百度网盘地址+提取码,文件无密~

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值