基于springboot處理date參數(shù)過(guò)程解析
這篇文章主要介紹了基于springboot處理date參數(shù)過(guò)程解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
前言
最近在后臺(tái)開(kāi)發(fā)中遇到了時(shí)間參數(shù)的坑,就單獨(dú)把這個(gè)問(wèn)題提出來(lái)找時(shí)間整理了一下;
正文
測(cè)試方法
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"; } }
接收參數(shù)的幾種方式(實(shí)驗(yàn))
- 通過(guò)bean來(lái)接收數(shù)據(jù)(表單方式)
- 這種方式只支持"yyyy/MM/dd HH:mm:ss"這種格式的time參數(shù)
- 通過(guò)bean來(lái)接收數(shù)據(jù)(json格式)
- 這種方式只支持"yyyy-MM-dd HH:mm:ss"這種格式的time參數(shù)
- 通過(guò)RequestParam注解
- 這種方式只支持"yyyy/MM/dd HH:mm:ss"這種格式的time參數(shù)
- 不通過(guò)RequestParam注解
- 這種方式只支持"yyyy/MM/dd HH:mm:ss"這種格式的time參數(shù)
以上幾種接收參數(shù)的方式接收的參數(shù)格式并不統(tǒng)一,而且有時(shí)候web前端傳入的時(shí)間參數(shù)為時(shí)間戳,還得寫(xiě)修改接口或者讓其自己修改格式;
后端給前端統(tǒng)一返回json格式的數(shù)據(jù),且時(shí)間格式為"yyyy-MM-dd HH:mm:ss"
解決方案
開(kāi)發(fā)之前統(tǒng)一時(shí)間接口接收的時(shí)間格式
一 yyyy/MM/dd HH:mm:ss 格式
后端所有接口統(tǒng)一接收"yyyy/MM/dd HH:mm:ss"或"yyyy/MM/dd"格式時(shí)間參數(shù)
第一種: 舍棄上邊的方式二的接口
第二種:不舍棄方拾二,在bean的時(shí)間屬性上添加JsonFormat注解,例如:
com.fasterxml.jackson.annotation.JsonFormat; @JsonFormat(timezone = "GMT+8",pattern = "yyyy/MM/dd HH:mm:ss") private Date receiveDate;
優(yōu)勢(shì): 不舍棄方式二接口,且統(tǒng)一了時(shí)間格式
使用該注解的弊端: 當(dāng)pattern="yyyy/MM/dd" 時(shí), 只支持處理“2019/09/03"格式時(shí)間參數(shù),不支持“2019/09/03 00:00:00”,且會(huì)報(bào)錯(cuò),當(dāng)pattern="yyyy/MM/dd HH:mm:ss"時(shí),只支持處理“2019/09/03 00:00:00"格式時(shí)間參數(shù),其余格式均會(huì)報(bào)錯(cuò);
二 接收所有時(shí)間格式
- yyyy-MM-dd HH:mm:ss 格式
- yyyy-MM-dd 格式
- 時(shí)間戳
- yyyy/MM/dd HH:mm:ss 格式
- yyyy/MM/dd 格式
注意
該方式不對(duì)json或xml的數(shù)據(jù)處理,比如使用@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: 時(shí)間轉(zhuǎn)換類 */ 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)) { //時(shí)間戳 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)); } }
將時(shí)間轉(zhuǎn)換類應(yīng)用到接口上
介紹兩種方式:使用@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()); } } }
最后
我使用的最后的一種方法的第二種方式
總結(jié)
時(shí)間參數(shù)這個(gè)坑還是有點(diǎn)大的,之前都是針對(duì)性的處理,只要一變化就沒(méi)法了;現(xiàn)在這個(gè)還是可以應(yīng)付基本上會(huì)出現(xiàn)的錯(cuò)誤了;
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
Spring MVC多種情況下進(jìn)行文件上傳的實(shí)例
上傳是Web工程中很常見(jiàn)的功能,SpringMVC框架簡(jiǎn)化了文件上傳的代碼,本文給大家總結(jié)了Spring MVC多種情況下進(jìn)行文件上傳的實(shí)例,并通過(guò)代碼示例給大家介紹的非常詳細(xì),需要的朋友可以參考下2024-02-02SpringSecurity 自定義認(rèn)證登錄的項(xiàng)目實(shí)踐
本文主要介紹了SpringSecurity 自定義認(rèn)證登錄的項(xiàng)目實(shí)踐,以手機(jī)驗(yàn)證碼登錄為例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2024-08-08Java中BigInteger與BigDecimal類用法總結(jié)
在Java中有兩個(gè)用于大數(shù)字運(yùn)算的類,分別是java.math.BigInteger類 和 java.math.BigDecimal類,這兩個(gè)類都可以用于高精度計(jì)算,BigInteger類是針對(duì)整型大數(shù)字的處理類,而B(niǎo)igDecimal類是針對(duì)大小數(shù)的處理類,接下來(lái)帶大家來(lái)學(xué)習(xí)一下,在Java中如何處理大數(shù)字2023-05-05Java實(shí)現(xiàn)新建有返回值的線程的示例詳解
本文主要介紹了一個(gè)Java多線程的例題,題目是:使用ThreadLocal管理一號(hào)和二號(hào)線程,分別存入100元,在三號(hào)線程中使用利用一號(hào)和二號(hào)的計(jì)算結(jié)果來(lái)算出賬戶的實(shí)際金額。感興趣的可以了解一下2022-09-09Idea中maven項(xiàng)目實(shí)現(xiàn)登錄驗(yàn)證碼功能
這篇文章主要介紹了Idea中maven項(xiàng)目實(shí)現(xiàn)登錄驗(yàn)證碼功能,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-12-12