springboot date processing parameters

The picture published by grebmot on Pixabay

Foreword

Recently encountered a pit time parameters in the background in development, it is proposed to find time alone to sort out this problem for a moment;

text

Test Methods

bean code:


public class DateModelNoAnnotation {
    private Integer id;
    private Date receiveDate;
}
    

controller Code:


@RestController
@RequestMapping("/date")
public class DateVerifyController {
    //    方式一
    @PostMapping("/no")
    public String dateUnNoAnnotation(DateModelNoAnnotation dateModelNoAnnotation){
        System.out.println(dateModelNoAnnotation.toString());
        return "SUCCESS";
    }

//    方式二
    @PostMapping("/has")
    public String dateHasAnnotation(@RequestBody DateModelNoAnnotation dateModelNoAnnotation){
        System.out.println(dateModelNoAnnotation.toString());
        return "SUCCESS";
    }
//    方式三
    @GetMapping("/param")
    public String dateParams(@RequestParam("id")Integer id, @RequestParam("receiveDate")Date receiveDate){
        System.out.println("id====="+id);
        System.out.println("receiveDate====="+receiveDate);
        System.out.println("receiveDate====="+receiveDate.getTime());
        return "SUCCESS";
    }
//    方式四
    @GetMapping("/no/param")
    public String dateNoParams(Integer id,Date receiveDate){
        System.out.println("id====="+id);
        System.out.println("receiveDate====="+receiveDate);
        System.out.println("receiveDate====="+receiveDate.getTime());
        return "SUCCESS";
    }
}

Several ways reception parameters (experiment)

  1. By bean receives data (Form mode)
  • This only supports "yyyy / MM / dd HH: mm: ss" time parameter in this format
  1. By bean receives data (JSON format)
  • This only supports "yyyy-MM-dd HH: mm: ss" time parameter in this format
  1. By RequestParam comment
  • This only supports "yyyy / MM / dd HH: mm: ss" time parameter in this format
  1. Not by RequestParam comment
  • This only supports "yyyy / MM / dd HH: mm: ss" time parameter in this format

Several more way to receive parameters received parameter format is not uniform, and sometimes web front-end parameters passed in time for the stamp had to write or modify the interface allowed to make changes to the format;
the back-end to front-end unified return json format data and time format is "yyyy-mM-dd HH: mm: ss"

solution

Prior to the development of a unified interface to receive Time Format

A yyyy / MM / dd HH: mm: ss format

All uniform interface receives a rear end "yyyy / MM / dd HH: mm: ss" or "yyyy / MM / dd" format time parameter

The first: give up the top two way interface

The second: do not abandon the party pick up two, add in the time properties of the bean JsonFormatnotes, for example:


    com.fasterxml.jackson.annotation.JsonFormat;
    
    @JsonFormat(timezone = "GMT+8",pattern = "yyyy/MM/dd HH:mm:ss")
    private Date receiveDate;
    

Advantages: no way give up two interfaces, and unified the Time Format

The drawbacks of using annotation: when pattern = "yyyy / MM / dd", supports only the process "2019/09/03" time parameter format is not supported "2019/09/03 00:00:00", and being given when the time pattern = "yyyy / mM / dd HH:: mm ss", supports only the process "2019/09/03 00:00:00" time parameter format, the remaining error will format;

All received two time formats

  • yyyy-MM-dd HH:mm:ss 格式
  • yyyy-MM-dd format
  • Timestamp
  • yyyy/MM/dd HH:mm:ss 格式
  • yyyy / MM / dd format
note

The wrong way json xml or data processing, such as the use of @RequestBodyannotations bean (i.e. two way)

Tools:


import org.springframework.core.convert.converter.Converter;
import org.springframework.util.StringUtils;
import java.text.SimpleDateFormat;
import java.util.Date;
/**
 * @author gyc
 * @title: DateConverter
 * @projectName app
 * @date 2019/8/1914:36
 * @description: 时间转换类
 */
public class CourseDateConverter implements Converter<String, Date> {
    private static final String dateFormat = "yyyy-MM-dd HH:mm:ss";
    private static final String dateFormata = "yyyy-MM-dd HH:mm:ss";
    private static final String shortDateFormat = "yyyy-MM-dd";
    private static final String shortDateFormata = "yyyy/MM/dd";
    private static final String timeStampFormat = "^\\d+$";
    @Override
    public Date convert(String value) {
        if(StringUtils.isEmpty(value)) {
            return null;
        }
        value = value.trim();
        try {
            if (value.contains("-")) {
                SimpleDateFormat formatter;
                if (value.contains(":")) {
                    //yyyy-MM-dd HH:mm:ss 格式
                    formatter = new SimpleDateFormat(dateFormat);
                } else {
                    //yyyy-MM-dd 格式
                    formatter = new SimpleDateFormat(shortDateFormat);
                }
                return formatter.parse(value);
            } else if (value.matches(timeStampFormat)) {
                //时间戳
                Long lDate = new Long(value);
                return new Date(lDate);
            }else if (value.contains("/")){
                SimpleDateFormat formatter;
                if (value.contains(":")) {
//                    yyyy/MM/dd HH:mm:ss 格式
                    formatter = new SimpleDateFormat(dateFormata);
                } else {
//                    yyyy/MM/dd 格式
                    formatter = new SimpleDateFormat(shortDateFormata);
                }
                return formatter.parse(value);
            }
        } catch (Exception e) {
            throw new RuntimeException(String.format("parser %s to Date fail", value));
        }
        throw new RuntimeException(String.format("parser %s to Date fail", value));
    }
}
The time transformation class to the interface

It describes two ways: using @Component + @PostConstruct or @ControllerAdvice + @InitBinder

The first way:

@Component + @PostConstruct

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.convert.support.GenericConversionService;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.support.ConfigurableWebBindingInitializer;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter;
import javax.annotation.PostConstruct;

@Component
public class WebConfigBeans {
  @Autowired
  private RequestMappingHandlerAdapter handlerAdapter;
  @PostConstruct
  public void initEditableAvlidation() {
    ConfigurableWebBindingInitializer initializer = (ConfigurableWebBindingInitializer)handlerAdapter.getWebBindingInitializer();
    if(initializer.getConversionService()!=null) {
      GenericConversionService genericConversionService = (GenericConversionService)initializer.getConversionService();

      genericConversionService.addConverter(new DateConverterConfig());

    }
  }
}

The second way:

@ControllerAdvice + @InitBinder

import com.aegis.config.converter.DateConverter;
import com.aegis.model.bean.common.JsonResult;
import org.springframework.core.convert.support.GenericConversionService;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.*;
@ControllerAdvice
public class CourseControllerHandler {
    @InitBinder
    public void initBinder(WebDataBinder binder) {
        GenericConversionService genericConversionService = (GenericConversionService) binder.getConversionService();
        if (genericConversionService != null) {
            genericConversionService.addConverter(new CourseDateConverter());
        }
    }
}
At last

The second way the last one method I use

to sum up

This time parameter is still a little big pit, before all targeted treatment, as long as it is not the change; now this can still cope with the error substantially occur;

Guess you like

Origin www.cnblogs.com/guoyuchuan/p/11454529.html