1. 程式人生 > 程式設計 >Spring mvc Json處理實現流程程式碼例項

Spring mvc Json處理實現流程程式碼例項

接收JSON

瀏覽器傳來的引數,可以是 key/value 形式的,也可以是一個 JSON 字串。在 Jsp/Servlet 中,我們接收 key/value 形式的引數,一般是通過 getParameter 方法。如果客戶端商戶傳的是 JSON 資料,我們可以通過如下格式進行解析:

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

但是這種解析方式有點麻煩,在 SpringMVC 中,我們可以通過一個註解來快速的將一個 JSON 字串轉為一個物件:

@RequestMapping("/addbook3")
@ResponseBody
public void addBook3(@RequestBody Book book) {
  System.out.println(book);
}

這樣就可以直接收到前端傳來的 JSON 字串了。這也是 HttpMessageConverter 提供的第二個功能。

返回JSON

目前主流的 JON 處理工具主要有三種:

jackson

jackson 是一個使用比較多,時間也比較長的 JSON 處理工具,在 SpringMVC 中使用 jackson ,只需要新增 jackson 的依賴即可:

<dependency>
  <groupId>com.fasterxml.jackson.core</groupId>
  <artifactId>jackson-databind</artifactId>
  <version>2.10.1</version>
</dependency>

依賴新增成功後,凡是在介面中直接返回的物件,集合等等,都會自動轉為 JSON。如下:

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("三國演義");
  book.setAuthor("羅貫中");
  return book;
}

這裡返回一個物件,但是在前端接收到的則是一個 JSON 字串,這個物件會通過 HttpMessageConverter 自動轉為 JSON 字串。

如果想返回一個 JSON 陣列,寫法如下:

@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("三國演義:" + i);
    book.setAuthor("羅貫中:" + i);
    list.add(book);
  }
  return list;
}

converter 【肯喔特】轉變器

添加了 jackson ,就能夠自動返回 JSON,這個依賴於一個名為 HttpMessageConverter 的類,這本身是一個介面,從名字上就可以看出,它的作用是 Http 訊息轉換器,既然是訊息轉換器,它提供了兩方面的功能:

將返回的物件轉為 JSON

將前端提交上來的 JSON 轉為物件

但是,HttpMessageConverter 只是一個介面,由各個 JSON 工具提供相應的實現,在 jackson 中,實現的名字叫做 MappingJackson2HttpMessageConverter,而這個東西的初始化,則由 SpringMVC 來完成。除非自己有一些自定義配置的需求,否則一般來說不需要自己提供

MappingJackson2HttpMessageConverter。

舉一個簡單的應用場景,例如每一本書,都有一個出版日期,修改 Book 類如下:

public class Book {
  private Integer id;
  private String name;
  private String author;
  private Date publish;
...
}

然後在構造 Book 時新增日期屬性:

@RequestMapping("/book")
@ResponseBody
public Book getBookById() {
  Book book = new Book();
  book.setId(1);
  book.setName("三國演義");
  book.setAuthor("羅貫中");
  book.setPublish(new Date());
  return book;
}

訪問 /book 介面,返回的 json 格式如下:

如果我們想自己定製返回日期的格式,簡單的辦法,可以通過添加註解來實現:

public class Book {
  private Integer id;
  private String name;
  private String author;
  @JsonFormat(pattern = "yyyy-MM-dd",timezone = "Asia/Shanghai")
  private Date publish;

注意這裡一定要設定時區。

這樣,就可以定製返回的日期格式了。

但是,這種方式有一個弊端,這個註解可以加在屬性上,也可以加在類上,也就說,最大可以作用到一個類中的所有日期屬性上。如果專案中有很多實體類都需要做日期格式化,使用這種方式就比較麻煩了,這個時候,我們可以自己提供一個 jackson 的 HttpMesageConverter 例項,在這個例項中,自己去配置相關屬性,這裡的配置將是一個全域性配置。

在 SpringMVC 配置檔案中,新增如下配置:

<mvc:annotation-driven>
  <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 實體類中日期格式化的註解,再進行測試,結果如下:

gson

gson 是 Google 推出的一個 JSON 解析器,主要在 Android 開發中使用較多,不過,Web 開發中也是支援這個的,而且 SpringMVC 還針對 Gson 提供了相關的自動化配置,以致我們在專案中只要新增 gson 依賴,就可以直接使用 gson 來做 JSON 解析了。

<dependency>
  <groupId>com.google.code.gson</groupId>
  <artifactId>gson</artifactId>
  <version>2.8.6</version>
</dependency>

如果專案中,同時存在 jackson 和gson 的話,那麼預設使用的是 jackson,為什麼呢?在
org.springframework.http.converter.support.AllEncompassingFormHttpMessageConverter類的構造方法中,載入順序就是先載入 jackson 的 HttpMessageConverter,後加載 gson 的 HttpMessageConverter。

加完依賴之後,就可以直接返回 JSON 字串了。使用 Gson 時,如果想做自定義配置,則需要自定義 HttpMessageConverter。

<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 號稱最快的 JSON 解析器,但是也是這三個中 BUG 最多的一個。在 SpringMVC 並沒針對 fastjson 提供相應的 HttpMessageConverter,所以,fastjson 在使用時,一定要自己手動配置 HttpMessageConverter(前面兩個如果沒有特殊需要,直接新增依賴就可以了)。

使用 fastjson,我們首先新增 fastjson 依賴:

<dependency>
  <groupId>com.alibaba</groupId>
  <artifactId>fastjson</artifactId>
  <version>1.2.60</version>
</dependency>

然後在 SpringMVC 的配置檔案中配置 HttpMessageConverter:

<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 預設中文亂碼,新增如下配置解決:

<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 中,對 jackson 和 gson 都提供了相應的支援,就是如果使用這兩個作為 JSON 轉換器,只需要新增對應的依賴就可以了,返回的物件和返回的集合、Map 等都會自動轉為 JSON,但是,如果使用 fastjson,除了新增相應的依賴之外,還需要自己手動配置 HttpMessageConverter 轉換器。其實前兩個也是使用 HttpMessageConverter 轉換器,但是是 SpringMVC 自動提供的,SpringMVC 沒有給 fastjson 提供相應的轉換器。

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支援我們。