Json已经成为当前服务器与 WEB 应用之间数据传输的公认标准。目前java json解析工具有阿里的fastjson,google的GSON,以及SpringMVC 默认的解析工具Jackson。SpringBoot默认自带是jackson,晚上有很多json转换速率的比对,如jackson,阿里的fastjson等,不过jackson足够使用了.
使用jackson
1.pom.xml文件中引用依赖包.
1
2
3
4
5
6<dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>2.9.5</version> </dependency>
一般情况下,SpringBoot开发web应用会引用spring-boot-starter-web依赖包,而这个依赖包会默认引用
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16<dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-annotations</artifactId> <version>2.8.0</version> </dependency> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-core</artifactId> <version>2.8.7</version> </dependency> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>2.8.7</version> </dependency>
Jackson 主要有三部分组成,除了三个模块之间存在依赖,不依赖任何外部 jar 包。三个模块的 作用及 artifactId
如下:
jackson-core
: 核心包jackson-annotations
: 注解包jackson-databind
: 数据绑定(依赖core
和annotations
)
而 jackson-databind 依赖另外两个,所以单独引用时,只引用 jackson-databind 就可以使用了.
2.使用
实体类:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33//JSON序列化和反序列化使用的User类 import java.util.Date; public class User { private String name; private Integer age; private Date birthday; 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; } }
1.序列化
1
2
3
4
5
6
7ObjectMapper是JSON操作的核心,Jackson的所有JSON操作都是在ObjectMapper中实现。 ObjectMapper有多个JSON序列化的方法,可以把JSON字符串保存File、OutputStream等不同的介质中。 writeValue(File arg0, Object arg1)把arg1转成json序列,并保存到arg0文件中。 writeValue(OutputStream arg0, Object arg1)把arg1转成json序列,并保存到arg0输出流中。 writeValueAsBytes(Object arg0)把arg0转成json序列,并把结果输出成字节数组。 writeValueAsString(Object arg0)把arg0转成json序列,并把结果输出成字符串。
使用的示例:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26import java.io.IOException; import java.text.ParseException; import java.text.SimpleDateFormat; import com.fasterxml.jackson.databind.ObjectMapper; public class JacksonDemo { public static void main(String[] args) throws ParseException, IOException { User user = new User(); user.setName("小民"); user.setEmail("xiaomin@sina.com"); user.setAge(20); SimpleDateFormat dateformat = new SimpleDateFormat("yyyy-MM-dd"); user.setBirthday(dateformat.parse("1996-10-01")); ObjectMapper mapper = new ObjectMapper(); //User类转JSON //输出结果:{"name":"小民","age":20,"birthday":844099200000,"email":"xiaomin@sina.com"} String json = mapper.writeValueAsString(user); System.out.println(json); //Java集合转JSON //输出结果:[{"name":"小民","age":20,"birthday":844099200000,"email":"xiaomin@sina.com"}] List<User> users = new ArrayList<User>(); users.add(user); String jsonlist = mapper.writeValueAsString(users); System.out.println(jsonlist); } }
2.反序列化
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15import java.io.IOException; import java.text.ParseException; import com.fasterxml.jackson.databind.ObjectMapper; public class JacksonDemo { public static void main(String[] args) throws ParseException, IOException { String json = "{"name":"小民","age":20,"birthday":844099200000,"email":"xiaomin@sina.com"}"; /** * ObjectMapper支持从byte[]、File、InputStream、字符串等数据的JSON反序列化。 */ ObjectMapper mapper = new ObjectMapper(); User user = mapper.readValue(json, User.class); System.out.println(user); } }
3.JSON注解
1
2
3
4
5Jackson提供了一系列注解,方便对JSON序列化和反序列化进行控制,下面介绍一些常用的注解。 @JsonIgnore 此注解用于属性上,作用是进行JSON操作时忽略该属性。 @JsonFormat 此注解用于属性上,作用是把Date类型直接转化为想要的格式,如@JsonFormat(pattern = "yyyy-MM-dd HH-mm-ss")。 @JsonProperty 此注解用于属性上,作用是把该属性的名称序列化为另外一个名称,如把trueName属性序列化为name,@JsonProperty("name")。
注:关于日期格式的格式化,jackson提供了两种方法:
1.单独格式化
在对象属性上,或者在属性的 getter 方法上,如下代码所示:
增加到属性上:
1
2
3
4/**更新时间 用户可以点击更新,保存最新更新的时间。**/ @JsonFormat(pattern="yyyy-MM-dd HH:mm:ss") private Date updateTime;
增加到 getter 方法上:
1
2
3
4
5@JsonFormat(pattern="yyyy-MM-dd HH:mm:ss") public Date getUpdateTime() { return updateTime; }
以上结果输出都是一样的。这个没有什么好说明的。具体输出格式,自己调整 pattern 。
@JsonFormat 相差8小时问题
上面直接这么使用,在我们中国来讲和我们的北京时间,会相差8个小时,因为我们是东八区(北京时间)。
所以我们在格式化的时候要指定时区(timezone ),代码如下:
1
2
3
4/**更新时间 用户可以点击更新,保存最新更新的时间。**/ @JsonFormat(pattern="yyyy-MM-dd HH:mm:ss",timezone="GMT+8") private Date updateTime;
也就是增加一个属性,timezone="GMT+8" 即可,getter 方法我就不写了,一样的。
2.统一格式化
数据库里面查出来的时间是时间错格式,前端需要处理才能展示相应的格式,自己一个个转的话太麻烦,所以可以在apllication.properties加入下面配置就可以
注意:
前置条件:
image
使用resultMap作为结果返回集
1
2
3
4#时间戳统一转换 spring.jackson.date-format=yyyy-MM-dd HH:mm:ss spring.jackson.time-zone=GMT+8
其中time-zone是时区偏移设置,如果不指定的话时间和北京时间会差八个小时。
上述的方法都是针对出参,还有一个日期格式化,不过这个是针对传入的参数,放在Date类型属性或setter方法上,两者可以同时使用,
1
2
3
4@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm") @JsonFormat(pattern="yyyy-MM-dd HH:mm:ss",timezone="GMT+8") private Date updateTime;
标签的使用如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57import java.util.Date; import com.fasterxml.jackson.annotation.*; public class User { private String name; //不JSON序列化年龄属性 @JsonIgnore private Integer age; //格式化日期属性 @JsonFormat(pattern = "yyyy年MM月dd日") 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; } } import java.io.IOException; import java.text.ParseException; import java.text.SimpleDateFormat; import com.fasterxml.jackson.databind.ObjectMapper; public class JacksonDemo { public static void main(String[] args) throws ParseException, IOException { User user = new User(); user.setName("小民"); user.setEmail("xiaomin@sina.com"); user.setAge(20); SimpleDateFormat dateformat = new SimpleDateFormat("yyyy-MM-dd"); user.setBirthday(dateformat.parse("1996-10-01")); ObjectMapper mapper = new ObjectMapper(); String json = mapper.writeValueAsString(user); System.out.println(json); //输出结果:{"name":"小民","birthday":"1996年09月30日","mail":"xiaomin@sina.com"} } }
4.readTree
在jackson中, 有些场景下,在实现一些基础服务和拦截器的时候,我们可能需要在不知道JSON字符串所属对象类型的情况下,对JSON字符串中的某些属性进行遍历和修改,比如,设置或查询一些报文头字段。
在jackson中,使用最多的JsonNode抽象类并没有提供修改节点值的方法,而是在ObjectNode节点中提供修改接口,这个节点在官方的说明中,一般用于创建新的节点。
在ObjectNode节点中提供修改接口(put),JsonNode提供查询的接口;
1
2
3
4
5JsonNode rootNode = mapper.readTree(jsonStr);//jsonStr是一个json字符串 JsonNode targetNode = null; targetNode = rootNode.findValue("rpcMsgId"); // 查找第一级的rpcMsgId属性,如果属性不存在,则返回null,属性值如果为明确的null,返回NullNode,否则返回正常的JsonNode // 注:JsonNode还提供了find/path/get等获取节点的方法,但是这三种方法都不能明确的区分节点不存在、为明确的null。所以,应该使用findValue方法。
如果只是纯粹的遍历和类似JsonTree的构造,网上各种文章一堆,主要是对原json中属性的修改。可通过如下方式进行修改:
1
2
3
4
5
6
7
8((ObjectNode)targetNode).put("rpcMsgId","abcdefg1234567890"); // 通过强制转换为ObjectNode,就可以对当前节点进行修改,其他的XXXNode均没有提供相关的API接口 String modifiedJsonStr = mapper.writeValueAsString(rootNode); // 最后重新生成json字符串,这跟dom4j修改xml一样,只能重新生成,内置不支持直接修改原文件 //完整的代码 JsonNode node = mapper.readTree(jsonStr); JsonNode node1 = node.findValue("spiderPacketHead"); ObjectNode node2 = (ObjectNode) node1; node2.put("rpcMsgId", "abc");
原文:https://www.cnblogs.com/zhjh256/p/6049663.html
示例:http://lijingshou.iteye.com/blog/2003112
jackson中各种属性总结:https://www.cnblogs.com/jian-xiao/p/6009435.html?utm_source=itdadao&utm_medium=referral
jackson中的使用方式:https://blog.csdn.net/java_huashan/article/details/46375857
在这里贴上我自己更改后的工具类JsonUtils代码:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179package com.luozhen.util.jackson; import java.util.List; import java.util.Map; import com.fasterxml.jackson.core.JsonParser.Feature; import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.databind.DeserializationFeature; import com.fasterxml.jackson.databind.JavaType; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.SerializationFeature; /** * <b>Description:</b> json转换工具类 <br> * * @author luozhen * @version 1.0 * @Note <b>ProjectName:</b> MySpringBoot <br> * <b>PackageName:</b> com.luozhen.util <br> * <b>ClassName:</b> JacksonActivity <br> * <b>Date:</b> 2018年5月24日 下午12:50:59 */ public class JsonUtils { /** * ObjectMapper是JSON操作的核心,Jackson的所有JSON操作都是在ObjectMapper中实现。 * ObjectMapper有多个JSON序列化的方法,可以把JSON字符串保存File、OutputStream等不同的介质中。 * writeValue(File arg0, Object arg1)把arg1转成json序列,并保存到arg0文件中。 * writeValue(OutputStream arg0, Object arg1)把arg1转成json序列,并保存到arg0输出流中。 * writeValueAsBytes(Object arg0)把arg0转成json序列,并把结果输出成字节数组。 * writeValueAsString(Object arg0)把arg0转成json序列,并把结果输出成字符串。 */ /** * 初始化变量 */ private static ObjectMapper mapper = new ObjectMapper(); static { // 解决实体未包含字段反序列化时抛出异常 mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); // 对于空的对象转json的时候不抛出错误 mapper.disable(SerializationFeature.FAIL_ON_EMPTY_BEANS); // 允许属性名称没有引号 mapper.configure(Feature.ALLOW_UNQUOTED_FIELD_NAMES, true); // 允许单引号 mapper.configure(Feature.ALLOW_SINGLE_QUOTES, true); } /** * * <b>Description:</b> 将一个object转换为json, 可以使一个java对象,也可以使集合<br> * <b>Title:</b> ObjectToJson<br> * * @param obj * - 传入的数据 * @return * @Note <b>Author:</b> luozhen <br> * <b>Date:</b> 2018年5月24日 下午1:26:53 <br> * <b>Version:</b> 1.0 */ public static String objectToJson(Object obj) { String json = null; try { json = mapper.writeValueAsString(obj); } catch (Exception e) { e.printStackTrace(); } return json; } /** * ObjectMapper支持从byte[]、File、InputStream、字符串等数据的JSON反序列化。 */ /** * * <b>Description:</b> 将json结果集转化为对象<br> * <b>Title:</b> jsonToClass<br> * * @param json * - json数据 * @param beanType * - 转换的实体类型 * @return * @Note <b>Author:</b> luozhen <br> * <b>Date:</b> 2018年5月24日 下午3:26:18 <br> * <b>Version:</b> 1.0 */ public static <T> T jsonToClass(String json, Class<T> beanType) { T t = null; try { t = mapper.readValue(json, beanType); } catch (Exception e) { e.printStackTrace(); } return t; } /** * * <b>Description:</b> 将json数据转换成Map<br> * <b>Title:</b> jsonToMap<br> * * @param json * - 转换的数据 * @return * @Note <b>Author:</b> luozhen <br> * <b>Date:</b> 2018年5月24日 下午3:29:37 <br> * <b>Version:</b> 1.0 */ public static Map<String, Object> jsonToMap(String json) { Map<String, Object> map = null; try { map = mapper.readValue(json, new TypeReference<Map<String, Object>>() {}); } catch (Exception e) { e.printStackTrace(); } return map; } /** * * <b>Description:</b> 将json数据转换成list <br> * <b>Title:</b> jsonToList<br> * * @param json * - 转换的数据 * @return * @Note <b>Author:</b> luozhen <br> * <b>Date:</b> 2018年5月24日 下午3:28:35 <br> * <b>Version:</b> 1.0 */ public static <T> List<T> jsonToList(String json, Class<T> beanType) { List<T> list = null; try { JavaType javaType = mapper.getTypeFactory().constructParametricType(List.class, beanType); list = mapper.readValue(json, javaType); } catch (Exception e) { e.printStackTrace(); } return list; } /** * * <b>Description:</b> 获取json对象数据的属性<br> * <b>Title:</b> findValue<br> * * @param resData * - 请求的数据 * @param resPro * - 请求的属性 * @return 返回String类型数据 * @Note <b>Author:</b> luozhen <br> * <b>Date:</b> 2018年5月31日 上午10:00:09 <br> * <b>Version:</b> 1.0 */ public static String findValue(String resData, String resPro) { String result = null; try { JsonNode node = mapper.readTree(resData); JsonNode resProNode = node.get(resPro); result = JsonUtils.objectToJson(resProNode); } catch (Exception e) { e.printStackTrace(); } return result; } }
=================== 实际使用案例 ==========================
案例1
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31import com.fasterxml.jackson.core.JsonParser; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import java.io.IOException; import java.io.UnsupportedEncodingException; import java.util.Properties; @RequestMapping("/mq") @RestController public class MqController { @GetMapping("/test") public String test() throws IOException { String jsonstr = "{"msg":{"head":{"version":"1.0","bizcode":"1006","senddate":"20140827","sendtime":"110325","seqid":"1"},"body":{"datalist":"wahaha","rstcode":"000000","rstmsg":"成功"}}}"; ObjectMapper mapper = new ObjectMapper(); //允许出现特殊字符和转义符 mapper.configure(JsonParser.Feature.ALLOW_UNQUOTED_CONTROL_CHARS, true) ; JsonNode root = mapper.readTree(jsonstr); //path与get作用相同,但是当找不到该节点的时候,返回missing node而不是Null. JsonNode msg = root.path("msg"); JsonNode head = msg.path("head"); JsonNode body = msg.path("body"); String bizcode = head.path("bizcode").asText(); String datalist = body.path("datalist").asText(); System.err.println(bizcode); System.err.println(datalist); System.err.println(root.path("msg").path("body").path("datalist").asText()); return ""; } }
1
2
3
4
5
6
7@GetMapping("/test") public String test(){ String jsonstr = "{"rstcode":"000000","rstmsg":"成功"}"; String svalue = JsonUtils.findValue(jsonstr, "rstcode"); return svalue; }
返回: 000000
1
2
3
4
5
6
7
8
9
10
11
12@GetMapping("/test") public String test(){ String jsonstr = "{"msg":{"head":{"version":"1.0","bizcode":"1006","senddate":"20140827","sendtime":"110325","seqid":"1"},"body":{"datalist":"wahaha","rstcode":"000000","rstmsg":"成功"}}}"; String smsg = JsonUtils.findValue(jsonstr, "msg"); System.out.println("smsg: " + smsg); String shead = JsonUtils.findValue(smsg, "head"); System.out.println("shead: " + shead); String svalue = JsonUtils.findValue(shead, "version"); System.out.println("svalue: " + svalue); return svalue; }
输出:
1
2
3smsg: {"head":{"version":"1.0","bizcode":"1006","senddate":"20140827","sendtime":"110325","seqid":"1"},"body":{"datalist":"wahaha","rstcode":"000000","rstmsg":"成功"}} shead: {"version":"1.0","bizcode":"1006","senddate":"20140827","sendtime":"110325","seqid":"1"} svalue: "1.0"
返回:"1.0"
使用案例2
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25try { ObjectMapper mapper = new ObjectMapper(); // 允许出现特殊字符和转义符 mapper.configure(Feature.ALLOW_UNQUOTED_CONTROL_CHARS, true); // String jsonstr = // "{"msg":{"head":{"version":"1.0","bizcode":"1006","senddate":"20140827","sendtime":"110325","seqid":"1"},"body":{"datalist":"wahaha","rstcode":"000000","rstmsg":"成功"}}}"; ObjectNode root = mapper.createObjectNode(); ObjectNode msg = mapper.createObjectNode(); ObjectNode head = mapper.createObjectNode(); head.put("version", "1.0"); head.put("bizcode", "1006"); head.put("senddate", "20140827"); head.put("sendtime", "110325"); head.put("seqid", "1"); ObjectNode body = mapper.createObjectNode(); body.put("datalist", "wahaha"); body.put("rstcode", "000000"); body.put("rstmsg", "成功"); msg.put("head", head); msg.put("body", body); root.put("msg", msg); System.out.println(mapper.writeValueAsString(root)); } catch (Exception e) { e.printStackTrace(); }
最后
以上就是包容网络最近收集整理的关于SpringBoot : 使用jackson操作json数据的全部内容,更多相关SpringBoot内容请搜索靠谱客的其他文章。
发表评论 取消回复