Spring MVC JSON data interaction

In our development, the back end often needs to accept the Json string data passed from the front end. How to convert the Json string into a Java object? The back end often needs to return the Json string to the front end. How to convert the Java object data into the Json string?

Review JSON

JSON(JavaScript Object Notation)

Comparison of JSON technologies

In the early days, JSON assembly and parsing were realized by writing code manually, which is not efficient. Therefore, many tool classes for assembling and parsing JSON format information appeared later, such as JSON lib, Jackson, Gson and fastjason, which can solve the development efficiency of JSON interaction.

1)json-lib

JSON LIB was also the earliest widely used JSON parsing tool, but it relies on many third-party packages, such as commons-beautils.jar, commons-collections-3.2.jar, commons-lang-2.6.jar, commons-logging-1.1.1.jar, ezmorph-1.0.6.jar, etc.

For the conversion of complex types, JSON lib has defects when converting JSON to Bean. For example, if a class contains a List or Map collection of another class, there will be problems in the conversion of JSON lib from JSON to Bean.

Therefore, JSON lib can not meet the needs of Internet in terms of function and performance.

2) Open source Jackson

Open source Jackson is a JSON conversion tool built into Spring MVC. Compared with JSON lib framework, Jackson relies on fewer jar files, which is easy to use and has higher performance. Moreover, Jackson community is relatively active and the update speed is relatively fast.

However, Jackson will have problems in converting JSON beans of complex types, and there will be problems in the conversion of some sets of Map and List. Jackson's JSON format for converting beans of complex types is not the standard JSON format.

3) Google's Gson

Gson is currently the most fully functional JSON parsing artifact. Gson was originally developed by Google according to the internal needs of Google. Since the first version was publicly released in May 2008, gson has been applied by many companies or users.

Gson mainly provides two conversion functions: tojason and fromjason. It can run directly on the JDK without relying on other jar files. Before using these two functions to convert, you need to create the object type and its members before you can successfully convert the JSON string to the corresponding object.

As long as there are get and set methods in the class, gson can convert complex types of JSON to Bean or Bean to JSON. It is an artifact of JSON parsing. Gson is impeccable in function, but its performance is lower than that of fastjason.

4) Alibaba's fastjason

Fastjason is a high-performance JSON processor written in Java language and developed by Alibaba company.

Fastjason can run directly on the JDK without relying on other jar files.

Fastjason will have some problems in converting JSON from Bean to JSON of complex types. There may be referenced types, resulting in JSON conversion errors. Reference needs to be made.

Fastjason uses an original algorithm to improve the speed of parse to the extreme, surpassing all JSON libraries.



To sum up the comparison of the four JSON technologies, Google's Gson and Alibaba's fastjason can be used in parallel during project selection. If there are only functional requirements and no performance requirements, Google's Gson can be used. If there are performance requirements above, you can use Gson to convert beans into JSON to ensure correct data, and use FastJson to convert JSON into beans.

JSON data conversion

In the process of data binding, Spring MVC needs to convert the format and type of transmitted data. It can convert not only String and other types of data, but also JSON and other types of data.

Open source Jackson

Create a new module, spring mvc-05-json, and add web support

Import jar file

The Maven project adds the following dependencies in the pom.xml file.

<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-core -->
<dependency>
   <groupId>com.fasterxml.jackson.core</groupId>
   <artifactId>jackson-databind</artifactId>
   <version>2.9.8</version>
</dependency>

Configure Spring MVC core configuration file

web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
        version="4.0">

   <!--1.register servlet-->
   <servlet>
       <servlet-name>SpringMVC</servlet-name>
       <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
       <!--Specified by initialization parameters SpringMVC The location of the configuration file is associated-->
       <init-param>
           <param-name>contextConfigLocation</param-name>
           <param-value>classpath:springmvc-servlet.xml</param-value>
       </init-param>
       <!-- Start sequence: the smaller the number, the earlier the start -->
       <load-on-startup>1</load-on-startup>
   </servlet>

   <!--All requests will be rejected springmvc intercept -->
   <servlet-mapping>
       <servlet-name>SpringMVC</servlet-name>
       <url-pattern>/</url-pattern>
   </servlet-mapping>

   <filter>
       <filter-name>encoding</filter-name>
       <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
       <init-param>
           <param-name>encoding</param-name>
           <param-value>utf-8</param-value>
       </init-param>
   </filter>
   <filter-mapping>
       <filter-name>encoding</filter-name>
       <url-pattern>/</url-pattern>
   </filter-mapping>

</web-app>

springmvc-servlet.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xmlns:context="http://www.springframework.org/schema/context"
      xmlns:mvc="http://www.springframework.org/schema/mvc"
      xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/context
       https://www.springframework.org/schema/context/spring-context.xsd
       http://www.springframework.org/schema/mvc
       https://www.springframework.org/schema/mvc/spring-mvc.xsd">

   <!-- Automatically scan the specified package, and submit all the following annotation classes to IOC Container management -->
   <context:component-scan base-package="com.kuang.controller"/>

   <!-- view resolver  -->
   <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"
         id="internalResourceViewResolver">
       <!-- prefix -->
       <property name="prefix" value="/WEB-INF/jsp/" />
       <!-- suffix -->
       <property name="suffix" value=".jsp" />
   </bean>

</beans>

Create POJO class

package com.kuang.pojo;

public class User {
    private String name;
    private int age;
    private String sex;

    /**Omit setter and getter methods*/

Create controller

Complete the conversion of the back-end Java object to the front-end Json string

@ResponseBody

When the POJO object is returned, it is converted to JSON format data by default to respond


Here we need two new things, one is @ ResponseBody and the other is ObjectMapper object

@RestController (recommended)

Unified solution for returning json strings


Use @ RestController directly on the class. In this way, all the methods in it will only return json strings. There is no need to add @ ResponseBody to each one! We usually use it in front and back-end separation development

Run test

Configure Tomcat run

Solve garbled code

@Products property of requestmapping

//produces: Specifies the return type and encoding of the response body
@RequestMapping(value = "/json1",produces = "application/json;charset=utf-8")

If there are many requests in the project, add each one

Spring configuration is specified uniformly (recommended)

We can add a message StringHttpMessageConverter transformation configuration to the configuration file of spring MVC, so we don't have to deal with it every time

<mvc:annotation-driven>
   <mvc:message-converters register-defaults="true">
       <bean class="org.springframework.http.converter.StringHttpMessageConverter">
           <constructor-arg value="UTF-8"/>
       </bean>
       <bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
           <property name="objectMapper">
               <bean class="org.springframework.http.converter.json.Jackson2ObjectMapperFactoryBean">
                   <property name="failOnEmptyBeans" value="false"/>
               </bean>
           </property>
       </bean>
   </mvc:message-converters>
</mvc:annotation-driven>

Test set output

Controller adding method

@RestController
public class UserController {

    //produces: Specifies the return type and encoding of the response body
    @RequestMapping(value = "/json1")
    public String json1() throws JsonProcessingException {
        //Create an object mapper for jackson to parse the data
        ObjectMapper mapper = new ObjectMapper();
        //Create an object
        User user = new User("Qinjiang 1", 3, "male");
        //Parse our object into json format
        String str = mapper.writeValueAsString(user);
        //Due to the @ ResponseBody annotation, str will be converted to json format and returned here; Very convenient
        return str;
    }

    @RequestMapping("/json2")
    public String json2() throws JsonProcessingException {

        //Create an object mapper for jackson to parse the data
        ObjectMapper mapper = new ObjectMapper();
        //Create an object
        User user1 = new User("Qinjiang 1", 3, "male");
        User user2 = new User("Qinjiang 2", 3, "male");
        User user3 = new User("Qinjiang 3", 3, "male");
        User user4 = new User("Qinjiang 4", 3, "male");
        List<User> list = new ArrayList<User>();
        list.add(user1);
        list.add(user2);
        list.add(user3);
        list.add(user4);

        //Parse our object into json format
        String str = mapper.writeValueAsString(list);
        return str;
    }

}

Output time object

Add a new method

The default date format will become a number, which is the number of milliseconds from January 1, 1970 to the current date!

Jackson will convert the time into timestamps by default

Custom time format


Extract as tool class

If you want to use it frequently, it is troublesome. We can encapsulate these codes into a tool class; Let's write it

package com.kuang.utils;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;

import java.text.SimpleDateFormat;

public class JsonUtils {
   
   public static String getJson(Object object) {
       return getJson(object,"yyyy-MM-dd HH:mm:ss");
  }

   public static String getJson(Object object,String dateFormat) {
       ObjectMapper mapper = new ObjectMapper();
       //Do not use time difference
       mapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
       //Custom date format object
       SimpleDateFormat sdf = new SimpleDateFormat(dateFormat);
       //Specify date format
       mapper.setDateFormat(sdf);
       try {
           return mapper.writeValueAsString(object);
      } catch (JsonProcessingException e) {
           e.printStackTrace();
      }
       return null;
  }
}


When we use tool classes, the code is more concise!

Alibaba's fastjason

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

fastjson.jar is a package developed by Alibaba for Java development. It can easily realize the conversion between json objects and JavaBean objects, between JavaBean objects and json strings, and between json objects and json strings. There are many conversion methods to implement json, and the final implementation results are the same.

We only need to master the use of this tool class, and find the corresponding implementation according to the specific business when using it. Like the previous commons IO toolkit, just use it!

fastjson has three main classes


JSON represents the conversion of JSONObject and JSONArray

  • Analysis and use of JSON class source code
  • Carefully observe these methods, mainly to realize the mutual transformation between json objects, json object arrays, javabean objects and json strings.

JSONObject represents a json object

  • JSONObject implements the Map interface. I guess the underlying operation of JSONObject is implemented by Map.
  • JSONObject corresponds to the json object. You can obtain the data in the json object through various forms of get() methods. You can also use methods such as size(), isEmpty() to obtain the number of "key: value" pairs and judge whether they are empty. Its essence is accomplished by implementing the Map interface and calling the methods in the interface.

JSONArray represents an array of json objects

Internally, there are methods in the List interface to complete the operation.

Code example

package com.kuang.controller;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.kuang.pojo.User;

import java.util.ArrayList;
import java.util.List;

public class FastJsonDemo {
   public static void main(String[] args) {
       //Create an object
       User user1 = new User("Qinjiang 1", 3, "male");
       User user2 = new User("Qinjiang 2", 3, "male");
       User user3 = new User("Qinjiang 3", 3, "male");
       User user4 = new User("Qinjiang 4", 3, "male");
       List<User> list = new ArrayList<User>();
       list.add(user1);
       list.add(user2);
       list.add(user3);
       list.add(user4);

       System.out.println("*******Java Object rotation JSON character string*******");
       String str1 = JSON.toJSONString(list);
       System.out.println("JSON.toJSONString(list)==>"+str1);
       String str2 = JSON.toJSONString(user1);
       System.out.println("JSON.toJSONString(user1)==>"+str2);

       System.out.println("\n****** JSON String conversion Java object*******");
       User jp_user1=JSON.parseObject(str2,User.class);
       System.out.println("JSON.parseObject(str2,User.class)==>"+jp_user1);

       System.out.println("\n****** Java Object rotation JSON object ******");
       JSONObject jsonObject1 = (JSONObject) JSON.toJSON(user2);
       System.out.println("(JSONObject) JSON.toJSON(user2)==>"+jsonObject1.getString("name"));

       System.out.println("\n****** JSON Object rotation Java object ******");
       User to_java_user = JSON.toJavaObject(jsonObject1, User.class);
       System.out.println("JSON.toJavaObject(jsonObject1, User.class)==>"+to_java_user);
  }
}

Keywords: JSON Spring mvc

Added by phpSensei on Fri, 29 Oct 2021 00:22:14 +0300