1. 程式人生 > >spring-boot 介面請求之Date、LocalDate、LocalDateTime日期型別轉換處理

spring-boot 介面請求之Date、LocalDate、LocalDateTime日期型別轉換處理

搭建完一個spring-boot的介面服務後,可以在前段通過ajax非同步請求後臺介面資料,一般ajax通過傳遞json物件給後臺介面,後臺接收資料轉化為Bean物件,處理邏輯完成後,將返回的資料轉為json回送給前臺呼叫者;

1.前臺ajax引數格式為:

var param1={
    id:1234,
    name:'名稱',
    path:'路徑',
    createdDate:'2017-01-05 12:45:32'
}

2.ajax 呼叫

$.get("http://***********/ajaxApi/getOfBean",param, function(result){
    console.info("result:"+JSON.stringify(result));
});
3.後臺接收引數的Bean實體類
public class Ajax implements Serializable{
    private Long id;
    private String name;
    private String path;
    private Date createdDate;
    
}

4.後臺spring-boot提供的介面:

@RestController
@RequestMapping(value="ajaxApi")
@Api(value = "/ajaxApi", description = "非同步介面測試API",tags={"/ajaxApi"})
public class AjaxController {
  private static final Logger logger = LoggerFactory.getLogger(AjaxController.class);
  /***
   * 非同步引數接收
   * @return
   */
    @RequestMapping(value = "/getOfBean")
    @ApiOperation("Bean實體引數")
    public Ajax getOfBean(Ajax ajax) throws Exception{
      logger.info("非同步引數接收:{}",ajax.toString());//列印接收的物件
      return ajax;
    }
 }

介面接收引數為AjaxBean實體類,結束後返回該實體類給前臺;啟動專案,觸發ajax請求,報錯:

【org.springframework.validation.BindException】

Failed to convert property value of type 'java.lang.String' to required type 'java.util.Date' for property 'createdDate';
 nested exception is org.springframework.core.convert.ConversionFailedException: 
Failed to convert from type [java.lang.String] to type [java.util.Date] for value '2017-01-05 12:45:32'; 
nested exception is java.lang.IllegalArgumentException
報錯原因】:

 ajax使用json字串將日期字串傳送到後臺介面,後臺無法將字串轉為日期型別,缺少轉換器;

解決方法】:

 增加日期型別轉換器,方式有四種:

第一種:在Bean實體欄位或引數上增加@DateTimeFormat註解

@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date createdDate;
第二種:在接收引數的的Controller中增加@InitBinder轉化方法
@InitBinder
protected void initBinder(WebDataBinder binder) {
   SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
   binder.registerCustomEditor(Date.class, new CustomDateEditor(dateFormat, true));
}

【*】此種方式只對當前controller起作用

第三種:配置全域性的日期轉換器

/**
 * 轉換解析器
 * @author wangqingguo 2017/9/25
 */
@Configuration
public class MappingConverterAdapter {
    /***
     * 日期引數接收轉換器,將json字串轉為日期型別
     * @return
     */
    @Bean
    public Converter<String, Date> DateConvert() {
        return new Converter<String, Date>() {
            @Override
            public Date convert(String source) {
                SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                Date date = null;
                try {
                    date = sdf.parse((String) source);
                } catch (Exception e) {
                    e.printStackTrace();
                }
                return date;
            }
        };
    }
}

【*】此處定義的dateConvert用來轉換Date型別,如果是LocalDate、LocalDateTime型別,則將Date
型別換成相應的型別即可,注意java8的日期型別需要用Formatter格式化:

/**
 * 轉換解析器
 * @author wangqingguo 2017/9/25
 */
@Configuration
public class MappingConverterAdapter {
    /***
     * 日期引數接收轉換器,將json字串轉為日期型別
     * @return
     */
   @Bean
    public Converter<String, LocalDateTime> LocalDateTimeConvert() {
        return new Converter<String, LocalDateTime>() {
            @Override
            public LocalDateTime convert(String source) {

                DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
                LocalDateTime date = null;
                try {
                    date = LocalDateTime.parse((String) source,df);
                } catch (Exception e) {
                    e.printStackTrace();
                }
                return date;
            }
        };
    }
}

第四種:配置Formatter日期轉換器
/**
 * 日期轉換器
 * @author LiMeng 2017/11/7
 */
@Configuration
public class DateConfig {
    /***
     * Date日期型別轉換器
     * @return
     */
    @Bean
    public Formatter<Date> dateFormatter() {
        return new Formatter<Date>() {

            @Override
            public Date parse(String text, Locale locale) throws ParseException {
                SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                Date date = null;
                try {
                    date = sdf.parse(text);
                } catch (Exception e) {
                    e.printStackTrace();
                }
                return date;
            }

            @Override
            public String print(Date object, Locale locale) {
                SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                return sdf.format(object);
            }
        };
    }
}

【*】如果是LocalDate、LocalDateTime型別,則將Date型別換成相應的型別即可,
注意java8的日期型別需要用Formatter格式化:
/**
 * 日期轉換器
 * @author LiMeng 2017/11/7
 */
@Configuration
public class DateConfig {
    /***
     * Date日期型別轉換器
     * @return
     */
    @Bean
    public Formatter<Date> dateFormatter() {
        return new Formatter<Date>() {

            @Override
            public Date parse(String text, Locale locale) throws ParseException {
                SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                Date date = null;
                try {
                    date = sdf.parse(text);
                } catch (Exception e) {
                    e.printStackTrace();
                }
                return date;
            }

            @Override
            public String print(Date object, Locale locale) {
                SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                return sdf.format(object);
            }
        };
    }
    @Bean
    public Formatter<LocalDate> localDateFormatter() {
        return new Formatter<LocalDate>() {
            @Override
            public LocalDate parse(String text, Locale locale) throws ParseException {
                return LocalDate.parse(text, DateTimeFormatter.ISO_LOCAL_DATE);
            }

            @Override
            public String print(LocalDate object, Locale locale) {
                return DateTimeFormatter.ISO_LOCAL_DATE.format(object);
            }
        };
    }

    @Bean
    public Formatter<LocalDateTime> localDateTimeFormatter() {
        return new Formatter<LocalDateTime>() {
            @Override
            public String print(LocalDateTime localDateTime, Locale locale) {
                DateTimeFormatter formatter=DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
                return formatter.format(localDateTime);
            }

            @Override
            public LocalDateTime parse(String text, Locale locale) throws ParseException {
                DateTimeFormatter formatter=DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
                return LocalDateTime.parse(text, DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
            }
        };
    }
}

OK,啟動系統,可以正常訪問,但這時發現後臺返回前臺的資料為:
{"id":1234,"name":"名稱","path":"路徑","createdDate":1483545600000}

發現後臺可以正常接收日期型別,但返回後前臺接收的日期成了時間戳;理想情況下前臺接收到時間的格式化字串資料;
之所以出現這個問題,是因為專案沒有對返回的JSON進行處理解析;

【報錯原因】:
 java中的日期型別,在轉為JSON字串時沒有進行日期格式化;

【解決方法】:

解決方式有以下幾種

第一種:在Bean實體屬性增加 @JsonFormat註解

    @JsonFormat( pattern = "yyyy-MM-dd HH:mm:ss",timezone="GMT+8")
    private Date createdDate;
    @JsonFormat( pattern = "yyyy-MM-dd HH:mm:ss")
    private LocalDateTime createdTime;

【*】注:Date型別的使用註解 會出現事件相差8小時的情況,需要設定timezone屬性指定時區;LocalDateTime型別沒有發現此問題,所以沒有加此屬性;

另外LocalDateTime只加此註解,還是無法解析,需要增加jackson-datatype-jsr310jar包才管用

compile group: 'com.fasterxml.jackson.datatype', name: 'jackson-datatype-jsr310', version: '2.9.3'

第二種:增加MappingJackson2HttpMessageConverterAdapter 轉換器,對日期型別進行格式化轉換:

/**
 * JSON解析器
 * @author wangqingguo 2017/9/25
 */
@Configuration
public class MappingJackson2HttpMessageConverterAdapter {

    /***
     * 配置JSON解析器內容
     * @return
     */
    @Bean
    public MappingJackson2HttpMessageConverter mappingJackson2HttpMessageConverter() {
        MappingJackson2HttpMessageConverter a= new MappingJackson2HttpMessageConverter();
        /***
         * 頭格式
         */
        List<MediaType> supportedMediaTypes=new ArrayList<>();
        supportedMediaTypes.add(MediaType.APPLICATION_JSON_UTF8);
        supportedMediaTypes.add(MediaType.TEXT_HTML);
        supportedMediaTypes.add(MediaType.TEXT_PLAIN);
        a.setSupportedMediaTypes(supportedMediaTypes);

        /***
         * 日期格式化,解決返回的日期型別格式化
         */
        ObjectMapper objectMapper = a.getObjectMapper();
        DateFormat dateFormat=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        objectMapper.setDateFormat(dateFormat);
        a.setObjectMapper(objectMapper);


        return a;
    }
}
【*】注:此種方式只對Date型別起作用,Java8的LocalDateTime型別不起作用,LocalDateTime型別還是需要用@JsonFormat註解的形式;

文章為本人測試後所寫,歡迎各位留言交流,如有不對請指正,歡迎大家留言

相關推薦

spring-boot 介面請求DateLocalDateLocalDateTime日期型別轉換處理

搭建完一個spring-boot的介面服務後,可以在前段通過ajax非同步請求後臺介面資料,一般ajax通過傳遞json物件給後臺介面,後臺接收資料轉化為Bean物件,處理邏輯完成後,將返回的資料轉為json回送給前臺呼叫者; 1.前臺ajax引數格式為: var par

Spring boot 中java.util.Date 在json資料庫之間格式的相互轉換

首先使用springboot開發網站時,經常會涉及到日期的形式,那麼在程式碼中使用java.util.Date來轉化為json格式的字串,應該怎樣轉化呢?將Date型別存入資料庫有應該怎樣實現呢? Date與json的相互轉換 實現Date轉換為json格

spring boot-高階話題 多執行緒@EnableScheduling開啟計劃任務的支援(2)

spring通過任務執行器(TaskExecutor)來實現多執行緒和併發程式設計。 ThreadPoolTaskExecutor可實現一個基於執行緒池的TaskExecutor。 實際開發中任務一般是非阻礙的,即非同步的,通過@EnableAsync開啟對非同步任務的支援

spring boot 介面 XML 接受和請求(傳送篇)

業務處理類 import java.io.IOException; import java.util.ArrayList; import java.util.Date; import java.util.List; import org.apache.commons.lang.time.D

spring boot 介面 XML 接受和請求

測試的xml 原檔案: <?xml version="1.0" encoding="utf-8"?> <xml> <head> <app_key>mdDve0aYHGvSNZlcke0QyA3kSZihXYdi</app_k

spring boot學習1 spring boot整合freemarkmybatis搭建專案

1. application.properties常用配置 server.port=9090 # 服務埠號 server.tomcat.uri-encoding=UTF-8 #以Tomcat為web容器

Spring Boot介面如何設計防篡改防重放攻擊

Spring Boot 防篡改、防重放攻擊 本示例主要內容 請求引數防止篡改攻擊 基於timestamp方案,防止重放攻擊 使用swagger介面文件自動生成 API介面設計 API介面由於需要供第三方服務呼叫,所以必須暴露到外網,並提供了具體請求地址和請求引數,為了防止被別有用心之人獲取到真實請求引數後

我的第一個spring boot程序(spring boot 學習筆記二)

獲取json 了解 訪問 static 依賴 過程 public 獲取數據 gap 第一個spring boot程序 寫在前面:鑒於spring註解以及springMVC的配置有大量細節和知識點,在學習理解之後,我們將直接進入spring boot的學習,在後續學習中用到註

Spring Boot參考教程(五)Spring Boot配置使用配置類用法

expr web程序 成功 驗證 pan hub parameter lan fix 4.2. SpringBoot配置使用之配置類使用 Spring Boot的大部分自動配置都可以滿足應用要求,但如果想精確的控制應用,或者想覆蓋自動配置,使用配置類是另一種很好的選擇,強調

Spring Boot參考教程(四)Spring Boot配置使用配置文件用法

point rop 推薦書 endpoint size int == 需要 相同 4.1 Spring Boot配置使用之配置文件用法 Spring Boot旨在簡化配置,但依然需要進行少量配置來滿足應用的特定需要。 配置方式拋棄了XML文件的配置方式,主要使用配置文件

spring boot框架學習重要註解3註解方式讀取外部資源配置文件

凱哥java java註解 本節主要內容:1:是用非註解方式怎麽獲取配置文件中的配置項2:使用註解實戰獲取外部properties文件配置項聲明:本文是《凱哥陪你學系列-框架學習之spring boot框架學習》中spring boot框架學習學前掌握之重要註解(3)-通過註解方式讀取外部資源配置文件

spring boot 源碼SpringBootExceptionReporter

epo public throw con 第一個 tro exc ring nbsp SpringBootExceptionReporter   用戶自定義異常處理回調接口。 public interface SpringBootExceptionReporter {

spring boot 與 thymeleaf (3): 設置屬性條件遍歷局部變量優先級內聯語法

負數 使用 cnblogs ttr price n) 原型 demo 解析結果 前面記錄了 thymeleaf 基本表達式, 這裏繼續看一下其他功能. 一. 設置屬性值 這裏的controller, html框架 還是沿用上一篇的部分. html: <div cl

spring boot 2.0使用spring boot

架構 spring spring boot依賴每一個spring boot的發型版本都包含了所依賴的版本,如果升級spring boot版本,其依賴也會同步更新升級。maven的用戶可以通過繼承spring-boot-starter-parent。其包含了一些合理的值的設置:1. 默認設置的編譯器為J

Spring-Boot整合freemarker引入靜態資源cssjs等(轉)

mark pan 創建 line path main 實現 content -m 一、概述springboot 默認靜態資源訪問的路徑為:/static 或 /public 或 /resources 或 /META-INF/resources 這樣的地址都必須定義在src/

013-Spring Boot web【二】靜態資源ServletFilterlistenter

ces 其中 bean response cat 使用 修改配置 dac tostring 一、靜態資源 1.1、webapp默認支持靜態資源 在src/main/webapp下建立user.html默認支持訪問 1.2、默認內置靜態資源目錄。可被直接訪問 查看包:

Spring Boot 進階Web進階 學習 - 單元測試

自動生成 添加 學習 one 類文件 dma AC mock ring 可在類文件中,右鍵->GO TO->Test 自動生成測試文件 1.添加測試註解 簡單方法測試 @RunWith(SpringRunner.class)@SpringBootTes

Spring Boot 鑒權—— JWT 鑒權

發現 ray The import 原因 arraylist alt 在一起 set 第一:什麽是JWT鑒權 1. JWT即JSON Web Tokens,是為了在網絡應用環境間傳遞聲明而執行的一種基於JSON的開放標準((RFC 7519),他可以用來安全的

spring boot項目賣家掃碼登陸獲取openid(微信身份驗證id)

能夠 style png info 提示 行處理 The 使用 src 賣家掃碼登陸獲取openid 註:此功能只能是微信公眾帳號能夠使用,個人賬號無此功能。 一、打開微信開放平臺(與支付階段不同,特別註意!!!),進入網站應用的網站應用微信登陸開發指南。 二、你會發

spring boot項目登陸緩存session至redis和cookies

進行 @param span set 參數 cat control session open 一、將獲取的openId(詳細步驟見賣家掃碼登陸獲取openId)作為參數傳入到SellerUserController中的login登陸方法。 註:此處設置token,是為了取