SpringMVC @ RequestBody Date Type Json Conversion Mode

  • 2021-11-30 00:22:33
  • OfStack

Directory SpringMVC @ RequestBody Date Type Json Conversion Set DateFormat Format through GsonBuilder Take Zero Configuration Framework as an Example Explain the Code Implementation under Zero Configuration Framework @ RequestBody Receives json String and Automatically Converts Date String to java. util. Date 1. Configuration springMVC Can Receive json String 2. @ Controller Class Code 3. Entity Class Object Code 4. DateJsonSerializer Class Code 5. DateJsonDeserializer Class Code

SpringMVC @ RequestBody Date Type Json Conversion

When using Json or Gson to serialize Date type into a string normally, the string in the form of "Dec 5, 2017 8:03:34 PM" is obtained. It is difficult to understand when this format is obtained at the front end, and the readability is very low.

At the same time, deserialization of an Date object with this form of string will also fail, and this process is irreversible. How to serialize an Date object into a string in a specified format, such as a string in the format of "yyyy-MM-dd", is illustrated by using Gson as an example.

For Gson objects, you can use GsonBuilder to instantiate

Format DateFormat through GsonBuilder


Gson gson = new GsonBuilder().setDateFormat("yyyy-MM-dd HH:mm:ss").create();

After this setting, when the Date object is serialized using the toJson (Object obj) method, a string in the format "yyyy-MM-dd HH: mm: ss" is output;

You can also deserialize a string in the format "yyyy-MM-dd HH: mm: ss" into an Date object. Note that when an Date object does not specify "HH: mm: ss", the current time is used to fill in the format length.

The above is the method of serialization and deserialization of Date objects into strings, which is not applicable in SpingMVC framework. The following is the serialization and deserialization of Date in SpringMVC.

In SpringMVC, if the front end passes a string in the form of GET, and the back end wants to deserialize this string into an Date object, the most commonly used one is to register an Formatter object

Take the Zero Configuration Framework as an Example


public class String2DateFormatter implements Formatter<Date> {
    private static final String DATE_TIME_FORMAT = "yyyy-MM-dd HH:mm:ss";
    private static final String DATE_FORMAT = "yyyy-MM-dd";
    @Override
    public String print(Date object, Locale locale) {
        return new GsonBuilder().setDateFormat(DATE_TIME_FORMAT).create().toJson(object);
    }
    @Override
    public Date parse(String text, Locale locale) throws ParseException {
        if (text.length() > 10) {
            return new SimpleDateFormat(DATE_TIME_FORMAT).parse(text);
        } else {
            return new SimpleDateFormat(DATE_FORMAT).parse(text);
        }
    }
}
public class MvcContextConfig extends WebMvcConfigurerAdapter {
    ......
    @Override
    public void addFormatters(FormatterRegistry registry) {
        registry.addFormatter(new String2DateFormatter());
    }
    ......
}

Of course, it can also be configured in the form of configuration files. Please Baidu for specific methods.

When Controller is accepted with an argument of type Date, Formatter is used to deserialize the string into an Date object.

If the front end passes an Json object in the form of POST, and there is an Date attribute inside the object, the front end passes a string, and the back end receives it with a composite object identifying @ RequestBody, Formatter will not work.

At this point, it is the implementation class of HttpMessageConverter that works. Normally there are Jackson or Gson dependencies within the project, and Json can be deserialized into composite objects.

If you rely on Jackson and use HttpMessageConverter of Jackson to deserialize Json, you only support deserialization of attributes of simple data types, not Date types; However, if it is Gson type, it supports deserialization in the format of "yyyy-MM-dd HH: mm: ss". It is determined that the format of "yyyy-MM-dd" is not supported, and other formats are uncertain.

That is to say, relying on Gson, the string in the format of "yyyy-MM-dd HH: mm: ss" at the front end can be deserialized into an Date object, but when the Date object is returned to the front end, the parsed string is still similar to "Dec 5, 2017 8:03:34 PM"

When we use Jackson as the parser for serialization and deserialization of Json objects

Take the code implementation under the framework of zero configuration form as an example


public class MvcContextConfig extends WebMvcConfigurerAdapter {
    ......
    @Override
    public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
        StringHttpMessageConverter stringConverter = new StringHttpMessageConverter(Charset.forName("UTF-8"));
        stringConverter.setWriteAcceptCharset(false);
        converters.add(stringConverter);
        converters.add(new ByteArrayHttpMessageConverter());
        converters.add(new ResourceHttpMessageConverter());
        converters.add(new MappingJackson2XmlHttpMessageConverter());
        // Settings Date Type usage HttpMessageConverter Format after conversion , Or register 1 A GsonHttpMessageConverter, Can directly support string to date conversion 
        // When the date string format is specified, , If the transmitted log format does not conform to the , The error is resolved 
        converters.add(new MappingJackson2HttpMessageConverter(
            new ObjectMapper().setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"))));
        //GsonHttpMessageConverter Not supported yyyy-MM-dd Converts a string of form to a date 
        //converters.add(new GsonHttpMessageConverter());
    }
    ......
}

When we choose to use Jackson as the parser of Json, we need to register an MappingJackson2HttpMessageConverter, expand the internal default objectMapper object, and specify a date formatter. When we specify a specific format, we only support the conversion of this format, and other formats will report errors when converting.

Therefore, when passing the date string, the front end needs to add the default time, such as "2017-12-2 00: 00:00". Although it is a little more work, it can ensure the correct format conversion.

Of course, it is not necessary to "yyyy-MM-dd HH: mm: ss", and other formats are also supported, such as "yyyy-MM-dd", etc. The details can be customized according to the project requirements, and the format of the front-end delivery date string needs to conform to the customized format.

When DateFormat is configured, the object that has the Date property inside is passed to the front end and serialized into a string in this format.

The method of configuring HttpMessageConverter in the form of XML file can be Baidu by itself.

@ RequestBody receives an json string and automatically converts a date string to java. util. Date

1. Configure springMVC to receive json strings


<?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:p="http://www.springframework.org/schema/p"
 xmlns:context="http://www.springframework.org/schema/context"
 xmlns:aop="http://www.springframework.org/schema/aop"
 xmlns:tx="http://www.springframework.org/schema/tx"
 xmlns:mvc="http://www.springframework.org/schema/mvc"
 xsi:schemaLocation="http://www.springframework.org/schema/beans 
 http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
 http://www.springframework.org/schema/context
 http://www.springframework.org/schema/context/spring-context-3.1.xsd
 http://www.springframework.org/schema/tx
 http://www.springframework.org/schema/tx/spring-tx-3.1.xsd
 http://www.springframework.org/schema/aop
 http://www.springframework.org/schema/aop/spring-aop-3.1.xsd
 http://www.springframework.org/schema/mvc
 http://www.springframework.org/schema/mvc/spring-mvc-3.1.xsd">
 <!--  Solve @ResponseBody Return Chinese garbled code , Solve @RequestBody Receive Json Strings are automatically converted to entities, List , Map Format converter  -->
 <bean 
  class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter">
  <property name="messageConverters">
   <list>
    <!-- 
    <bean 
     class="org.springframework.http.converter.StringHttpMessageConverter">
     <property name="supportedMediaTypes">
      <list>
       <value>text/html;charset=UTF-8</value>
      </list>
     </property>
    </bean>
    -->
    <bean 
     class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter">
     <property name="supportedMediaTypes">
      <list>
       <value>application/json;charset=UTF-8</value>
      </list>
     </property>
    </bean>
   </list>
  </property>
 </bean>
 <!--  Scan package, application Spring Annotations of  -->
 <context:component-scan base-package="com.mvc.action"></context:component-scan>
 <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"
  p:viewClass="org.springframework.web.servlet.view.JstlView"
  p:prefix="/"
  p:suffix=".jsp">
 </bean>
 <!-- SpringMVC Customize the interceptor so that SpringMVC Open CORS Support  -->
 <!-- 
 <mvc:interceptors>
  <mvc:interceptor>
   <mvc:mapping path="/*"/>
   <bean class="com.mvc.dao.CorsInterceptor"></bean>
  </mvc:interceptor>
 </mvc:interceptors>
 -->
 <context:annotation-config/>
 <mvc:annotation-driven/>
</beans>

2. @ Controller class code


@RequestMapping(value="/addDicAppUsers.do")
 @ResponseBody
 public boolean addDicAppUsers(@RequestBody DicAppUsersModel dicAppUsersModel)
 {
  if(dicAppUsersService.addDicAppUsers(dicAppUsersModel))
  {
   return true;
  }
  else
  {
   return false;
  }
 }

3. Entity class object code


package com.mvc.model; 
import java.util.Date;
import org.codehaus.jackson.map.annotate.JsonDeserialize;
import org.codehaus.jackson.map.annotate.JsonSerialize;
import com.mvc.imp.DateJsonDeserializer;
import com.mvc.imp.DateJsonSerializer;
 
/**
 *  User view class 
 * @author suyunlong
 *
 */
@SuppressWarnings("serial")
public class DicAppUsersModel implements java.io.Serializable
{
 private long id;
 private String loginid;
 private String loginname;
 private String loginpassword;
 private String loginunitcode;
 private String workplace;
 @JsonSerialize(using=DateJsonSerializer.class)
 @JsonDeserialize(using=DateJsonDeserializer.class)
 private Date addtime;
 private long sourceid;
 @JsonSerialize(using=DateJsonSerializer.class)
 @JsonDeserialize(using=DateJsonDeserializer.class)
 private Date createdate;
 public DicAppUsersModel() {
  super();
 }
 public DicAppUsersModel(long id, String loginid, String loginname,
   String loginpassword, String loginunitcode, String workplace,
   Date addtime, long sourceid, Date createdate) {
  super();
  this.id = id;
  this.loginid = loginid;
  this.loginname = loginname;
  this.loginpassword = loginpassword;
  this.loginunitcode = loginunitcode;
  this.workplace = workplace;
  this.addtime = addtime;
  this.sourceid = sourceid;
  this.createdate = createdate;
 }
 public long getId() {
  return id;
 }
 public void setId(long id) {
  this.id = id;
 }
 public String getLoginid() {
  return loginid;
 }
 public void setLoginid(String loginid) {
  this.loginid = loginid;
 }
 public String getLoginname() {
  return loginname;
 }
 public void setLoginname(String loginname) {
  this.loginname = loginname;
 }
 public String getLoginpassword() {
  return loginpassword;
 }
 public void setLoginpassword(String loginpassword) {
  this.loginpassword = loginpassword;
 }
 public String getLoginunitcode() {
  return loginunitcode;
 }
 public void setLoginunitcode(String loginunitcode) {
  this.loginunitcode = loginunitcode;
 }
 public String getWorkplace() {
  return workplace;
 }
 public void setWorkplace(String workplace) {
  this.workplace = workplace;
 }
 public Date getAddtime() {
  return addtime;
 }
 public void setAddtime(Date addtime) {
  this.addtime = addtime;
 }
 public long getSourceid() {
  return sourceid;
 }
 public void setSourceid(long sourceid) {
  this.sourceid = sourceid;
 }
 public Date getCreatedate() {
  return createdate;
 }
 public void setCreatedate(Date createdate) {
  this.createdate = createdate;
 }
}

4. DateJsonSerializer class code


package com.mvc.imp; 
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import org.codehaus.jackson.JsonGenerator;
import org.codehaus.jackson.JsonProcessingException;
import org.codehaus.jackson.map.JsonSerializer;
import org.codehaus.jackson.map.SerializerProvider;
 
public class DateJsonSerializer extends JsonSerializer<Date>
{
 public static final SimpleDateFormat format=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
 public void serialize(Date date,JsonGenerator jsonGenerator,SerializerProvider serializerProvider)
   throws IOException,JsonProcessingException 
 {
  jsonGenerator.writeString(format.format(date));  
    }  
}

5. DateJsonDeserializer class code


package com.mvc.imp; 
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import org.codehaus.jackson.JsonParser;
import org.codehaus.jackson.JsonProcessingException;
import org.codehaus.jackson.map.DeserializationContext;
import org.codehaus.jackson.map.JsonDeserializer;
 
public class DateJsonDeserializer extends JsonDeserializer<Date>
{
 public static final SimpleDateFormat format=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
 public Date deserialize(JsonParser jsonParser,DeserializationContext deserializationContext)
   throws IOException,JsonProcessingException
 {
  try
  {
   return format.parse(jsonParser.getText());
  }
  catch(Exception e)
  {
   System.out.println(e.getMessage());
   throw new RuntimeException(e);
  } 
 }
}

In this way, you can convert the received json date string to Date. Later, you can save the date data directly through Date type.


Related articles: