接收J(rèn)SON
瀏覽器傳來(lái)的參數(shù),可以是 key/value 形式的,也可以是一個(gè) JSON 字符串。在 Jsp/Servlet 中,我們接收 key/value 形式的參數(shù),一般是通過(guò) getParameter 方法。如果客戶端商戶傳的是 JSON 數(shù)據(jù),我們可以通過(guò)如下格式進(jìn)行解析:
1
2
3
4
5
6
7
|
@RequestMapping ( "/addbook2" ) @ResponseBody public void addBook2(HttpServletRequest req) throws IOException { ObjectMapper om = new ObjectMapper(); Book book = om.readValue(req.getInputStream(), Book. class ); System.out.println(book); } |
但是這種解析方式有點(diǎn)麻煩,在 SpringMVC 中,我們可以通過(guò)一個(gè)注解來(lái)快速的將一個(gè) JSON 字符串轉(zhuǎn)為一個(gè)對(duì)象:
1
2
3
4
5
|
@RequestMapping ( "/addbook3" ) @ResponseBody public void addBook3( @RequestBody Book book) { System.out.println(book); } |
這樣就可以直接收到前端傳來(lái)的 JSON 字符串了。這也是 HttpMessageConverter 提供的第二個(gè)功能。
返回JSON
目前主流的 JON 處理工具主要有三種:
jackson
jackson 是一個(gè)使用比較多,時(shí)間也比較長(zhǎng)的 JSON 處理工具,在 SpringMVC 中使用 jackson ,只需要添加 jackson 的依賴(lài)即可:
1
2
3
4
5
|
< dependency > < groupId >com.fasterxml.jackson.core</ groupId > < artifactId >jackson-databind</ artifactId > < version >2.10.1</ version > </ dependency > |
依賴(lài)添加成功后,凡是在接口中直接返回的對(duì)象,集合等等,都會(huì)自動(dòng)轉(zhuǎn)為 JSON。如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
public class Book { private Integer id; private String name; private String author; ... } @RequestMapping ( "/book" ) @ResponseBody public Book getBookById() { Book book = new Book(); book.setId( 1 ); book.setName( "三國(guó)演義" ); book.setAuthor( "羅貫中" ); return book; } |
這里返回一個(gè)對(duì)象,但是在前端接收到的則是一個(gè) JSON 字符串,這個(gè)對(duì)象會(huì)通過(guò) HttpMessageConverter 自動(dòng)轉(zhuǎn)為 JSON 字符串。
如果想返回一個(gè) JSON 數(shù)組,寫(xiě)法如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
|
@RequestMapping ( "/books" ) @ResponseBody public List<Book> getAllBooks() { List<Book> list = new ArrayList<Book>(); for ( int i = 0 ; i < 10 ; i++) { Book book = new Book(); book.setId(i); book.setName( "三國(guó)演義:" + i); book.setAuthor( "羅貫中:" + i); list.add(book); } return list; } |
converter 【肯喔特】轉(zhuǎn)變器
添加了 jackson ,就能夠自動(dòng)返回 JSON,這個(gè)依賴(lài)于一個(gè)名為 HttpMessageConverter 的類(lèi),這本身是一個(gè)接口,從名字上就可以看出,它的作用是 Http 消息轉(zhuǎn)換器,既然是消息轉(zhuǎn)換器,它提供了兩方面的功能:
將返回的對(duì)象轉(zhuǎn)為 JSON
將前端提交上來(lái)的 JSON 轉(zhuǎn)為對(duì)象
但是,HttpMessageConverter 只是一個(gè)接口,由各個(gè) JSON 工具提供相應(yīng)的實(shí)現(xiàn),在 jackson 中,實(shí)現(xiàn)的名字叫做 MappingJackson2HttpMessageConverter,而這個(gè)東西的初始化,則由 SpringMVC 來(lái)完成。除非自己有一些自定義配置的需求,否則一般來(lái)說(shuō)不需要自己提供
MappingJackson2HttpMessageConverter。
舉一個(gè)簡(jiǎn)單的應(yīng)用場(chǎng)景,例如每一本書(shū),都有一個(gè)出版日期,修改 Book 類(lèi)如下:
1
2
3
4
5
6
7
|
public class Book { private Integer id; private String name; private String author; private Date publish; ... } |
然后在構(gòu)造 Book 時(shí)添加日期屬性:
1
2
3
4
5
6
7
8
9
10
|
@RequestMapping ( "/book" ) @ResponseBody public Book getBookById() { Book book = new Book(); book.setId( 1 ); book.setName( "三國(guó)演義" ); book.setAuthor( "羅貫中" ); book.setPublish( new Date()); return book; } |
訪問(wèn) /book 接口,返回的 json 格式如下:
如果我們想自己定制返回日期的格式,簡(jiǎn)單的辦法,可以通過(guò)添加注解來(lái)實(shí)現(xiàn):
1
2
3
4
5
6
|
public class Book { private Integer id ; private String name; private String author; private Date publish; |
注意這里一定要設(shè)置時(shí)區(qū)。
這樣,就可以定制返回的日期格式了。
但是,這種方式有一個(gè)弊端,這個(gè)注解可以加在屬性上,也可以加在類(lèi)上,也就說(shuō),最大可以作用到一個(gè)類(lèi)中的所有日期屬性上。如果項(xiàng)目中有很多實(shí)體類(lèi)都需要做日期格式化,使用這種方式就比較麻煩了,這個(gè)時(shí)候,我們可以自己提供一個(gè) jackson 的 HttpMesageConverter 實(shí)例,在這個(gè)實(shí)例中,自己去配置相關(guān)屬性,這里的配置將是一個(gè)全局配置。
在 SpringMVC 配置文件中,添加如下配置:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
< mvc:message-converters > < ref bean = "httpMessageConverter" /> </ mvc:message-converters > </ mvc:annotation-driven > < bean class = "org.springframework.http.converter.json.MappingJackson2HttpMessageConverter" id = "httpMessageConverter" > < property name = "objectMapper" > < bean class = "com.fasterxml.jackson.databind.ObjectMapper" > < property name = "dateFormat" > < bean class = "java.text.SimpleDateFormat" > < constructor-arg name = "pattern" value = "yyyy-MM-dd HH:mm:ss" /> </ bean > </ property > < property name = "timeZone" value = "Asia/Shanghai" /> </ bean > </ property > </ bean > |
添加完成后,去掉 Book 實(shí)體類(lèi)中日期格式化的注解,再進(jìn)行測(cè)試,結(jié)果如下:
gson
gson 是 Google 推出的一個(gè) JSON 解析器,主要在 Android 開(kāi)發(fā)中使用較多,不過(guò),Web 開(kāi)發(fā)中也是支持這個(gè)的,而且 SpringMVC 還針對(duì) Gson 提供了相關(guān)的自動(dòng)化配置,以致我們?cè)陧?xiàng)目中只要添加 gson 依賴(lài),就可以直接使用 gson 來(lái)做 JSON 解析了。
1
2
3
4
5
|
< dependency > < groupId >com.google.code.gson</ groupId > < artifactId >gson</ artifactId > < version >2.8.6</ version > </ dependency > |
如果項(xiàng)目中,同時(shí)存在 jackson 和gson 的話,那么默認(rèn)使用的是 jackson,為什么呢?在
org.springframework.http.converter.support.AllEncompassingFormHttpMessageConverter類(lèi)的構(gòu)造方法中,加載順序就是先加載 jackson 的 HttpMessageConverter,后加載 gson 的 HttpMessageConverter。
加完依賴(lài)之后,就可以直接返回 JSON 字符串了。使用 Gson 時(shí),如果想做自定義配置,則需要自定義 HttpMessageConverter。
1
2
3
4
5
6
7
8
9
10
11
12
13
|
< mvc:annotation-driven > < mvc:message-converters > < ref bean = "httpMessageConverter" /> </ mvc:message-converters > </ mvc:annotation-driven > < bean class = "org.springframework.http.converter.json.GsonHttpMessageConverter" id = "httpMessageConverter" > < property name = "gson" > < bean class = "com.google.gson.Gson" factory-bean = "gsonBuilder" factory-method = "create" /> </ property > </ bean > < bean class = "com.google.gson.GsonBuilder" id = "gsonBuilder" > < property name = "dateFormat" value = "yyyy-MM-dd" /> </ bean > |
fastjson 號(hào)稱(chēng)最快的 JSON 解析器,但是也是這三個(gè)中 BUG 最多的一個(gè)。在 SpringMVC 并沒(méi)針對(duì) fastjson 提供相應(yīng)的 HttpMessageConverter,所以,fastjson 在使用時(shí),一定要自己手動(dòng)配置 HttpMessageConverter(前面兩個(gè)如果沒(méi)有特殊需要,直接添加依賴(lài)就可以了)。
使用 fastjson,我們首先添加 fastjson 依賴(lài):
1
2
3
4
5
|
< dependency > < groupId >com.alibaba</ groupId > < artifactId >fastjson</ artifactId > < version >1.2.60</ version > </ dependency > |
然后在 SpringMVC 的配置文件中配置 HttpMessageConverter:
1
2
3
4
5
6
7
8
9
10
11
12
|
< mvc:annotation-driven > < mvc:message-converters > < ref bean = "httpMessageConverter" /> </ mvc:message-converters > </ mvc:annotation-driven > < bean class = "com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter" id = "httpMessageConverter" > < property name = "fastJsonConfig" > < bean class = "com.alibaba.fastjson.support.config.FastJsonConfig" > < property name = "dateFormat" value = "yyyy-MM-dd" /> </ bean > </ property > </ bean > |
fastjson 默認(rèn)中文亂碼,添加如下配置解決:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
< mvc:annotation-driven > < mvc:message-converters > < ref bean = "httpMessageConverter" /> </ mvc:message-converters > </ mvc:annotation-driven > < bean class = "com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter" id = "httpMessageConverter" > < property name = "fastJsonConfig" > < bean class = "com.alibaba.fastjson.support.config.FastJsonConfig" > < property name = "dateFormat" value = "yyyy-MM-dd" /> </ bean > </ property > < property name = "supportedMediaTypes" > < list > < value >application/json;charset=utf-8</ value > </ list > </ property > </ bean > |
在 SpringMVC 中,對(duì) jackson 和 gson 都提供了相應(yīng)的支持,就是如果使用這兩個(gè)作為 JSON 轉(zhuǎn)換器,只需要添加對(duì)應(yīng)的依賴(lài)就可以了,返回的對(duì)象和返回的集合、Map 等都會(huì)自動(dòng)轉(zhuǎn)為 JSON,但是,如果使用 fastjson,除了添加相應(yīng)的依賴(lài)之外,還需要自己手動(dòng)配置 HttpMessageConverter 轉(zhuǎn)換器。其實(shí)前兩個(gè)也是使用 HttpMessageConverter 轉(zhuǎn)換器,但是是 SpringMVC 自動(dòng)提供的,SpringMVC 沒(méi)有給 fastjson 提供相應(yīng)的轉(zhuǎn)換器。
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持服務(wù)器之家。
原文鏈接:https://www.cnblogs.com/qiuwenli/p/13424010.html