基於springboot處理date引數過程解析
這篇文章主要介紹了基於springboot處理date引數過程解析,文中通過示例程式碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
前言
最近在後臺開發中遇到了時間引數的坑,就單獨把這個問題提出來找時間整理了一下;
正文
測試方法
bean程式碼:
public class DateModelNoAnnotation { private Integer id; private Date receiveDate; }
controller程式碼:
@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"; } }
接收引數的幾種方式(實驗)
- 通過bean來接收資料(表單方式)
- 這種方式只支援"yyyy/MM/dd HH:mm:ss"這種格式的time引數
- 通過bean來接收資料(json格式)
- 這種方式只支援"yyyy-MM-dd HH:mm:ss"這種格式的time引數
- 通過RequestParam註解
- 這種方式只支援"yyyy/MM/dd HH:mm:ss"這種格式的time引數
- 不通過RequestParam註解
- 這種方式只支援"yyyy/MM/dd HH:mm:ss"這種格式的time引數
以上幾種接收引數的方式接收的引數格式並不統一,而且有時候web前端傳入的時間引數為時間戳,還得寫修改介面或者讓其自己修改格式;
後端給前端統一返回json格式的資料,且時間格式為"yyyy-MM-dd HH:mm:ss"
解決方案
開發之前統一時間介面接收的時間格式
一 yyyy/MM/dd HH:mm:ss 格式
後端所有介面統一接收"yyyy/MM/dd HH:mm:ss"或"yyyy/MM/dd"格式時間引數
第一種: 捨棄上邊的方式二的介面
第二種:不捨棄方拾二,在bean的時間屬性上新增JsonFormat註解,例如:
com.fasterxml.jackson.annotation.JsonFormat; @JsonFormat(timezone = "GMT+8",pattern = "yyyy/MM/dd HH:mm:ss") private Date receiveDate;
優勢: 不捨棄方式二介面,且統一了時間格式
使用該註解的弊端: 當pattern="yyyy/MM/dd" 時, 只支援處理“2019/09/03"格式時間引數,不支援“2019/09/03 00:00:00”,且會報錯,當pattern="yyyy/MM/dd HH:mm:ss"時,只支援處理“2019/09/03 00:00:00"格式時間引數,其餘格式均會報錯;
二 接收所有時間格式
- yyyy-MM-dd HH:mm:ss 格式
- yyyy-MM-dd 格式
- 時間戳
- yyyy/MM/dd HH:mm:ss 格式
- yyyy/MM/dd 格式
注意
該方式不對json或xml的資料處理,比如使用@RequestBody註解的bean(也就是方式二)
工具類:
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)); } }
將時間轉換類應用到介面上
介紹兩種方式:使用@Component + @PostConstruct或@ControllerAdvice + @InitBinder
第一種方式:
@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()); } } }
第二種方式:
@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()); } } }
最後
我使用的最後的一種方法的第二種方式
總結
時間引數這個坑還是有點大的,之前都是針對性的處理,只要一變化就沒法了;現在這個還是可以應付基本上會出現的錯誤了;
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支援我們。