最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java controller接口出入?yún)r間序列化轉(zhuǎn)換操作方法(兩種)

 更新時間:2025年04月30日 11:58:17   作者:Muscleheng  
這篇文章主要介紹了Java controller接口出入?yún)r間序列化轉(zhuǎn)換操作方法,本文給大家列舉兩種簡單方法,感興趣的朋友一起看看吧

場景:在controller編寫的接口,在前后端交互過程中一般都會涉及到時間字段的交互,比如:后端給前端返的數(shù)據(jù)有時間相關(guān)的字段,同樣,前端也存在傳時間相關(guān)的字段給后端,最原始的方式就是前后端都先轉(zhuǎn)換成字符串和時間戳后進行傳輸,收到后再進行轉(zhuǎn)換,特別麻煩。
為了方便可以使用注解或者配置做到時間字段的自動轉(zhuǎn)換,這里列舉兩種簡單的操作。

方式一、使用注解

就是在日期字段上添加對應(yīng)的注解(@JsonFormat),例:

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

優(yōu)點:靈活、清晰。
缺點:所有需要轉(zhuǎn)換的字段都需要手動添加、并且只支持時間和指定格式字符串互轉(zhuǎn),不支持時間戳

方式二、統(tǒng)一配置

一勞永逸的方式,支持時間和 時間戳、字符串 之間的互轉(zhuǎn)

package com.zhh.demo.config;
import cn.hutool.core.date.LocalDateTimeUtil;
import cn.hutool.core.util.NumberUtil;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import org.apache.commons.lang3.StringUtils;
import org.springframework.boot.autoconfigure.jackson.Jackson2ObjectMapperBuilderCustomizer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.io.IOException;
import java.math.BigInteger;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeParseException;
@Configuration
// 表示通過aop框架暴露該代理對象,AopContext能夠訪問
//@EnableAspectJAutoProxy(exposeProxy = true)
public class ApplicationConfig {
    /** 年-月-日 時:分:秒 */
    private static final String DEFAULT_DATE_TIME_FORMAT = "yyyy-MM-dd HH:mm:ss";
    /**
     * 序列化 時間格式轉(zhuǎn)換類型
     * timestamp:時間戳
     * dateString: 時間字符串格式
     * */
    private static final String LOCAL_DATE_TIME_SERIALIZER_TYPE = "dateString";
    /**
     * description:適配自定義序列化和反序列化策略
     */
    @Bean
    public Jackson2ObjectMapperBuilderCustomizer jackson2ObjectMapperBuilderCustomizer() {
        return builder -> {
            // 時間的序列化和反序列化
            builder.serializerByType(LocalDateTime.class, new LocalDateTimeSerializer());
            builder.deserializerByType(LocalDateTime.class, new LocalDateTimeDeserializer());
            // 將long類型數(shù)據(jù)轉(zhuǎn)化為string給前端 避免前端造成的精度丟失
            builder.serializerByType(Long.class, ToStringSerializer.instance);
            builder.serializerByType(BigInteger.class, ToStringSerializer.instance);
        };
    }
    /**
     * description:序列化
     * LocalDateTime序列化為毫秒級時間戳
     */
    public static class LocalDateTimeSerializer extends JsonSerializer<LocalDateTime> {
        @Override
        public void serialize(LocalDateTime value, JsonGenerator gen, SerializerProvider serializers)
                throws IOException {
            if (value != null) {
                // 通過配置決定把時間轉(zhuǎn)換成 時間戳 或 時間字符串
                if ("timestamp".equals(LOCAL_DATE_TIME_SERIALIZER_TYPE)) {
                    // 13位時間戳
                    gen.writeNumber(LocalDateTimeUtil.toEpochMilli(value));
                } else {
                    // 指定格式的時間字符串
                    gen.writeString(value.format(DateTimeFormatter.ofPattern(DEFAULT_DATE_TIME_FORMAT)));
                }
            }
        }
    }
    /**
     * description:反序列化
     * 毫秒級時間戳序列化為LocalDateTime
     */
    public static class LocalDateTimeDeserializer extends JsonDeserializer<LocalDateTime> {
        @Override
        public LocalDateTime deserialize(JsonParser p, DeserializationContext deserializationContext)
                throws IOException {
            //2023年11月2日: 嘗試反序列增加更多的支持, 支持long輸入, 支持字符串輸入
            if (p == null) {
                return null;
            }
            String source = p.getText();
            return parse(source);
        }
    }
    /**
     * 時間戳字符串或格式化時間字符串轉(zhuǎn)換為 LocalDateTime
     * 例:1745806578000、2025-04-28 10:16:18
     * @param source    13位時間戳 或格式化時間字符串
     * @return
     */
    private static LocalDateTime parse(String source) {
        // 如果是時間戳
        if (NumberUtil.isLong(source)) {
            long timestamp = Long.parseLong(source);
            if (timestamp > 0) {
                return LocalDateTimeUtil.of(timestamp, ZoneOffset.of("+8"));
            } else {
                return null;
            }
            // 如果是格式化時間字符串
        } else {
            if (StringUtils.isBlank(source)) {
                return null;
            }
            // 嘗試判斷能否解析
            if (canParseByDateTimeFormatter(source, DateTimeFormatter.ofPattern(DEFAULT_DATE_TIME_FORMAT))) {
                return LocalDateTime.parse(source, DateTimeFormatter.ofPattern(DEFAULT_DATE_TIME_FORMAT));
            }
            return null;
        }
    }
    /**
     * 判斷是否能解析格式化時間字符串
     * @param source    格式化時間字符串(格式 2025-04-28 10:16:18)
     * @param dateTimeFormatter 格式 yyyy-MM-dd HH:mm:ss
     * @return
     */
    private static boolean canParseByDateTimeFormatter(String source, DateTimeFormatter dateTimeFormatter) {
        try {
            dateTimeFormatter.parse(source);
        } catch (DateTimeParseException e) {
            return false;
        }
        return true;
    }
}

測試一下:
在上面配置的基礎(chǔ)上添加部分測試使用的代碼

用于前后端交互的bean對象:

@Data
public class UserRO {
    private LocalDateTime createTime1;
    private LocalDateTime createTime2;
    @JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
    private Date createTime3;
}

controller層接口:

   @ApiOperation("時間測試")
    @PostMapping("/time")
    public UserRO show(@RequestBody UserRO userRO){
        System.out.println("\n接收到的入?yún)ⅲ?);
        System.out.println(userRO.getCreateTime1());
        System.out.println(userRO.getCreateTime2());
        System.out.println(userRO.getCreateTime3());
        System.out.println("\n出參:");
        LocalDateTime newTime = LocalDateTime.now();
        UserRO user = new UserRO();
        user.setCreateTime1(newTime);
        user.setCreateTime2(newTime);
        user.setCreateTime3(new Date());
        System.out.println(user.getCreateTime1());
        System.out.println(user.getCreateTime2());
        System.out.println(user.getCreateTime3());
        System.out.println("\n");
        return user;
    }

通過配置類,可以配置后端接口給調(diào)用方返的時間格式【字符串、時間戳】、接口調(diào)用方傳的入?yún)⒖梢允亲址部梢缘臅r間戳,后端會自動解析。

到此這篇關(guān)于Java controller接口出入?yún)r間序列化轉(zhuǎn)換操作方法(兩種)的文章就介紹到這了,更多相關(guān)Java controller接口出入?yún)?nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Spring Scheduler定時任務(wù)實戰(zhàn)指南(零基礎(chǔ)入門任務(wù)調(diào)度)

    Spring Scheduler定時任務(wù)實戰(zhàn)指南(零基礎(chǔ)入門任務(wù)調(diào)度)

    本文介紹SpringScheduler在電商訂單超時處理中的應(yīng)用,涵蓋啟用定時任務(wù)、使用@Scheduled注解、cron表達式配置、線程池優(yōu)化及異步執(zhí)行等核心內(nèi)容,本文給大家介紹Spring Scheduler定時任務(wù)實戰(zhàn)指南,感興趣的朋友跟隨小編一起看看吧
    2025-09-09
  • SpringBoot接收前端參數(shù)的最常用的場景和具體案例

    SpringBoot接收前端參數(shù)的最常用的場景和具體案例

    在SpringBoot開發(fā)中接收參數(shù)是非常常見且重要的一部分,依賴于請求的不同場景,Spring?Boot提供了多種方式來處理和接收參數(shù),項目小編就和大家簡單講講SpringBoot接收前端參數(shù)的3 個最常用的場景和具體案例
    2025-11-11
  • Spring?Boot?整合?Neo4j的過程詳解

    Spring?Boot?整合?Neo4j的過程詳解

    Neo4j是一個高性能的?圖數(shù)據(jù)庫??,適用于存儲和查詢節(jié)點(Node)??和??關(guān)系(Relationship)??的數(shù)據(jù),本文介紹在springboot項目中整合neo4j,并實現(xiàn)基本的crud操作,感興趣的朋友跟隨小編一起看看吧
    2025-10-10
  • 關(guān)于MyBatis通用Mapper@Table注解使用的注意點

    關(guān)于MyBatis通用Mapper@Table注解使用的注意點

    這篇文章主要介紹了關(guān)于MyBatis通用Mapper@Table注解使用的注意點,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-11-11
  • SpringCloud使用CircuitBreaker實現(xiàn)熔斷器的詳細步驟

    SpringCloud使用CircuitBreaker實現(xiàn)熔斷器的詳細步驟

    在微服務(wù)架構(gòu)中,服務(wù)之間的依賴調(diào)用非常頻繁,當(dāng)一個下游服務(wù)因高負載或故障導(dǎo)致響應(yīng)變慢或不可用時,可能會引發(fā)上游服務(wù)的級聯(lián)故障,最終導(dǎo)致整個系統(tǒng)崩潰,熔斷器是解決這類問題的關(guān)鍵模式之一,Spring Cloud提供了對熔斷器的支持,本文將詳細介紹如何集成和使用它
    2025-02-02
  • SpringBoot淺析依賴管理與自動配置概念與使用

    SpringBoot淺析依賴管理與自動配置概念與使用

    一般來講SpringBoot項目是不需要指定版本,而SSM項目是需要指定版本,SpringBoot的核心依賴就是spring-boot-starter-parent和spring-boot-starter-web兩個依賴,這篇文章主要介紹了SpringBoot依賴管理與自動配置概念與使用
    2022-10-10
  • Spring Cloud下實現(xiàn)用戶鑒權(quán)的方案

    Spring Cloud下實現(xiàn)用戶鑒權(quán)的方案

    Java下常用的安全框架主要有Spring Security和shiro,都可提供非常強大的功能,但學(xué)習(xí)成本較高。但在微服務(wù)下鑒權(quán)又會對服務(wù)有一定的入侵性。 因此,本文將介紹Spring Cloud下實現(xiàn)用戶鑒權(quán)的方案,感興趣的同學(xué)可以關(guān)注一下
    2021-11-11
  • Java 互相關(guān)聯(lián)的實體無限遞歸問題的解決

    Java 互相關(guān)聯(lián)的實體無限遞歸問題的解決

    這篇文章主要介紹了Java 互相關(guān)聯(lián)的實體無限遞歸問題的解決,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-10-10
  • spring 自定義讓@Value被解析到

    spring 自定義讓@Value被解析到

    這篇文章主要介紹了spring 自定義讓@Value被解析到,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-09-09
  • MyBatis?SQL映射文件的作用和結(jié)構(gòu)詳解

    MyBatis?SQL映射文件的作用和結(jié)構(gòu)詳解

    MyBatisSQL映射文件定義了SQL語句和參數(shù)映射規(guī)則,用于將Java代碼與數(shù)據(jù)庫操作解耦,實現(xiàn)SQL語句的靈活配置和動態(tài)生成
    2025-03-03

最新評論

荔浦县| 平谷区| 兰西县| 吉林省| 阿荣旗| 姜堰市| 阿克陶县| 阳朔县| 保德县| 温宿县| 寿宁县| 双柏县| 涟水县| 剑河县| 稷山县| 浦县| 澄城县| 瑞安市| 青岛市| 海南省| 申扎县| 吴旗县| 灵寿县| 财经| 绥江县| 青川县| 五指山市| 岚皋县| 绥德县| 银川市| 曲周县| 淳化县| 夏津县| 孟连| 临高县| 绥芬河市| 晋中市| 佛坪县| 松阳县| 瑞丽市| 高青县|