Spring Boot in JSON technology

Spring Boot in JSON technology

Weekdays are generally used in processing JSON Alibaba Fastjson in the project, but later found using the built-in Spring Boot Jackson to complete the JSON serialization and de-serialization operation is also very convenient. Jackson not only can complete a simple serialization and de-serialization operation can achieve complex sequences of personalized and de-serialization operations.

Custom ObjectMapper

We all know that in the Spring @ResponseBody annotation method returns a sequence of objects can be into JSON, such as:

@RequestMapping("getuser")
@ResponseBody
public User getUser() {
  User user = new User();
  user.setUserName("mrbird");
  user.setBirthday(new Date());
  return user;
}

 

User class:

public class User implements Serializable {
  private static final long serialVersionUID = 6222176558369919436L;
   
  private String userName;
  private int age;
  private String password;
  private Date birthday;
  ...
}

 

Access getuser page output:

{"userName":"aaaa","age":0,"password":null,"birthday":1522634892365}

 

The default output time can be seen in the form of a time stamp, if you want to change this default behavior, we can customize a ObjectMapper instead:

import java.text.SimpleDateFormat;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import com.fasterxml.jackson.databind.ObjectMapper;

@Configuration
public class JacksonConfig {
  @Bean
  public ObjectMapper getObjectMapper(){
      ObjectMapper mapper = new ObjectMapper();
      mapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));
      return mapper;
  }
}

 

The above object is configured ObjectMapper acquired, and sets the time format. Visit again getUser , page output:

{"userName":"mrbird","age":0,"password":null,"birthday":"2018-04-02 10:14:24"}

 

Serialization

Jackson by using the mapper writeValueAsString method will serialize Java objects into JSON format string:

@Autowired
ObjectMapper mapper;

@RequestMapping("serialization")
@ResponseBody
public String serialization() {
  try {
      User user = new User();
      user.setUserName("mrbird");
      user.setBirthday(new Date());
      String str = mapper.writeValueAsString(user);
      return str;
  } catch (Exception e) {
      e.printStackTrace();
  }
  return null;
}

 

Deserialization

Use @ResponseBody annotation can target sequence as JSON format string, in addition, also provided Jackson deserialization method.

Tree traversal

When the tree traversal mode, is read into JsonNode JSON object can be read as the operation of JSON as XML DOM. such as:

@Autowired
ObjectMapper mapper;

@RequestMapping("readjsonstring")
@ResponseBody
public String readJsonString() {
  try {
      String json = "{\"name\":\"mrbird\",\"age\":26}";
      JsonNode node = this.mapper.readTree(json);
      String name = node.get("name").asText();
      int age = node.get("age").asInt();
      return name + " " + age;
  } catch (Exception e) {
      e.printStackTrace();
  }
  return null;
}

 

readTree method can accept a string or byte array, file, InputStream like JsonNode return the root node, so you can operate image forming operation traverse JsonNode XML DOM to retrieve data.

Multi-level parsing JSON example:

String json = "{\"name\":\"mrbird\",\"hobby\":{\"first\":\"sleep\",\"second\":\"eat\"}}";;
JsonNode node = this.mapper.readTree(json);
JsonNode hobby = node.get("hobby");
String first = hobby.get("first").asText();

 

Bound object

We can also Java objects and JSON data binding, as shown below:

@Autowired
ObjectMapper mapper;

@RequestMapping("readjsonasobject")
@ResponseBody
public String readJsonAsObject() {
  try {
      String json = "{\"name\":\"mrbird\",\"age\":26}";
      User user = mapper.readValue(json, User.class);
      String name = user.getUserName();
      int age = user.getAge();
      return name + " " + age;
  } catch (Exception e) {
      e.printStackTrace();
  }
  return null;
}

 

Jackson notes

Jackson contains some useful notes:

@JsonProperty

@JsonProperty , acting on the attribute used to specify an alias for JSON Key.

@JsonProperty("bth")
private Date birthday;

 

Visit again getuser page output:

{"userName":"mrbird","age":0,"password":null,"bth":"2018-04-02 10:38:37"}

 

key birthday has been replaced for bth.

@Jsonlgnore

@Jsonlgnore , acting on property that ignore this property.

@JsonIgnore
private String password;

 

Visit again getuser page output:

{"userName":"mrbird","age":0,"bth":"2018-04-02 10:40:45"}

 

password attribute has been ignored.

@JsonIgnoreProperties

@JsonIgnoreProperties , ignoring a set of attributes, at class, such JsonIgnoreProperties ({ "password", "Age"}) .

@JsonIgnoreProperties({ "password", "age" })
public class User implements Serializable {
  ...
}

 

Visit again getuser page output:

{"userName":"mrbird","bth":"2018-04-02 10:45:34"}

 

@JsonFormat

@JsonFormat , a date format, such as:

@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date birthday;

 

@JsonNaming

@JsonNaming , used to specify a named policy, or acting on class attributes. Jackson comes with a variety naming policy, you can implement your own naming strategy, key outputs such converted by the Java naming naming the following line - userName into a user-name.

@JsonNaming(PropertyNamingStrategy.LowerCaseWithUnderscoresStrategy.class)
public class User implements Serializable {
  ...
}

 

Visit again getuser page output:

{"user_name":"mrbird","bth":"2018-04-02 10:52:12"}

 

@JsonSerialize

@JsonSerialize , specify a class defined from serialization. Class must implement JsonSerializer interface code is as follows:

import java.io.IOException;

import com.example.pojo.User;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;

public class UserSerializer extends JsonSerializer<User> {

  @Override
  public void serialize(User user, JsonGenerator generator, SerializerProvider provider)
          throws IOException, JsonProcessingException {
      generator.writeStartObject();
      generator.writeStringField("user-name", user.getUserName());
      generator.writeEndObject();
  }
}

 

We just above the code sequences of the userName attribute, key and the output is a User-name . Use annotations @JsonSerialize to specify the serialization User objects:

@JsonSerialize(using = UserSerializer.class)
public class User implements Serializable {
  ...
}

 

Visit again getuser page output:

{"user-name":"mrbird"}

 

@JsonDeserialize

@JsonDeserialize , custom deserialization with @JsonSerialize , need to achieve JsonDeserializer interface.

import java.io.IOException;

import com.example.pojo.User;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.JsonNode;

public class UserDeserializer extends JsonDeserializer<User> {

  @Override
  public User deserialize(JsonParser parser, DeserializationContext context)
          throws IOException, JsonProcessingException {
      JsonNode node = parser.getCodec().readTree(parser);
      String userName = node.get("user-name").asText();
      User user = new User();
      user.setUserName(userName);
      return user;
  }
}

 

Use annotations @JsonDeserialize to specify the serialization User objects:

@JsonDeserialize (using = UserDeserializer.class)
public class User implements Serializable {
  ...
}

 

test:

@Autowired
ObjectMapper mapper;

@RequestMapping("readjsonasobject")
@ResponseBody
public String readJsonAsObject() {
  try {
      String json = "{\"user-name\":\"mrbird\"}";
      User user = mapper.readValue(json, User.class);
      String name = user.getUserName();
      return name;
  } catch (Exception e) {
      e.printStackTrace();
  }
  return null;
}

 

Access readjsonasobject , page output:

mrbird

 

@JsonView

@JsonView , acting on the class or attribute is used to define a group of sequences. For example, for the User object in some cases only return userName attribute on the line, and in some cases required to return all the property. User objects can thus be defined as follows:

public class User implements Serializable {
  private static final long serialVersionUID = 6222176558369919436L;
   
  public interface UserNameView {};
  public interface AllUserFieldView extends UserNameView {};
   
  @JsonView(UserNameView.class)
  private String userName;
   
  @JsonView(AllUserFieldView.class)
  private int age;
   
  @JsonView(AllUserFieldView.class)
  private String password;
   
  @JsonView(AllUserFieldView.class)
  private Date birthday;
  ...
}

 

User class defines two interfaces, one of userNameView , the other being AllUserFieldView inherited userNameView interface. These interfaces represent the names of the two sequences of groups. UserName attribute used @JsonView (UserNameView.class) , while the remaining properties using the @JsonView (AllUserFieldView.class) .

Spring method allows the Controller @JsonView to specify a group name, the serialized object is serialized only if the properties of this group, as follows:

@JsonView(User.UserNameView.class)
@RequestMapping("getuser")
@ResponseBody
public User getUser() {
  User user = new User();
  user.setUserName("mrbird");
  user.setAge(26);
  user.setPassword("123456");
  user.setBirthday(new Date());
  return user;
}

 

Access getuser page output:

{"userName":"mrbird"}

 

If @JsonView (User.UserNameView.class) replaced @JsonView (User.AllUserFieldView.class) , Output:

{"userName":"mrbird","age":26,"password":"123456","birthday":"2018-04-02 11:24:00"}

 

Because the interface AllUserFieldView inherited interfaces UserNameView so userName will be output.

Set deserialization

In Controller method may be used @RequestBody the JSON submitted automatically mapped to the method parameters, such as:

@RequestMapping("updateuser")
@ResponseBody
public int updateUser(@RequestBody List<User> list){
  return list.size();
}

 

The above method may be acceptable as a JSON request and automatically mapped to the User object:

[{"userName":"mrbird","age":26},{"userName":"scott","age":27}]

 

Spring Boot can automatically identify the User List object contains the class, because of the generic type defined in the process will be retained in the bytecode, so Spring Boot can identify the generic type so that it can properly contain List deserialize .

In some cases, the object set does not include generic definitions, as shown in the following code, and deserialization can not achieve the desired result.

@Autowired
ObjectMapper mapper;

@RequestMapping("customize")
@ResponseBody
public String customize() throws JsonParseException, JsonMappingException, IOException {
    String jsonStr = "[{\"userName\":\"mrbird\",\"age\":26},{\"userName\":\"scott\",\"age\":27}]";
    List<User> list = mapper.readValue(jsonStr, List.class);
    String msg = "";
    for (User user : list) {
        msg += user.getUserName();
    }
    return msg;
}

 

Access Customize , Console throws an exception:

java.lang.ClassCastException: java.util.LinkedHashMap cannot be cast to com.example.pojo.User

 

This is because at run time, generics have been erased (generic method is different from the parameter definitions, will not be erased). In order to provide generic information, Jackson The javaType provided, used to indicate the type of collection, the above method is the following:

@Autowired
ObjectMapper mapper;

@RequestMapping("customize")
@ResponseBody
public String customize() throws JsonParseException, JsonMappingException, IOException {
  String jsonStr = "[{\"userName\":\"mrbird\",\"age\":26},{\"userName\":\"scott\",\"age\":27}]";
  JavaType type = mapper.getTypeFactory().constructParametricType(List.class, User.class);
  List<User> list = mapper.readValue(jsonStr, type);
  String msg = "";
  for (User user : list) {
      msg += user.getUserName();
  }
  return msg;
}

 

Access Customize , page output: mrbirdscott .

Guess you like

Origin www.cnblogs.com/7788IT/p/11626830.html