background

1.1 problem

Spring Boot When dealing with serialization and deserialization of objects , By default, the built-in JackSon To configure . Use the frame default , We usually face the following problems :
  1. Date Return date format ( It is not recommended to use Date, But old projects should be compatible ), with T, Such as 2018-05-15T24:59:59:
  1. LocalDate The returned Date object is an array ( The framework inherits WebMvcConfigurationSupport);
  1. LocalDateTime Time conversion failed ;
  1. Defines the date type , Such as LocalDate, Front end docking (post/get), If you pass in a date string ("2022-05-05"), Will be submitted to the String Convert to LocalDate Failure ;
  1. return long Type data , front end js There is accuracy problem , Conversion required ;
  1. Some special objects need special business transformation , Such as encryption and decryption ;

1.2 Solution

For the above problems , There are many solutions . Because the underlying framework uniformly configures different implementation modes of interception classes , There will still be differences , This article mainly explains that in different configuration scenarios , Customize Jackson Some considerations for configuration and reasons for differentiation :
In order to solve special objects ( Such as date ) Serialization and deserialization of , Common schemes are as follows :
  1. For a particular specific object , Use annotations on objects , Such as :
@JsonSerialize(using= JsonDateSerializer.class)
private Date taskEndTime; @ApiModelProperty(value = " Inspection date ")
@JsonFormat(pattern = "yyyy-MM-dd")
private LocalDate checkDate;
  1. Re actualize WebMvcConfigurer Interface , Customize JackSon To configure .
  1. Inherit WebMvcConfigurationSupport class , Customize JackSon To configure .

1.3 In particular

  • programme 1 The pattern of , Annotate the corresponding variable , It can solve the problem , But the code is seriously duplicated , Not elegant ;
  • Realization WebMvcConfigurer Interface and inheritance WebMvcConfigurationSupport class , yes Spring Boot It provides two modes for developers to make unified global configuration classes , Notice the difference between the two modes , See the following chapters for details ( Two different modes , Improper use , The configuration will not take effect );

Customize Jackson

  1. JackSon Configuration instructions

Customize a Jackson Configuration information , Need to know Jackson Some configuration standards for , Such as :

// Ignored in deserialization  json  There is but  Java  Object does not exist 

mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES,

false);

// The date format defaults to  yyyy-MM-dd'T'HH:mm:ss.SSSZ , For example, if a class has private Date date; This date attribute , Serialized as :{"date" : 1413800730456}, If not true, Then for {"date" : "2014-10-20T10:26:06.604+0000"}

mapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS,false);

// Ignore the value... When serializing  null  Properties of 

mapper.setSerializationInclusion(Include.NON_NULL);

// Ignore properties with default values 

mapper.setDefaultPropertyInclusion(Include.NON_DEFAULT);

//  Beautify the output 

mapper.enable(SerializationFeature.INDENT_OUTPUT);

//  Allow serialization of empty POJO class 

// ( Otherwise, an exception will be thrown )

mapper.disable(SerializationFeature.FAIL_ON_EMPTY_BEANS);

//  hold java.util.Date, Calendar Output to digital ( Time stamp )

mapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);

//  Don't throw an exception when you encounter an unknown property 

mapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);

//  mandatory JSON  An empty string ("") Convert to null The object is worth :

mapper.enable(DeserializationFeature.ACCEPT_EMPTY_STRING_AS_NULL_OBJECT);

//  stay JSON It is allowed that C/C++  Comments on styles ( Nonstandard , Default disabled )

mapper.configure(JsonParser.Feature.ALLOW_COMMENTS, true);

//  Allow field names without quotes ( Nonstandard )

mapper.configure(JsonParser.Feature.ALLOW_UNQUOTED_FIELD_NAMES, true);

//  Single quotation marks are allowed ( Nonstandard )

mapper.configure(JsonParser.Feature.ALLOW_SINGLE_QUOTES, true);

//  Mandatory escape is not ASCII character 

mapper.configure(JsonGenerator.Feature.ESCAPE_NON_ASCII, true);

//  Wrap the content into a JSON attribute , The attribute name is from @JsonRootName Annotation assignment 

mapper.configure(SerializationFeature.WRAP_ROOT_VALUE, true);

// Serializing enumerations starts with toString() To output , Default false, That is to say, by default name() To output 

mapper.configure(SerializationFeature.WRITE_ENUMS_USING_TO_STRING,true);

// serialize Map When the key Sort operations , Default false

mapper.configure(SerializationFeature.ORDER_MAP_ENTRIES_BY_KEYS,true);

// serialize char[] Time and space json Array output , Default false

mapper.configure(SerializationFeature.WRITE_CHAR_ARRAYS_AS_JSON_ARRAYS,true);

// serialize BigDecimal Between the output of the original number or scientific counting , Default false, That is to say, whether to use toPlainString() Output by scientific counting 

mapper.configure(SerializationFeature.WRITE_CHAR_ARRAYS_AS_JSON_ARRAYS,true);
  1. Realization WebMvcConfigurer Interface

Rewrite a ObjectMapper, Replace the system default bean, You can implement the interface in post Request mode , Object serialization and deserialization define the configuration information .
Rewrite Jackson after , It doesn't deal with get When asked , Serialization of special objects such as dates ; in the light of get request , Write the serialization rule function of the object , By implementing addFormatters() Interface , Scalable support ;

To write LocalDateTime Conversion function

/**
* java 8 LocalDateTime converter
*
* @author wangling
*/
public class LocalDateTimeFormatter implements Formatter<LocalDateTime> {
private final DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); @Override
public LocalDateTime parse(String text, Locale locale) throws ParseException {
return LocalDateTime.parse(text, formatter);
} @Override
public String print(LocalDateTime object, Locale locale) {
return formatter.format(object);
}
}

To write LocalDate Conversion function

/**
* java 8 localDate converter
*
* @author wangling
*/
public class LocalDateFormatter implements Formatter<LocalDate> {
private final DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd"); @Override
public LocalDate parse(String text, Locale locale) throws ParseException {
return LocalDate.parse(text, formatter);
} @Override
public String print(LocalDate object, Locale locale) {
return formatter.format(object);
}
}

To write Jackson To configure

Write a custom ObjectMapper bean object , Set priority to replace default bean.
/**
* Project global configuration class
*
* @author wangling
* @date 2022/06/10
*/
@Configuration
@RequiredArgsConstructor
public class WebConfig implements WebMvcConfigurer { @Override
public void addFormatters(FormatterRegistry registry) {
registry.addFormatterForFieldType(LocalDate.class, new LocalDateFormatter());
registry.addFormatterForFieldType(LocalDateTime.class, new LocalDateTimeFormatter());
} @Bean
@Primary
public ObjectMapper ObjectMapper() {
String dateTimeFormat = "yyyy-MM-dd HH:mm:ss";
String dateFormat = "yyyy-MM-dd";
String timeFormat = "HH:mm:ss";
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
JavaTimeModule javaTimeModule = new JavaTimeModule();
// serialize
javaTimeModule.addSerializer(
LocalDateTime.class,
new LocalDateTimeSerializer(DateTimeFormatter.ofPattern(dateTimeFormat)));
javaTimeModule.addSerializer(
LocalDate.class,
new LocalDateSerializer(DateTimeFormatter.ofPattern(dateFormat)));
javaTimeModule.addSerializer(
LocalTime.class,
new LocalTimeSerializer(DateTimeFormatter.ofPattern(timeFormat)));
javaTimeModule.addSerializer(
Date.class,
new DateSerializer(false, new SimpleDateFormat(dateTimeFormat))); // Deserialization
javaTimeModule.addDeserializer(
LocalDateTime.class,
new LocalDateTimeDeserializer(DateTimeFormatter.ofPattern(dateTimeFormat)));
javaTimeModule.addDeserializer(
LocalDate.class,
new LocalDateDeserializer(DateTimeFormatter.ofPattern(dateFormat)));
javaTimeModule.addDeserializer(
LocalTime.class,
new LocalTimeDeserializer(DateTimeFormatter.ofPattern(timeFormat)));
javaTimeModule.addDeserializer(Date.class, new DateDeserializers.DateDeserializer() {
@SneakyThrows
@Override
public Date deserialize(JsonParser jsonParser, DeserializationContext dc) {
String text = jsonParser.getText().trim();
SimpleDateFormat sdf = new SimpleDateFormat(dateTimeFormat);
return sdf.parse(text);
}
});
javaTimeModule.addSerializer(Long.class, ToStringSerializer.instance);
javaTimeModule.addSerializer(BigInteger.class, ToStringSerializer.instance);
objectMapper.registerModule(javaTimeModule);
return objectMapper;
}
}
  1. WebMvcConfigurationSupport class

To write Jackson To configure

Rewrite Jackson after , It doesn't deal with get When asked , Serialization of special objects such as dates ; in the light of get request , Write the serialization rule function of the object , By implementing addFormatters() Interface , Scalable support ;
Write custom configuration Jackson Information , Need to rewrite extendMessageConverters Method . Specific technical details , Please refer to the documentation 《 Spring Boot Realization WebMvcConfigurationSupport Lead to custom JSON The time return format does not take effect 》

/**
* Project global configuration class
*
* @author wangling
* @date 2022/06/10
*/
@Configuration
public class MvcInterceptorConfig extends WebMvcConfigurationSupport { @Override
protected void addFormatters(FormatterRegistry registry) {
// be used for get Global format date conversion
registry.addFormatterForFieldType(LocalDate.class, new LocalDateFormatter());
registry.addFormatterForFieldType(LocalDateTime.class, new LocalDateTimeFormatter());
} @Override
protected void extendMessageConverters(List<HttpMessageConverter<?>> converters) {
// Replace the frame default JackSon To configure be used for post Global format date conversion ,long Turn the string
MappingJackson2HttpMessageConverter jackson2HttpMessageConverter =
new MappingJackson2HttpMessageConverter();
jackson2HttpMessageConverter.setObjectMapper(ObjectMapper());
// Based on order , First, execute the customized
converters.add(0, jackson2HttpMessageConverter);
} private ObjectMapper ObjectMapper() {
String dateTimeFormat = "yyyy-MM-dd HH:mm:ss";
String dateFormat = "yyyy-MM-dd";
String timeFormat = "HH:mm:ss";
ObjectMapper objectMapper = new ObjectMapper();
// Ignore empty Bean turn json Error of
objectMapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
// Ignore stay json There is... In the string , But there is no corresponding attribute in the object , Prevent mistakes .
// for example json There are more fields in the data , There is no such field in the object . If you set true, Throw an exception , Because the field does not correspond to ;false Then ignore the extra fields , The default value is null, Deserialize other fields successfully
objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
JavaTimeModule javaTimeModule = new JavaTimeModule();
// serialize
javaTimeModule.addSerializer(
LocalDateTime.class,
new LocalDateTimeSerializer(DateTimeFormatter.ofPattern(dateTimeFormat)));
javaTimeModule.addSerializer(
LocalDate.class,
new LocalDateSerializer(DateTimeFormatter.ofPattern(dateFormat)));
javaTimeModule.addSerializer(
LocalTime.class,
new LocalTimeSerializer(DateTimeFormatter.ofPattern(timeFormat)));
javaTimeModule.addSerializer(
Date.class,
new DateSerializer(false, new SimpleDateFormat(dateTimeFormat))); // Deserialization
javaTimeModule.addDeserializer(
LocalDateTime.class,
new LocalDateTimeDeserializer(DateTimeFormatter.ofPattern(dateTimeFormat)));
javaTimeModule.addDeserializer(
LocalDate.class,
new LocalDateDeserializer(DateTimeFormatter.ofPattern(dateFormat)));
javaTimeModule.addDeserializer(
LocalTime.class,
new LocalTimeDeserializer(DateTimeFormatter.ofPattern(timeFormat)));
javaTimeModule.addDeserializer(Date.class, new DateDeserializers.DateDeserializer() {
@SneakyThrows
@Override
public Date deserialize(JsonParser jsonParser, DeserializationContext dc) {
String text = jsonParser.getText().trim();
SimpleDateFormat sdf = new SimpleDateFormat(dateTimeFormat);
return sdf.parse(text);
}
});
javaTimeModule.addSerializer(Long.class, ToStringSerializer.instance);
javaTimeModule.addSerializer(BigInteger.class, ToStringSerializer.instance);
objectMapper.registerModule(javaTimeModule);
return objectMapper;
}
}

WebMvcConfigurer And WebMvcConfigurationSupport Related knowledge

  1. Basic knowledge points

Spring Of WebMvcConfigurer Interfaces provide many ways for developers to customize SpringMVC Configuration of .
WebMvcConfigurationSupport implements ApplicationContextAware, ServletContextAware. More and more customized configurations are supported ,WebMvcConfigurerAdapter There are ways , This class also has . This kind of annotation content is translated : This is to provide MVC Java config The main classes configured behind . Usually by putting @EnableWebMvc Added to the application @Configuration Class . Another more advanced option is to extend directly from this class and rewrite methods as needed , Remember to add subclasses @Configuration, Rewrite with @Bean We should also add @Bean.
  1. Precautions for use

          Reference documents : 《 Reason for interception failure 》
  1. Realization WebMvcConfigurer: Will not cover WebMvcAutoConfiguration Configuration of
  1. Realization WebMvcConfigurer+ annotation @EnableWebMvc: Will be covered WebMvcAutoConfiguration Configuration of
  1. Inherit WebMvcConfigurationSupport: Will be covered WebMvcAutoConfiguration Configuration of
  1. Inherit DelegatingWebMvcConfiguration: Will be covered WebMvcAutoConfiguration Configuration of
  1. Recommended use mode

  1. It's not necessary , It's best to avoid WebMvcConfigurer,WebMvcConfigurationSupport Use... Simultaneously in a project ;
  1. Intercept configuration for security , Recommended for the project WebMvcConfigurer Interface for global configuration ;
  1. date , It is suggested to use LocalDate, Replace historical Date data type ;
 

A detailed explanation JackSon More articles on configuration information

  1. A detailed explanation Hexo+Github Xiaobai builds a station

    author : Cynical Coder Time :2020-03-08 explain : This is an original article , Can't reprint without permission , Please contact the author before reprinting A detailed explanation Hexo+Github Xiaobai builds a station Preface GitHub It's a project for open source and private software ...

  2. log4j.properties Detailed explanation and configuration steps ( turn )

    Looking for articles , For reference from  log4j.properties Detailed explanation and configuration steps One .log4j.properties Use of 1. Type of output level ERROR.WARN.INFO.DEBUGERROR ...

  3. C3P0 Connection pool details and configuration

    C3P0 Connection pool details and configuration I use C3P0 Of jar Bag is :c3p0-0.9.1.jar <bean id = "dataSource" class = "com.m ...

  4. rsync Introduction and parameter explanation of , Configuration steps , Working mode introduction

    rsync Introduction and parameter explanation of , Configuration steps , Working mode introduction rsync It's a class unix Data image backup tool under the system . It's a fast incremental backup . Full backup tools . Sync Remote synchronization is possible , Support local replication , Or with others SSH.rsync Lord ...

  5. Disk partition alignment details and configuration – Linux piece

    In the previous article < Disk partition alignment details and configuration – Windows piece > in , I introduced the function of disk partition alignment and its application to MBR and GPT Configuration of two disk types of , as well as Windows How to set the disk partition of the platform . Article as ...

  6. tomcat start-up nio,apr Details and configuration

    tomcat start-up nio,apr Details and configuration Preface Before the beginning of the text , We first in idea Look at the startup information in the tool , By the way, let's see the basic information about the startup Insert the picture description here, and you can see that the information is tomcat Version operating system version java edition ...

  7. A detailed explanation Linux The article "common monitoring work of the system" is explained in detail Linux Common monitoring tools for the system (top,htop,iotop,iftop) have (top,htop,iotop,iftop)

    A detailed explanation Linux Common monitoring tools for the system (top,htop,iotop,iftop)     General Statement This article mainly records Linux Some common system monitoring tools on the system , Very easy to use . It's just that sharpening a knife doesn't miss cutting wood , Take some time. ...

  8. nginx Of gzip Module details and configuration

    Source of the article Operation and Maintenance Association :nginx Of gzip Module details and configuration   1.gzip Module function gzip This module must be opened in both test and production environments , This module can efficiently integrate the content of the page , Whether it's html perhaps css.j ...

  9. SpringBoot Profile Use detailed and configuration source code analysis

    In the process of practice, we often encounter situations where different environments need different configuration files , If you change the configuration file or repackage every time, it will be troublesome ,Spring Boot This provides Profile Configuration to solve this problem . Profile ...

  10. Log4j2 Detailed explanation ——XML Configuration details

    Log4j2 Detailed explanation --XML Configuration details Found a very detailed article link https://www.jianshu.com/p/bfc182ee33db

Random recommendation

  1. JavaScript Authoritative design --JavaScript object ( Brief study notes 8 )

    1. Properties of properties An attribute contains a name and 4 A feature .4 A feature : value , writability , Enumerability , Configurability   2. Three properties of an object One : Prototype attribute To test whether an object is the prototype of another object , Use isPrototypeOf( ...

  2. PHP-Redis Extended user manual ( Four )

    /* Add one or more value To an unordered set , If value It has become set in , Then return to false * @param key set name * @param value * ... * @return in ...

  3. Merge 2 individual dll Become a , Benefits, you know

    Step one : Download Microsoft tools first  ilmerge.exe Address :http://www.microsoft.com/en-us/download/details.aspx?id=17630 Step two : Once installed ...

  4. MySQL Study note 2

    Ø function function Function is more important , Generally used in select Query statements and where After the conditional statement . According to the result returned by the function , Can be divided into : Multiline and single line functions : The so-called single line function is to calculate each data independently , however ...

  5. Spring: DispacherServlet and ContextLoaderListener Medium WebApplicationContext The relationship between

    stay Web Containers ( such as Tomcat) Middle configuration Spring when , You may be used to web.xml The following configuration code in the file : <context-param> <param-name>cont ...

  6. CH Round #53 -【Nescaf&#233; 32】 A cup of NOIP Simulation game

    A.GCD Path http://ch.ezoj.tk/contest/CH%20Round%20%2353%20-%E3%80%90Nescaf%C3%A9%2032%E3%80%91%E6%9D ...

  7. SharePoint SPHierarchyDataSourceControl+SPTreeView

    Use today SPHierarchyDataSourceControl and SPTreeView To display SharePoint In the process of document library hierarchy , I found that I have been reporting the following errors : The target 'ctl00$c ...

  8. Oracle Detailed explanation of cursor

    This article from the : http://www.cnblogs.com/sc-xx/archive/2011/12/03/2275084.html -- declare cursor :CURSOR cursor_name IS sel ...

  9. python+flask: Realization POST Interface functions

    1. Installation is required first python and flask, This is a must . 2. What we implement here is a POST Simple interface of function . from flask import Flask, request, jsonify imp ...

  10. Salesforce Objects and fields for

    object Salesforce Many functions are provided by default , Can be used to sell . market development . Customer service, etc . To achieve these functions ,Salesforce Provides a series of standard objects , such as " Customer "(Account).&quo ...