Spring Boot practice--The front-end string date is automatically converted to the back-end date type.

basic introduction

When developing in the front-end and back-end: the date format will turn around, which is very troublesome. A rough summary is as follows:

1: The backend returns the object: You can use the HttpMessageConverter provided by spring to automatically convert, there are many implementations.

For example: two implementations of AbstractJackson2HttpMessageConverter: the first two below

  • MappingJackson2XmlHttpMessageConverter: xml parser
  • MappingJackson2HttpMessageConverter: JSON parser. system default.
  • GsonHttpMessageConverter JSON parser 
  • FastHttpMessageConverter JSON Parser

2: Backend receiving object: There are two kinds:

  •  Serialize the passed value as a JSON object. It can be automatically converted to the corresponding date format in the backend.
  •  Form date string: It cannot be automatically recognized, which is the problem solved by this blog.

 

Problem restoration: When the frontend submits the date format data to the backend and saves it, it has been transmitted in the form of a string. If the backend accepts the data type, a 400 format error will be reported. Refer to the online blog and record your own practice. At this time, you need to deal with it: There are four ways:

One: Field String type conversion

The 0th (lowest way): The background is received with a String type field, and if you need to use it, replace it with date.

二:@DateTimeFormat

Type 1: Use @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") to annotate the entity field. 
The advantage of this method is that it can flexibly define the received type. The 
disadvantage is obvious: it cannot be globally unified Processing, it is too troublesome to annotate each field that needs to be converted

Three: The base class @InitBinder writes a global conversion date

Type 2: Write a BaseController, each controller that needs to be processed inherits this BaseController, and uses @InitBinder in BaseController to write a global conversion date method:

/**
	 * form表单提交 Date类型数据绑定
	 * <功能详细描述>
	 * @param binder
	 * @see [类、类#方法、类#成员]
	 */
@InitBinder  
public void initBinder(WebDataBinder binder) {  
	    SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");  
	    dateFormat.setLenient(false);  
	    binder.registerCustomEditor(Date.class, new CustomDateEditor(dateFormat, true));  
}

@InitBinder
public void initBinder(ServletRequestDataBinder binder,WebRequest request) {
	//转换日期格式
    DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    //注册自定义的编辑器
    binder.registerCustomEditor(Date.class, new CustomDateEditor(dateFormat, true));        
}

The advantage of this method is that it can be handled globally and uniformly, and you don't need to pay attention to the date fields that need to be converted 
. -dd HH:mm:ss", 
if the date format from different pages in the front desk is different, it will be difficult to handle

Four: Customize DateConverterConfig to rewrite the convert method

Implement the Converter provided by spring and rewrite the convert method inside:

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import org.springframework.core.convert.converter.Converter;
import org.springframework.stereotype.Component;

/**
 * 全局handler前日期统一处理
 * @author zhanghang
 * @date 2018/1/11
 */
@Component
public class DateConverterConfig implements Converter<String, Date> {

    private static final List<String> formarts = new ArrayList<>(4);
    static{
        formarts.add("yyyy-MM");
        formarts.add("yyyy-MM-dd");
        formarts.add("yyyy-MM-dd hh:mm");
        formarts.add("yyyy-MM-dd hh:mm:ss");
    }

    @Override
    public Date convert(String source) {
        String value = source.trim();
        if ("".equals(value)) {
            return null;
        }
        if(source.matches("^\\d{4}-\\d{1,2}$")){
            return parseDate(source, formarts.get(0));
        }else if(source.matches("^\\d{4}-\\d{1,2}-\\d{1,2}$")){
            return parseDate(source, formarts.get(1));
        }else if(source.matches("^\\d{4}-\\d{1,2}-\\d{1,2} {1}\\d{1,2}:\\d{1,2}$")){
            return parseDate(source, formarts.get(2));
        }else if(source.matches("^\\d{4}-\\d{1,2}-\\d{1,2} {1}\\d{1,2}:\\d{1,2}:\\d{1,2}$")){
            return parseDate(source, formarts.get(3));
        }else {
            throw new IllegalArgumentException("Invalid boolean value '" + source + "'");
        }
    }

    /**
     * 格式化日期
     * @param dateStr String 字符型日期
     * @param format String 格式
     * @return Date 日期
     */
    public  Date parseDate(String dateStr, String format) {
        Date date=null;
        try {
            DateFormat dateFormat = new SimpleDateFormat(format);
            date = dateFormat.parse(dateStr);
        } catch (Exception e) {

        }
        return date;
    }

}

I am here in the springboot project to hand over this class to the spring container through the @Component annotation. If the springmvc project also needs to register this class in the xml configuration file, the 
advantages are obvious: flexible enough to customize the date in any format in the static code block, In the rewritten method, it is enough to match the corresponding regular expression, and it can also be processed globally, taking into account the first and second types, perfect!

 

Four: Non-BOOT way: global date type converter and configuration

package com.spinach.core.web;

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;

import org.springframework.beans.propertyeditors.CustomDateEditor;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.support.WebBindingInitializer;
import org.springframework.web.context.request.WebRequest;

public class CustomDateEdtor implements WebBindingInitializer {

    
    public void initBinder(WebDataBinder binder, WebRequest request) {
        // TODO Auto-generated method stub
        //转换日期格式
        DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        
        binder.registerCustomEditor(Date.class, new CustomDateEditor(dateFormat, true));
    }

}


And configure it in the spingMVC configuration file

<bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
      <property name="webBindingInitializer">    
          <bean class="com.spinach.core.web.CustomDateEdtor"/>
      </property>
</bean>

   

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325339731&siteId=291194637