Spring MVC -- JSON(Jackson's use)

Posted by bqheath on Fri, 14 Jan 2022 20:51:19 +0100

Let's first understand what JSON is

  • JSON (JavaScript object notation) is a lightweight data exchange format, which is widely used at present.

  • Data is stored and represented in a text format completely independent of the programming language.

  • The concise and clear hierarchy makes JSON an ideal data exchange language.

  • It is easy for people to read and write, but also easy for machine analysis and generation, and effectively improves the network transmission efficiency.

  • In the JavaScript language, everything is an object. Therefore, any type supported by JavaScript can be represented by JSON, such as string, number, object, array, etc. Look at his requirements and syntax format:

  • Objects are represented as key value pairs, and data is separated by commas

  • Curly braces hold objects and square braces hold arrays

JSON key value pairs are a way to save JavaScript objects, and the writing method is similar to that of JavaScript objects. The key name in the key / value pair combination is written in front and wrapped in double quotation marks "", separated by colon: and then followed by the value:

{"name": "KuangShen"}
{"age": "3"}
{"sex": "male"}

Many people don't know the relationship between JSON and JavaScript objects, even who is who. In fact, it can be understood as follows:

JSON is a string representation of JavaScript objects. It uses text to represent the information of a JS object, which is essentially a string.

var obj = {a: 'Hello', b: 'World'}; //This is an object. Note that the key name can also be wrapped in quotation marks
var json = '{"a": "Hello", "b": "World"}'; //This is a JSON string, which is essentially

JSON and JavaScript objects interoperate

Use JSON The parse () method converts the JSON string into a JS object

var obj = JSON.parse('{"a": "Hello", "b": "World"}');
//The result is {a: 'Hello', b: 'World'}

Use JSON The stringify () method converts a JS object to a JSON string

var json = JSON.stringify({a: 'Hello', b: 'World'});
//The result is' {"a": "Hello", "b": "World"} '
<!DOCTYPE html>
<html lang="en">
<head>
   <meta charset="UTF-8">
   <title>JSON_Qin Jiang</title>
</head>
<body>

<script type="text/javascript">
   //Write a js object
   var user = {
       name:"Qin Jiang",
       age:3,
       sex:"male"
  };
   //Convert js object to json string
   var str = JSON.stringify(user);
   console.log(str);
   
   //Convert json string to js object
   var user2 = JSON.parse(str);
   console.log(user2.age,user2.name,user2.sex);

</script>

</body>
</html>

JSON data returned by Controller

Jackson should be a better json parsing tool at present

Of course, there are more than one tool, such as Alibaba's fastjson and so on.

We use Jackson here. To use Jackson, we need to import its jar package;

<!-- 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>

Configuration required to configure spring MVC

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>

We randomly write a User entity class, and then we write our test Controller;

package com.kuang.pojo;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

//lombok needs to be imported
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {

   private String name;
   private int age;
   private String sex;
   
}

Here we need two new things, one is @ ResponseBody and the other is ObjectMapper object. Let's see the specific usage

Write a Controller;

@Controller
public class UserController {

   @RequestMapping("/json1")
   @ResponseBody
   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;
  }

}

You also need to set the coding format, otherwise it will be garbled
This is implemented through the @ requestmapping products attribute. Modify the following code

@RequestMapping(value = "/json1",produces = "application/json;charset=utf-8")

Unified solution of garbled code

If there are many requests in the project, each one needs to be added, which can be specified uniformly through Spring configuration, so you don't have to deal with them every time!
Add a message StringHttpMessageConverter conversion configuration on the configuration file of spring MVC!

<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>

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 generally use @ RestController in front and back-end separation development, which is very convenient!

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

}

Output time object

Add a new method

@RequestMapping("/json3")
public String json3() throws JsonProcessingException {
  ObjectMapper mapper = new ObjectMapper();
  //Create a time object, Java util. Date
  Date date = new Date();
  //Parse our object into json format
  String str = mapper.writeValueAsString(date);
  return str;
}

Output:

  • 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

Solution: cancel the timestamps format and customize the time format

@RequestMapping("/json4")
public String json4() throws JsonProcessingException {
  ObjectMapper mapper = new ObjectMapper();
  //Without timestamp
  mapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
  //Custom date format object
  SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
  //Specify date format
  mapper.setDateFormat(sdf);
  Date date = new Date();
  String str = mapper.writeValueAsString(date);
  return str;
}

Output:

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!

@RequestMapping("/json5")
public String json5() throws JsonProcessingException {
  Date date = new Date();
  String json = JsonUtils.getJson(date);
  return json;
}

There are also fastjason and so on. There is no example here

Topics: Java JSON