對於每一個開發web的人來講,JSON確定都不陌生.它的輕量級與簡潔性,使得它備受青睞.同時,隨着先後臺技術的不斷成熟,Json解析技術也發展地愈來愈完善.在這衆多的Json解析技術中,備受歡迎的則是咱們今天要講的如下三種:html
Jacksonjava
Gsongit
json-bgithub
Jackson是一個簡單基於Java應用庫,Jackson能夠輕鬆的將Java對象轉換成json對象和xml文檔,一樣也能夠將json、xml轉換成Java對象。Jackson所依賴的jar包較少,簡單易用而且性能也要相對高些,而且Jackson社區相對比較活躍,更新速度也比較快。從SpringMVC到SpringBoot,官方推薦的都是jackson.,它主要具有如下幾個優勢:容易使用。web
容易使用 - jackson API提供了一個高層次外觀,以簡化經常使用的用例。spring
無需建立映射 - API提供了默認的映射大部分對象序列化。apache
性能高 - 快速,低內存佔用,適合大型對象圖表或系統。json
乾淨的JSON - jackson建立一個乾淨和緊湊的JSON結果,這是讓人很容易閱讀。api
不依賴 - 庫不須要任何其餘的庫,除了JDK。瀏覽器
開源代碼 - jackson是開源的,能夠無償使用。
對於咱們而言,咱們比較關心的是他的序列化操做,這裏咱們先引入jackson的依賴包
<dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> </dependency>
構建成功後,咱們看到依賴裏出現了:
jackson-annotations-2.9.0.jar jackson-core-2.9.7.jar jackson-databind-2.9.7.jar
這是jackson的依賴庫,接下來咱們建立一個基本的實體類:
package top.lianmengtu.testjson.domain; import lombok.Getter; import lombok.Setter; @Getter @Setter public class UserInfo { private Long id; private String nickName; private Boolean gender; }
咱們來一個測試類:
package top.lianmengtu.testjson; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; import top.lianmengtu.testjson.domain.UserInfo; public class MyJsonTest { public static void main(String[] args) { ObjectMapper objectMapper=new ObjectMapper(); UserInfo userInfo = new UserInfo(); userInfo.setId(1l); userInfo.setNickName("Nick"); userInfo.setGender(false); String userInfoString= null; try { userInfoString = objectMapper.writeValueAsString(userInfo); } catch (JsonProcessingException e) { e.printStackTrace(); } System.out.println(userInfoString); } }
運行結果以下:
{"id":1,"nickName":"Nick","gender":false}
這是一個基本類型,咱們這裏添加兩個屬性,一個基本類型的List,另外一個是日期類型:
package top.lianmengtu.testjson.domain; import com.fasterxml.jackson.annotation.JsonFormat; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; import lombok.Getter; import lombok.Setter; import java.util.ArrayList; import java.util.Date; import java.util.List; @Getter @Setter public class UserInfo { private Long id; private String nickName; private Boolean gender; private List<String> roleList; private Date createTime; }
測試類以下:
package top.lianmengtu.testjson; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; import top.lianmengtu.testjson.domain.UserInfo; import java.util.ArrayList; import java.util.Date; import java.util.List; public class MyJsonTest { public static void main(String[] args) { ObjectMapper objectMapper =new ObjectMapper(); UserInfo userInfo = new UserInfo(); userInfo.setId(1l); userInfo.setNickName("Nick"); userInfo.setGender(false); List<String> roleList=new ArrayList<>(); roleList.add("admin"); roleList.add("manager"); userInfo.setRoleList(roleList); userInfo.setCreateTime(new Date()); String userInfoString= null; try { userInfoString = objectMapper.writeValueAsString(userInfo); } catch (JsonProcessingException e) { e.printStackTrace(); } System.out.println(userInfoString); } }
運行結果以下:
{"id":1,"nickName":"Nick","gender":false,"roleList":["admin","manager"],"createTime":1540451548817}
這裏咱們看到基本類型的List按着咱們的指望解析了,但日期明顯不是咱們想要的,這裏咱們可使用@JsonFormat來傳入咱們想要的格式,以下所示:
package top.lianmengtu.testjson.domain; import com.fasterxml.jackson.annotation.JsonFormat; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; import lombok.Getter; import lombok.Setter; import java.util.ArrayList; import java.util.Date; import java.util.List; @Getter @Setter public class UserInfo { private Long id; private String nickName; private Boolean gender; private List<String> roleList; @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") private Date createTime; }
這裏咱們的測試類不變,運行結果以下所示:
{"id":1,"nickName":"Nick","gender":false,"roleList":["admin","manager"],"createTime":"2018-10-25 07:16:12"}
此時,咱們看到日期類型已經按着咱們指望的格式進行展現了.咱們在使用的時候,常會使用內嵌類型,這裏咱們給用戶定義一個公司:
package top.lianmengtu.testjson.domain; import lombok.Getter; import lombok.Setter; @Setter @Getter public class Company { private Long id; private String name; private String address; }
咱們再給用戶定義一個公司列表,代表用戶工做過的公司:
package top.lianmengtu.testjson.domain; import com.fasterxml.jackson.annotation.JsonFormat; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; import lombok.Getter; import lombok.Setter; import java.util.ArrayList; import java.util.Date; import java.util.List; @Getter @Setter public class UserInfo { private Long id; private String nickName; private Boolean gender; private List<String> roleList; private List<Company> companies; @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") private Date createTime; }
咱們也修改一下測試類:
package top.lianmengtu.testjson; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; import top.lianmengtu.testjson.domain.Company; import top.lianmengtu.testjson.domain.UserInfo; import java.util.ArrayList; import java.util.Date; import java.util.List; public class MyJsonTest { public static void main(String[] args) { ObjectMapper objectMapper =new ObjectMapper(); UserInfo userInfo = new UserInfo(); userInfo.setId(1l); userInfo.setNickName("Nick"); userInfo.setGender(false); List<String> roleList=new ArrayList<>(); roleList.add("admin"); roleList.add("manager"); userInfo.setRoleList(roleList); Company baidu=new Company(); baidu.setId(1l); baidu.setName("百度"); baidu.setAddress("西二旗"); List<Company> companies = new ArrayList<>(); companies.add(baidu); userInfo.setCompanies(companies); userInfo.setCreateTime(new Date()); String userInfoString= null; try { userInfoString = objectMapper.writeValueAsString(userInfo); } catch (JsonProcessingException e) { e.printStackTrace(); } System.out.println(userInfoString); } }
運行結果以下:
{"id":1,"nickName":"Nick","gender":false,"roleList":["admin","manager"],"companies":[{"id":1,"name":"百度","address":"西二旗"}],"createTime":"2018-10-25 07:19:42"}
展現了基本使用以後,咱們如今來看一下SpringBoot對Jackson的支持,當咱們在pom中添加了spring-boot-starter-web 以後,咱們發現已經自動加入了jackson的三個包.啓動類以下:
package top.lianmengtu.testjson; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class Application { public static void main(String[] args) { SpringApplication.run(Application.class,args); } }
JsonController類代碼以下所示:
package top.lianmengtu.testjson.controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import top.lianmengtu.testjson.domain.Company; import top.lianmengtu.testjson.domain.UserInfo; import java.util.ArrayList; import java.util.Date; import java.util.List; @RestController @RequestMapping("json/") public class JsonController { @RequestMapping("basic_json") public UserInfo basicJson(){ UserInfo userInfo = new UserInfo(); userInfo.setId(1l); userInfo.setNickName("Nick"); userInfo.setGender(false); List<String> roleList=new ArrayList<>(); roleList.add("admin"); roleList.add("manager"); userInfo.setRoleList(roleList); Company baidu=new Company(); baidu.setId(1l); baidu.setName("百度"); baidu.setAddress("西二旗"); List<Company> companies = new ArrayList<>(); companies.add(baidu); userInfo.setCompanies(companies); userInfo.setCreateTime(new Date()); return userInfo; } }
咱們啓動項目,而後打開瀏覽器,結果以下所示:
{"id":1,"nickName":"Nick","gender":false,"roleList":["admin","manager"],"companies":[{"id":1,"name":"百度","address":"西二旗"}],"createTime":"2018-10-25 07:44:13"}
和咱們剛剛演示的同樣,但如今有兩個問題,首先,包含日期類型的model可能不僅一個,若是咱們在model裏添加@JsonFormat可能每個都須要加,比較地繁瑣.其次,有些時候咱們可能沒有辦法改變model的源碼,所以不能給諸如日期這樣的字段添加@JsonFormat註解,那怎麼辦呢?此時咱們就能夠將咱們的配置外移,移到application.yml裏,以下所示:
spring: jackson: date-format: 'yyyy-MM-dd'
而後咱們將實體類裏的@JsonFormat去掉,以下所示:
package top.lianmengtu.testjson.domain; import com.fasterxml.jackson.annotation.JsonFormat; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; import lombok.Getter; import lombok.Setter; import java.util.ArrayList; import java.util.Date; import java.util.List; @Getter @Setter public class UserInfo { private Long id; private String nickName; private Boolean gender; private List<String> roleList; private List<Company> companies; private Date createTime; }
咱們運行咱們的代碼,發現日期如今變成了咱們在配置文件裏配置的yyyy-MM-dd的格式:
{"id":1,"nickName":"Nick","gender":false,"roleList":["admin","manager"],"companies":[{"id":1,"name":"百度","address":"西二旗"}],"createTime":"2018-10-25"}
不過這裏有一點須要說明一下,若是咱們即在yml裏進行了配置,同時也使用了@JsonFormat註解,那麼@JsonFormat會覆蓋yml裏的。除此以外,springBoot還支持jackson如下一些屬性的使用:
spring.jackson.default-property-inclusion= spring.jackson.deserialization.*= spring.jackson.generator.*= spring.jackson.joda-date-time-format= spring.jackson.locale= spring.jackson.mapper.*= spring.jackson.parser.*= spring.jackson.property-naming-strategy= spring.jackson.serialization.*= spring.jackson.time-zone=
它使用的方式和objectMapper使用的方式幾乎如出一轍,好比,咱們剛剛嘗試過關於日期格式的問題,在咱們沒有寫JsonFormat的時候,jackson會自動將咱們的日期格式轉換爲時間戳,如今咱們來禁用這個屬性
public static void main(String[] args) { ObjectMapper objectMapper=new ObjectMapper(); UserInfo userInfo = new UserInfo(); userInfo.setId(1l); userInfo.setNickName("Nick"); userInfo.setGender(false); userInfo.setCreateTime(new Date()); objectMapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS); String userInfoString= null; try { userInfoString = objectMapper.writeValueAsString(userInfo); } catch (JsonProcessingException e) { e.printStackTrace(); } System.out.println(userInfoString); }
由於serialization是一個map,因此在yml裏這麼寫
spring: jackson: serialization: /write_dates_as_timestamps: false
當咱們禁用以後,打印出來的字符串以下所示:
{"id":1,"nickName":"Nick","gender":false,"roleList":null,"companies":null,"createTime":"2018-10-25T08:46:32.192+0000"}
咱們發現,已經不在是時間戳了,說明咱們的配置已經生效了,其餘的,你們能夠進到相應的實現裏去一一查看.
gson是google出的一個json解析工具.使用它的時候,咱們只須要在pom中添加gson一個包就能夠了,以下所示:
<dependency> <groupId>com.google.code.gson</groupId> <artifactId>gson</artifactId> <version>2.8.5</version> </dependency>
咱們仍是先來看一下gson的基本使用.咱們仍然使用剛剛那個實體類:
package top.lianmengtu.testjson.domain; import lombok.Getter; import lombok.Setter; import java.util.Date; import java.util.List; @Getter @Setter public class UserInfo { private Long id; private String nickName; private Boolean gender; private List<String> roleList; private List<Company> companies; private Date createTime; }
而後是咱們的測試類:
package top.lianmengtu.testjson; import com.google.gson.Gson; import com.google.gson.GsonBuilder; import com.google.gson.JsonObject; import top.lianmengtu.testjson.domain.Company; import top.lianmengtu.testjson.domain.UserInfo; import java.util.ArrayList; import java.util.Date; import java.util.List; public class GsonTest { public static void main(String[] args) { UserInfo userInfo = new UserInfo(); userInfo.setId(1l); userInfo.setNickName("Nick"); userInfo.setGender(false); List<String> roleList=new ArrayList<>(); roleList.add("admin"); roleList.add("manager"); userInfo.setRoleList(roleList); Company baidu=new Company(); baidu.setId(1l); baidu.setName("百度"); baidu.setAddress("西二旗"); List<Company> companies = new ArrayList<>(); companies.add(baidu); userInfo.setCompanies(companies); userInfo.setCreateTime(new Date()); Gson gson=new Gson(); String userInfoString=gson.toJson(userInfo); System.out.println(userInfoString); } }
而後運行結果以下所示:
{"id":1,"nickName":"Nick","gender":false,"roleList":["admin","manager"],"companies":[{"id":1,"name":"百度","address":"西二旗"}],"createTime":"Oct 25, 2018, 5:12:44 PM"}
如今咱們來展現他的日期轉換,在gson中咱們處理日期轉換可使用gsonbuilder去處理,以下所示(由於重點是日期,因此略過其餘字段):
package top.lianmengtu.testjson; import com.google.gson.Gson; import com.google.gson.GsonBuilder; import top.lianmengtu.testjson.domain.UserInfo; import java.util.Date; public class GsonTest { public static void main(String[] args) { UserInfo userInfo = new UserInfo(); userInfo.setCreateTime(new Date()); GsonBuilder gsonBuilder = new GsonBuilder(); gsonBuilder.setDateFormat("yyyy-MM-dd"); Gson gson=gsonBuilder.create(); String userInfoString=gson.toJson(userInfo); System.out.println(userInfoString); } }
測試結果以下所示:
{"createTime":"2018-10-25"}
gsonbuilder的這種處理方式,除了能處理date類型外,還能處理long類型,能夠將long轉換爲字符串或者轉換爲數字類型.默認是將long轉換爲數字,這裏咱們處理成字符串,測試類以下所示:
package top.lianmengtu.testjson; import com.google.gson.Gson; import com.google.gson.GsonBuilder; import com.google.gson.LongSerializationPolicy; import top.lianmengtu.testjson.domain.UserInfo; import java.util.Date; public class GsonTest { public static void main(String[] args) { UserInfo userInfo = new UserInfo(); userInfo.setId(1l); userInfo.setCreateTime(new Date()); GsonBuilder gsonBuilder = new GsonBuilder(); gsonBuilder.setDateFormat("yyyy-MM-dd"); gsonBuilder.setLongSerializationPolicy(LongSerializationPolicy.STRING); Gson gson=gsonBuilder.create(); String userInfoString=gson.toJson(userInfo); System.out.println(userInfoString); } }
運行結果以下:
{"id":"1","createTime":"2018-10-25"}
以前在json的時候出現過一種狀況,就是循環解析致使報錯的,最典型的狀況是對tree的解析,以前咱們曾在tree裏設置children來存放子節點,同時又設置了parent來存放父節點,後來就直接報錯了.除了這些以外,還有一些純粹是爲了咱們的業務邏輯而設置的屬性,這些咱們也須要忽略,那gson如何實現這個功能呢:
1.字段上標註transient或@Expose
實體類代碼以下所示:
package top.lianmengtu.testjson.domain; import lombok.Getter; import lombok.Setter; import org.springframework.format.annotation.DateTimeFormat; import java.util.Date; import java.util.List; @Getter @Setter public class UserInfo { private transient Long id; private String nickName; private Boolean gender; private List<String> roleList; private List<Company> companies; private Date createTime; }
而後咱們仍然運行上面的測試代碼,運行結果以下所示:
{"createTime":"2018-10-25"}
使用transient是標記須要排除的,而@Expose則標記的是須要序列化的字段.實體類修改以下:
package top.lianmengtu.testjson.domain; import com.google.gson.annotations.Expose; import lombok.Getter; import lombok.Setter; import org.springframework.format.annotation.DateTimeFormat; import java.util.Date; import java.util.List; @Getter @Setter public class UserInfo { @Expose private Long id; @Expose private String nickName; @Expose private Boolean gender; private List<String> roleList; private List<Company> companies; @Expose private Date createTime; }
測試代碼修改以下:
package top.lianmengtu.testjson; import com.google.gson.*; import top.lianmengtu.testjson.domain.Company; import top.lianmengtu.testjson.domain.UserInfo; import java.util.ArrayList; import java.util.Date; import java.util.List; public class GsonTest { public static void main(String[] args) { UserInfo userInfo = new UserInfo(); userInfo.setId(1l); userInfo.setCreateTime(new Date()); userInfo.setNickName("Nick"); userInfo.setGender(false); List<String> roleList=new ArrayList<>(); roleList.add("admin"); roleList.add("manager"); userInfo.setRoleList(roleList); Company baidu=new Company(); baidu.setId(1l); baidu.setName("百度"); baidu.setAddress("西二旗"); List<Company> companies = new ArrayList<>(); companies.add(baidu); userInfo.setCompanies(companies); GsonBuilder gsonBuilder = new GsonBuilder(); gsonBuilder.setDateFormat("yyyy-MM-dd"); gsonBuilder.excludeFieldsWithoutExposeAnnotation(); Gson gson=gsonBuilder.create(); String userInfoString=gson.toJson(userInfo); System.out.println(userInfoString); } }
運行結果以下:
{"id":1,"nickName":"Nick","gender":false,"createTime":"2018-10-25"}
2.使用排除策略 exclusionStrategy
排除策略有不少種,另外一種是傳字符串去匹配,測試代碼修改以下:
package top.lianmengtu.testjson; import com.google.gson.*; import top.lianmengtu.testjson.domain.Company; import top.lianmengtu.testjson.domain.UserInfo; import java.util.ArrayList; import java.util.Date; import java.util.List; public class GsonTest { public static void main(String[] args) { UserInfo userInfo = new UserInfo(); userInfo.setId(1l); userInfo.setCreateTime(new Date()); userInfo.setNickName("Nick"); userInfo.setGender(false); List<String> roleList=new ArrayList<>(); roleList.add("admin"); roleList.add("manager"); userInfo.setRoleList(roleList); Company baidu=new Company(); baidu.setId(1l); baidu.setName("百度"); baidu.setAddress("西二旗"); List<Company> companies = new ArrayList<>(); companies.add(baidu); userInfo.setCompanies(companies); GsonBuilder gsonBuilder = new GsonBuilder(); gsonBuilder.setDateFormat("yyyy-MM-dd"); final List<String> filedList= new ArrayList<>(); filedList.add("companies"); filedList.add("nickName"); gsonBuilder.addSerializationExclusionStrategy(new ExclusionStrategy() { @Override public boolean shouldSkipField(FieldAttributes fieldAttributes) { String name=fieldAttributes.getName(); for(String filed: filedList){ if(filed.equals(name)){ return true; } } return false; } @Override public boolean shouldSkipClass(Class<?> clazz) { return false; } }); Gson gson=gsonBuilder.create(); String userInfoString=gson.toJson(userInfo); System.out.println(userInfoString); } }
而後咱們再運行,獲得結果以下:
{"id":1,"gender":false,"roleList":["admin","manager"],"createTime":"2018-10-25"}
由於SpringBoot是支持SPI的,簡單理解就是能抓到哪一個,就用哪一個實現,由於spring-boot-starter-web默認是用jackson,因此此時爲了可以讓springboot抓到gson,咱們一方面要在pom里加上gson的配置,另外一方面還須要將jackson排除掉,以下所示:
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>top.lianmengtu</groupId> <artifactId>test-json</artifactId> <version>1.0-SNAPSHOT</version> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.0.6.RELEASE</version> </parent> <name>test-json</name> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <maven.compiler.source>11</maven.compiler.source> <maven.compiler.target>11</maven.compiler.target> <lombok.version>1.18.2</lombok.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> <exclusions> <exclusion> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> </exclusion> <exclusion> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-annotations</artifactId> </exclusion> <exclusion> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-core</artifactId> </exclusion> </exclusions> </dependency> <dependency> <groupId>com.google.code.gson</groupId> <artifactId>gson</artifactId> <version>2.8.5</version> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>${lombok.version}</version> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>
這樣就能夠在SpringBoot中啓用Gson了.咱們能夠打開日誌查看一下:
GsonAutoConfiguration matched: - @ConditionalOnClass found required class 'com.google.gson.Gson'; @ConditionalOnMissingClass did not find unwanted class (OnClassCondition) GsonAutoConfiguration#gson matched: - @ConditionalOnMissingBean (types: com.google.gson.Gson; SearchStrategy: all) did not find any beans (OnBeanCondition) GsonAutoConfiguration#gsonBuilder matched: - @ConditionalOnMissingBean (types: com.google.gson.GsonBuilder; SearchStrategy: all) did not find any beans (OnBeanCondition) GsonHttpMessageConvertersConfiguration matched: - @ConditionalOnClass found required class 'com.google.gson.Gson'; @ConditionalOnMissingClass did not find unwanted class (OnClassCondition) GsonHttpMessageConvertersConfiguration.GsonHttpMessageConverterConfiguration matched: - AnyNestedCondition 1 matched 1 did not; NestedCondition on GsonHttpMessageConvertersConfiguration.PreferGsonOrJacksonAndJsonbUnavailableCondition.JacksonJsonbUnavailable NoneNestedConditions 0 matched 2 did not; NestedCondition on GsonHttpMessageConvertersConfiguration.JacksonAndJsonbUnavailableCondition.JsonbPreferred @ConditionalOnProperty (spring.http.converters.preferred-json-mapper=jsonb) did not find property 'spring.http.converters.preferred-json-mapper'; NestedCondition on GsonHttpMessageConvertersConfiguration.JacksonAndJsonbUnavailableCondition.JacksonAvailable @ConditionalOnBean (types: org.springframework.http.converter.json.MappingJackson2HttpMessageConverter; SearchStrategy: all) did not find any beans of type org.springframework.http.converter.json.MappingJackson2HttpMessageConverter; NestedCondition on GsonHttpMessageConvertersConfiguration.PreferGsonOrJacksonAndJsonbUnavailableCondition.GsonPreferred @ConditionalOnProperty (spring.http.converters.preferred-json-mapper=gson) did not find property 'spring.http.converters.preferred-json-mapper' (GsonHttpMessageConvertersConfiguration.PreferGsonOrJacksonAndJsonbUnavailableCondition) - @ConditionalOnBean (types: com.google.gson.Gson; SearchStrategy: all) found bean 'gson' (OnBeanCondition)
如今咱們來演示一下日期排除,Controller代碼以下:
package top.lianmengtu.testjson.controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import top.lianmengtu.testjson.domain.Company; import top.lianmengtu.testjson.domain.UserInfo; import java.util.ArrayList; import java.util.Date; import java.util.List; @RestController @RequestMapping("gson/") public class GsonController { @RequestMapping("basic") public UserInfo basic(){ UserInfo userInfo = new UserInfo(); userInfo.setId(1l); userInfo.setCreateTime(new Date()); userInfo.setNickName("Nick"); userInfo.setGender(false); List<String> roleList=new ArrayList<>(); roleList.add("admin"); roleList.add("manager"); userInfo.setRoleList(roleList); Company baidu=new Company(); baidu.setId(1l); baidu.setName("百度"); baidu.setAddress("西二旗"); List<Company> companies = new ArrayList<>(); companies.add(baidu); userInfo.setCompanies(companies); return userInfo; } }
與jackson配置相似,springboot支持gson,其相關配置在spring.gson下,yml配置修改以下:
spring: gson: date-format: 'yyyy-MM-dd HH:mm:ss'
運行後,結果以下:
{"id":1,"nickName":"Nick","gender":false,"roleList":["admin","manager"],"companies":[{"id":1,"name":"百度","address":"西二旗"}],"createTime":"2018-10-25 18:38:38"}
如今咱們來演示字段排除,由於transient是自動支持的,因此咱們再也不演示,咱們來演示一下@Expose的使用,配置文件修改以下:
spring: gson: date-format: 'yyyy-MM-dd HH:mm:ss' exclude-fields-without-expose-annotation: true
而後實體類修改以下:
package top.lianmengtu.testjson.domain; import com.google.gson.annotations.Expose; import lombok.Getter; import lombok.Setter; import org.springframework.format.annotation.DateTimeFormat; import java.util.Date; import java.util.List; @Getter @Setter public class UserInfo { @Expose private Long id; @Expose private String nickName; private Boolean gender; private List<String> roleList; private List<Company> companies; private Date createTime; }
咱們在id和nickName字段上加上@Expose,,而後運行代碼,效果以下所示:
{"id":1,"nickName":"Nick"}
除了這些以外,它支持的配置以下所示:
spring.gson.date-format= spring.gson.disable-html-escaping= spring.gson.disable-inner-class-serialization= spring.gson.enable-complex-map-key-serialization= spring.gson.exclude-fields-without-expose-annotation= spring.gson.field-naming-policy= spring.gson.generate-non-executable-json= spring.gson.lenient= spring.gson.long-serialization-policy= spring.gson.pretty-printing= spring.gson.serialize-nulls=
這裏有個屬性是disable-html-escaping,能夠幫助咱們過濾html標籤,這個在某些場景下仍是頗有用的
json-b是Java EE8中提供的一種json標準.該 API提供了適配器及一些自定義序列化器和反序列化器。對於較高級的場景,可使用類中的註解或運行時配置構建器來覆蓋 JSON-B 的默認設置。
總而言之,JSON-B整理了已在企業開發人員中普遍應用的行業實踐和方法。它使用註解經過映射語義來標記類和字段,提供了處理複雜數據結構時經常須要的可擴展性。
最重要的是,這個 API 支持以一種直觀且容易的方式在 Java 類與 JSON 文檔之間進行綁定。甚至沒有 JSON經驗的開發人員,應該也可以輕鬆上手使用 Java API for JSON Binding。對 JSON 反/序列化庫(好比 GSON、Boon 和 Jackson)經驗豐富的開發人員將發現 JSON-B 很熟悉且用起來很溫馨。
咱們仍然從兩方面來闡述JSON-B的使用,首先是非SpringBoot項目中的使用,其次是SpringBoot項目中的使用
json-b是一種規範,其中Yasson是eclipse實現的,而johnzon-jsonb則是apache實現的.由於json-b是一種規範,因此咱們只要加入實現便可,不管哪一種實現,使用起來幾乎是同樣的,咱們添加了Yasson,GAV座標以下:
<dependency> <groupId>org.eclipse</groupId> <artifactId>yasson</artifactId> <version>1.0.2</version> </dependency> <dependency> <groupId>org.glassfish</groupId> <artifactId>javax.json</artifactId> <version>1.1.2</version> </dependency>
測試代碼以下:
package top.lianmengtu.testjson; import top.lianmengtu.testjson.domain.Company; import top.lianmengtu.testjson.domain.UserInfo; import javax.json.bind.Jsonb; import javax.json.bind.JsonbBuilder; import java.util.ArrayList; import java.util.Date; import java.util.List; public class JSONBTest { public static void main(String[] args) { UserInfo userInfo = new UserInfo(); userInfo.setId(1l); userInfo.setCreateTime(new Date()); userInfo.setNickName("Nick"); userInfo.setGender(false); List<String> roleList=new ArrayList<>(); roleList.add("admin"); roleList.add("manager"); userInfo.setRoleList(roleList); Company baidu=new Company(); baidu.setId(1l); baidu.setName("百度"); baidu.setAddress("西二旗"); List<Company> companies = new ArrayList<>(); companies.add(baidu); userInfo.setCompanies(companies); Jsonb userJson=JsonbBuilder.create(); String userInfoString=userJson.toJson(userInfo); System.out.println(userInfoString); } }
運行代碼後的結果以下:
{"companies":[{"address":"西二旗","id":1,"name":"百度"}],"createTime":"2018-10-25T11:32:17.337Z[UTC]","gender":false,"id":1,"nickName":"Nick","roleList":["admin","manager"]}
首先,咱們仍是來看日期格式化的問題,測試代碼以下:
package top.lianmengtu.testjson; import top.lianmengtu.testjson.domain.Company; import top.lianmengtu.testjson.domain.UserInfo; import javax.json.bind.Jsonb; import javax.json.bind.JsonbBuilder; import javax.json.bind.JsonbConfig; import java.util.ArrayList; import java.util.Date; import java.util.List; import java.util.Locale; public class JSONBTest { public static void main(String[] args) { UserInfo userInfo = new UserInfo(); userInfo.setId(1l); userInfo.setCreateTime(new Date()); userInfo.setNickName("Nick"); userInfo.setGender(false); List<String> roleList=new ArrayList<>(); roleList.add("admin"); roleList.add("manager"); userInfo.setRoleList(roleList); Company baidu=new Company(); baidu.setId(1l); baidu.setName("百度"); baidu.setAddress("西二旗"); List<Company> companies = new ArrayList<>(); companies.add(baidu); userInfo.setCompanies(companies); JsonbConfig config=new JsonbConfig(); config.withDateFormat("yyyy-MM-dd",Locale.CHINESE); Jsonb userJson=JsonbBuilder.create(config); String userInfoString=userJson.toJson(userInfo); System.out.println(userInfoString); } }
運行就結果以下:
{"companies":[{"address":"西二旗","id":1,"name":"百度"}],"createTime":"2018-10-25","gender":false,"id":1,"nickName":"Nick","roleList":["admin","manager"]}
在springBoot中使用JSON-B的方式和GSON類似,咱們只須要排除掉jackson而後添加上apache-johnzon的jackson就能夠了.這裏咱們添加的是Apache Johnzon. GAV座標以下:
<dependency> <groupId>org.apache.johnzon</groupId> <artifactId>johnzon-jsonb</artifactId> <version>1.1.10</version> </dependency> <dependency> <groupId>org.apache.johnzon</groupId> <artifactId>jsonb-api</artifactId> <version>1.0.0</version> </dependency>
配置文件以下所示:
JsonbHttpMessageConvertersConfiguration matched: - @ConditionalOnClass found required class 'javax.json.bind.Jsonb'; @ConditionalOnMissingClass did not find unwanted class (OnClassCondition)
咱們看懂這裏匹配到的是jsonb,這說明咱們的配置已經成功了.controller不變,咱們打開瀏覽器,而後訪問localhost:8080/jsonb/basic,結果以下所示:
{"companies":[{"address":"西二旗","id":1,"name":"百度"}],"createTime":"2018-10-25","gender":false,"id":1,"nickName":"Nick","roleList":["admin","manager"]}