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

SpringBoot配置LocalDateTime格式化方式

 更新時(shí)間:2026年01月06日 09:36:25   作者:Roc?Lau  
文章主要介紹了Spring?Boot中處理日期格式化和反格式化的方法,包括配置Jackson的`@JsonFormat`注解和全局配置日期轉(zhuǎn)換器`LocalDateTimeConvert`,以及`ConversionService`中`convert`的添加時(shí)機(jī)和過程

【1】格式化后臺(tái)傳給前端的日期

    • SpringBoot對(duì)Date/DateTime配置
    • 第一種方式:配置localDateTimeSerializer
    • 第二種方式:@JsonFormat

【2】前臺(tái)傳String格式日期給后臺(tái)

    • ① 配置全局的日期轉(zhuǎn)換器localDateTimeConvert
    • ② 配置日期格式化器

【3】convert是什么時(shí)候添加到ConversionService中的?

    • ① SpringBoot啟動(dòng)的時(shí)候運(yùn)行run方法
    • ② 嘗試獲取ConversionService
    • ③ 獲取ApplicationConversionService
    • ④ ApplicationConversionService.configure
    • ⑤ DefaultConversionService.addDefaultConverters
    • ⑥ addDefaultFormatters添加格式化器
    • ⑦ addApplicationFormatters(registry)
    • ⑧ addApplicationConverters(registry)

【1】格式化后臺(tái)傳給前端的日期

首先第一點(diǎn)需要知道的是springboot默認(rèn)依賴的json框架是jackson。

當(dāng)使用@ResponseBody注解返回json格式數(shù)據(jù)時(shí)就是該框架在起作用。

SpringBoot對(duì)Date/DateTime配置

如果字段屬性是Date而非LocalDateTime時(shí),通常我們會(huì)在application.properties里面配置如下:

spring.mvc.date-format=yyyy-MM-dd HH:mm:ss
spring.jackson.date-format=yyyy-MM-dd HH:mm:ss
spring.jackson.time-zone=GMT+8
spring.jackson.serialization.write-dates-as-timestamps=false

如下圖所示,spring.jackson開頭的配置會(huì)被JacksonProperties類獲取進(jìn)行使用。

當(dāng)返回json格式的時(shí)候,Jackson就會(huì)根據(jù)配置文件中日期格式化的配置對(duì)結(jié)果進(jìn)行處理。

但是如果字段屬性為LocalDateTime呢?這種配置就失去了作用。

第一種方式:配置localDateTimeSerializer

這時(shí)候建議配置如下:

/**
 * Created by jianggc at 2020/7/1.
 */
@Configuration
public class LocalDateTimeSerializerConfig {
    @Value("${spring.jackson.date-format:yyyy-MM-dd HH:mm:ss}")
    private String pattern;
    // localDateTime 序列化器
    @Bean
    public LocalDateTimeSerializer localDateTimeSerializer() {
        return new LocalDateTimeSerializer(DateTimeFormatter.ofPattern(pattern));
    }
    // localDateTime 反序列化器
    @Bean
    public LocalDateTimeDeserializer localDateTimeDeserializer() {
        return new LocalDateTimeDeserializer(DateTimeFormatter.ofPattern(pattern));
    }
    @Bean
    public Jackson2ObjectMapperBuilderCustomizer jackson2ObjectMapperBuilderCustomizer() {
//        return new Jackson2ObjectMapperBuilderCustomizer() {
//            @Override
//            public void customize(Jackson2ObjectMapperBuilder jacksonObjectMapperBuilder) {
                jacksonObjectMapperBuilder.featuresToDisable(SerializationFeature.FAIL_ON_EMPTY_BEANS);
//                jacksonObjectMapperBuilder.serializerByType(LocalDateTime.class, localDateTimeSerializer());
//                jacksonObjectMapperBuilder.deserializerByType(LocalDateTime.class,localDateTimeDeserializer());
//            }
//        };
        //這種方式同上
        return builder -> {
            builder.serializerByType(LocalDateTime.class, localDateTimeSerializer());
            builder.deserializerByType(LocalDateTime.class,localDateTimeDeserializer());
            builder.simpleDateFormat(pattern);
        };
    }
}

第二種方式:@JsonFormat

這種配置方式自然是全局的,如果想針對(duì)某個(gè)字段特殊處理,可以在類字段上面添加注解@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;

【2】前臺(tái)傳String格式日期給后臺(tái)

如下所示,前臺(tái)傳參2020-08-30 11:11:11,后臺(tái)使用LocalDateTime 接收。

通常會(huì)報(bào)錯(cuò)類似如下:

nested exception is org.springframework.core.convert.ConversionFailedException:

Failed to convert from type [java.lang.String] to type [java.time.LocalDateTime ]

很顯然是在參數(shù)綁定的時(shí)候沒有找到合適的轉(zhuǎn)換器把String轉(zhuǎn)換為對(duì)應(yīng)的格式。

① 配置全局的日期轉(zhuǎn)換器localDateTimeConvert

@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 dateTime = null;
            try {
                //2020-01-01 00:00:00
                switch (source.length()){
                    case 10:
                        logger.debug("傳過來的是日期格式:{}",source);
                        source=source+" 00:00:00";
                        break;
                    case 13:
                        logger.debug("傳過來的是日期 小時(shí)格式:{}",source);
                        source=source+":00:00";
                        break;
                    case 16:
                        logger.debug("傳過來的是日期 小時(shí):分鐘格式:{}",source);
                        source=source+":00";
                        break;
                }
                dateTime = LocalDateTime.parse(source, df);
            } catch (Exception e) {
               logger.error(e.getMessage(),e);
            }
            return dateTime;
        }
    };
}

實(shí)現(xiàn)原理簡要描述

在進(jìn)行參數(shù)綁定的時(shí)候,會(huì)使用WebDataBinder對(duì)象。而創(chuàng)建WebDataBinder對(duì)象時(shí),會(huì)遍歷DefaultDataBinderFactory.initializer,使用其WebBindingInitializer initializer對(duì)WebDataBinder對(duì)象進(jìn)行初始化。

初始化方法具體可見ConfigurableWebBindingInitializer.initBinder(WebDataBinder binder),源碼如下:

 public void initBinder(WebDataBinder binder) {
        binder.setAutoGrowNestedPaths(this.autoGrowNestedPaths);
        if (this.directFieldAccess) {
            binder.initDirectFieldAccess();
        }
        //設(shè)置messageCodesResolver
        if (this.messageCodesResolver != null) {
            binder.setMessageCodesResolver(this.messageCodesResolver);
        }
        //設(shè)置bindingErrorProcessor
        if (this.bindingErrorProcessor != null) {
            binder.setBindingErrorProcessor(this.bindingErrorProcessor);
        }
        //設(shè)置validator
        if (this.validator != null && binder.getTarget() != null && this.validator.supports(binder.getTarget().getClass())) {
            binder.setValidator(this.validator);
        }
        //設(shè)置conversionService
        if (this.conversionService != null) {
            binder.setConversionService(this.conversionService);
        }
        if (this.propertyEditorRegistrars != null) {
            PropertyEditorRegistrar[] var2 = this.propertyEditorRegistrars;
            int var3 = var2.length;
            for(int var4 = 0; var4 < var3; ++var4) {
                PropertyEditorRegistrar propertyEditorRegistrar = var2[var4];
                propertyEditorRegistrar.registerCustomEditors(binder);
            }
        }
    }

而conversionService中包含了許多的convert-類型格式化器。在WebDataBinder進(jìn)行參數(shù)綁定的時(shí)候就會(huì)使用不同的格式化器即不同的convert進(jìn)行參數(shù)類型轉(zhuǎn)換。

關(guān)于參數(shù)綁定的過程,有興趣的可以跟蹤DataBinder.doBind方法,在這個(gè)過程中會(huì)對(duì)前臺(tái)傳輸?shù)闹颠M(jìn)行類型轉(zhuǎn)換為目標(biāo)參數(shù)需要的類型。自定義的localDateTimeConvert也是在這里被用到的。

如下所示前臺(tái)傳String格式給后臺(tái)參數(shù)endDate,參數(shù)類型為java.time.LocalDateTime。

找到我們自定義的converter

調(diào)用convert進(jìn)行類型轉(zhuǎn)換:

可以看到轉(zhuǎn)換后的結(jié)果為:

② 配置日期格式化器

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

自定義的格式化器會(huì)在SpringBoot啟動(dòng)時(shí)自動(dòng)化配置過程中被加入,具體可以參考如下代碼。

WebMvcAutoConfiguration.mvcConversionService:

@Bean
@Override
public FormattingConversionService mvcConversionService() {
	WebConversionService conversionService = new WebConversionService(this.mvcProperties.getDateFormat());
	addFormatters(conversionService);
	return conversionService;
}

【3】convert是什么時(shí)候添加到ConversionService中的?

① SpringBoot啟動(dòng)的時(shí)候運(yùn)行run方法

其會(huì)走到SpringApplication.configureEnvironment方法處:

   protected void configureEnvironment(ConfigurableEnvironment environment, String[] args) {
        if (this.addConversionService) {
        //從這里跟蹤
            ConversionService conversionService = ApplicationConversionService.getSharedInstance();
            environment.setConversionService((ConfigurableConversionService)conversionService);
        }
        this.configurePropertySources(environment, args);
        this.configureProfiles(environment, args);
    }

② 嘗試獲取ConversionService

ApplicationConversionService.getSharedInstance如下所示,這里可以看到其使用了設(shè)計(jì)模式中的懶漢式之雙重校驗(yàn)鎖來獲取單例。

public static ConversionService getSharedInstance() {
      ApplicationConversionService sharedInstance = sharedInstance;
      if (sharedInstance == null) {
          Class var1 = ApplicationConversionService.class;
          synchronized(ApplicationConversionService.class) {
              sharedInstance = sharedInstance;
              if (sharedInstance == null) {
                  sharedInstance = new ApplicationConversionService();
                  sharedInstance = sharedInstance;
              }
          }
      }
      return sharedInstance;
  }

③ 獲取ApplicationConversionService

繼續(xù)對(duì)象創(chuàng)建過程會(huì)發(fā)現(xiàn)其走到了configure處:

  public ApplicationConversionService(StringValueResolver embeddedValueResolver) {
        if (embeddedValueResolver != null) {
            this.setEmbeddedValueResolver(embeddedValueResolver);
        }
//我們從這里繼續(xù)跟進(jìn)
        configure(this);
    }

這里我們順帶看一下ApplicationConversionService的類繼承示意圖(其不只是可以作為ConversionService還可以作為ConverterRegistry與FormatterRegistry):

④ ApplicationConversionService.configure

創(chuàng)建ApplicationConversionService時(shí)會(huì)對(duì)其進(jìn)行配置,這里很重要。其會(huì)注入默認(rèn)的Converter和Formatter:

public static void configure(FormatterRegistry registry) {
      DefaultConversionService.addDefaultConverters(registry);
      DefaultFormattingConversionService.addDefaultFormatters(registry);
      addApplicationFormatters(registry);
      addApplicationConverters(registry);
  }

⑤ DefaultConversionService.addDefaultConverters

該方法執(zhí)行完,會(huì)添加52個(gè)類型轉(zhuǎn)換器:

public static void addDefaultConverters(ConverterRegistry converterRegistry) {
	addScalarConverters(converterRegistry);
	addCollectionConverters(converterRegistry);
	converterRegistry.addConverter(new ByteBufferConverter((ConversionService) converterRegistry));
	converterRegistry.addConverter(new StringToTimeZoneConverter());
	converterRegistry.addConverter(new ZoneIdToTimeZoneConverter());
	converterRegistry.addConverter(new ZonedDateTimeToCalendarConverter());
	converterRegistry.addConverter(new ObjectToObjectConverter());
	converterRegistry.addConverter(new IdToEntityConverter((ConversionService) converterRegistry));
	converterRegistry.addConverter(new FallbackObjectToStringConverter());
	converterRegistry.addConverter(new ObjectToOptionalConverter((ConversionService) converterRegistry));
}

addScalarConverters(converterRegistry);如下所示:

private static void addScalarConverters(ConverterRegistry converterRegistry) {
	converterRegistry.addConverterFactory(new NumberToNumberConverterFactory());
	converterRegistry.addConverterFactory(new StringToNumberConverterFactory());
	converterRegistry.addConverter(Number.class, String.class, new ObjectToStringConverter());
	converterRegistry.addConverter(new StringToCharacterConverter());
	converterRegistry.addConverter(Character.class, String.class, new ObjectToStringConverter());
	converterRegistry.addConverter(new NumberToCharacterConverter());
	converterRegistry.addConverterFactory(new CharacterToNumberFactory());
	converterRegistry.addConverter(new StringToBooleanConverter());
	converterRegistry.addConverter(Boolean.class, String.class, new ObjectToStringConverter());
	converterRegistry.addConverterFactory(new StringToEnumConverterFactory());
	converterRegistry.addConverter(new EnumToStringConverter((ConversionService) converterRegistry));
	converterRegistry.addConverterFactory(new IntegerToEnumConverterFactory());
	converterRegistry.addConverter(new EnumToIntegerConverter((ConversionService) converterRegistry));
	converterRegistry.addConverter(new StringToLocaleConverter());
	converterRegistry.addConverter(Locale.class, String.class, new ObjectToStringConverter());
	converterRegistry.addConverter(new StringToCharsetConverter());
	converterRegistry.addConverter(Charset.class, String.class, new ObjectToStringConverter());
	converterRegistry.addConverter(new StringToCurrencyConverter());
	converterRegistry.addConverter(Currency.class, String.class, new ObjectToStringConverter());
	converterRegistry.addConverter(new StringToPropertiesConverter());
	converterRegistry.addConverter(new PropertiesToStringConverter());
	converterRegistry.addConverter(new StringToUUIDConverter());
	converterRegistry.addConverter(UUID.class, String.class, new ObjectToStringConverter());
}

這里會(huì)添加23個(gè)類型轉(zhuǎn)換器:

添加集合處理的類型轉(zhuǎn)換器(這里會(huì)添加17個(gè)類型轉(zhuǎn)換器):

public static void addCollectionConverters(ConverterRegistry converterRegistry) {
	ConversionService conversionService = (ConversionService) converterRegistry;
	converterRegistry.addConverter(new ArrayToCollectionConverter(conversionService));
	converterRegistry.addConverter(new CollectionToArrayConverter(conversionService));
	converterRegistry.addConverter(new ArrayToArrayConverter(conversionService));
	converterRegistry.addConverter(new CollectionToCollectionConverter(conversionService));
	converterRegistry.addConverter(new MapToMapConverter(conversionService));
	converterRegistry.addConverter(new ArrayToStringConverter(conversionService));
	converterRegistry.addConverter(new StringToArrayConverter(conversionService));
	converterRegistry.addConverter(new ArrayToObjectConverter(conversionService));
	converterRegistry.addConverter(new ObjectToArrayConverter(conversionService));
	converterRegistry.addConverter(new CollectionToStringConverter(conversionService));
	converterRegistry.addConverter(new StringToCollectionConverter(conversionService));
	converterRegistry.addConverter(new CollectionToObjectConverter(conversionService));
	converterRegistry.addConverter(new ObjectToCollectionConverter(conversionService));
	converterRegistry.addConverter(new StreamConverter(conversionService));
}

⑥ addDefaultFormatters添加格式化器

/**
 * Add formatters appropriate for most environments: including number formatters,
 * JSR-354 Money & Currency formatters, JSR-310 Date-Time and/or Joda-Time formatters,
 * depending on the presence of the corresponding API on the classpath.
 * @param formatterRegistry the service to register default formatters with
 */
public static void addDefaultFormatters(FormatterRegistry formatterRegistry) {
	// Default handling of number values
	formatterRegistry.addFormatterForFieldAnnotation(new NumberFormatAnnotationFormatterFactory());
	// Default handling of monetary values
	if (jsr354Present) {
		formatterRegistry.addFormatter(new CurrencyUnitFormatter());
		formatterRegistry.addFormatter(new MonetaryAmountFormatter());
		formatterRegistry.addFormatterForFieldAnnotation(new Jsr354NumberFormatAnnotationFormatterFactory());
	}
	// Default handling of date-time values
	// just handling JSR-310 specific date and time types
	new DateTimeFormatterRegistrar().registerFormatters(formatterRegistry);
	if (jodaTimePresent) {
		// handles Joda-specific types as well as Date, Calendar, Long
		new JodaTimeFormatterRegistrar().registerFormatters(formatterRegistry);
	}
	else {
		// regular DateFormat-based Date, Calendar, Long converters
		new DateFormatterRegistrar().registerFormatters(formatterRegistry);
	}
}

DateTimeFormatterRegistrar.registerFormatters

@Override
public void registerFormatters(FormatterRegistry registry) {
	DateTimeConverters.registerConverters(registry);
	DateTimeFormatter df = getFormatter(Type.DATE);
	DateTimeFormatter tf = getFormatter(Type.TIME);
	DateTimeFormatter dtf = getFormatter(Type.DATE_TIME);
	// Efficient ISO_LOCAL_* variants for printing since they are twice as fast...
	registry.addFormatterForFieldType(LocalDate.class,
			new TemporalAccessorPrinter(
					df == DateTimeFormatter.ISO_DATE ? DateTimeFormatter.ISO_LOCAL_DATE : df),
			new TemporalAccessorParser(LocalDate.class, df));
	registry.addFormatterForFieldType(LocalTime.class,
			new TemporalAccessorPrinter(
					tf == DateTimeFormatter.ISO_TIME ? DateTimeFormatter.ISO_LOCAL_TIME : tf),
			new TemporalAccessorParser(LocalTime.class, tf));
	registry.addFormatterForFieldType(LocalDateTime.class,
			new TemporalAccessorPrinter(
					dtf == DateTimeFormatter.ISO_DATE_TIME ? DateTimeFormatter.ISO_LOCAL_DATE_TIME : dtf),
			new TemporalAccessorParser(LocalDateTime.class, dtf));
	registry.addFormatterForFieldType(ZonedDateTime.class,
			new TemporalAccessorPrinter(dtf),
			new TemporalAccessorParser(ZonedDateTime.class, dtf));
	registry.addFormatterForFieldType(OffsetDateTime.class,
			new TemporalAccessorPrinter(dtf),
			new TemporalAccessorParser(OffsetDateTime.class, dtf));
	registry.addFormatterForFieldType(OffsetTime.class,
			new TemporalAccessorPrinter(tf),
			new TemporalAccessorParser(OffsetTime.class, tf));
	registry.addFormatterForFieldType(Instant.class, new InstantFormatter());
	registry.addFormatterForFieldType(Period.class, new PeriodFormatter());
	registry.addFormatterForFieldType(Duration.class, new DurationFormatter());
	registry.addFormatterForFieldType(Year.class, new YearFormatter());
	registry.addFormatterForFieldType(Month.class, new MonthFormatter());
	registry.addFormatterForFieldType(YearMonth.class, new YearMonthFormatter());
	registry.addFormatterForFieldType(MonthDay.class, new MonthDayFormatter());
	registry.addFormatterForFieldAnnotation(new Jsr310DateTimeFormatAnnotationFormatterFactory());
}

DateTimeConverters.registerConverters

public static void registerConverters(ConverterRegistry registry) {
	DateFormatterRegistrar.addDateConverters(registry);
	registry.addConverter(new LocalDateTimeToLocalDateConverter());
	registry.addConverter(new LocalDateTimeToLocalTimeConverter());
	registry.addConverter(new ZonedDateTimeToLocalDateConverter());
	registry.addConverter(new ZonedDateTimeToLocalTimeConverter());
	registry.addConverter(new ZonedDateTimeToLocalDateTimeConverter());
	registry.addConverter(new ZonedDateTimeToOffsetDateTimeConverter());
	registry.addConverter(new ZonedDateTimeToInstantConverter());
	registry.addConverter(new OffsetDateTimeToLocalDateConverter());
	registry.addConverter(new OffsetDateTimeToLocalTimeConverter());
	registry.addConverter(new OffsetDateTimeToLocalDateTimeConverter());
	registry.addConverter(new OffsetDateTimeToZonedDateTimeConverter());
	registry.addConverter(new OffsetDateTimeToInstantConverter());
	registry.addConverter(new CalendarToZonedDateTimeConverter());
	registry.addConverter(new CalendarToOffsetDateTimeConverter());
	registry.addConverter(new CalendarToLocalDateConverter());
	registry.addConverter(new CalendarToLocalTimeConverter());
	registry.addConverter(new CalendarToLocalDateTimeConverter());
	registry.addConverter(new CalendarToInstantConverter());
	registry.addConverter(new LongToInstantConverter());
	registry.addConverter(new InstantToLongConverter());
}

DateFormatterRegistrar.addDateConverters

public static void addDateConverters(ConverterRegistry converterRegistry) {
	converterRegistry.addConverter(new DateToLongConverter());
	converterRegistry.addConverter(new DateToCalendarConverter());
	converterRegistry.addConverter(new CalendarToDateConverter());
	converterRegistry.addConverter(new CalendarToLongConverter());
	converterRegistry.addConverter(new LongToDateConverter());
	converterRegistry.addConverter(new LongToCalendarConverter());
}

⑦ addApplicationFormatters(registry)

添加全局格式化器:

   public static void addApplicationFormatters(FormatterRegistry registry) {
        registry.addFormatter(new CharArrayFormatter());
        registry.addFormatter(new InetAddressFormatter());
        registry.addFormatter(new IsoOffsetFormatter());
    }

⑧ addApplicationConverters(registry)

添加全局類型轉(zhuǎn)換器:

public static void addApplicationConverters(ConverterRegistry registry) {
       addDelimitedStringConverters(registry);
       registry.addConverter(new StringToDurationConverter());
       registry.addConverter(new DurationToStringConverter());
       registry.addConverter(new NumberToDurationConverter());
       registry.addConverter(new DurationToNumberConverter());
       registry.addConverter(new StringToDataSizeConverter());
       registry.addConverter(new NumberToDataSizeConverter());
       registry.addConverter(new StringToFileConverter());
       registry.addConverterFactory(new LenientStringToEnumConverterFactory());
       registry.addConverterFactory(new LenientBooleanToEnumConverterFactory());
   }
   public static void addDelimitedStringConverters(ConverterRegistry registry) {
       ConversionService service = (ConversionService)registry;
       registry.addConverter(new ArrayToDelimitedStringConverter(service));
       registry.addConverter(new CollectionToDelimitedStringConverter(service));
       registry.addConverter(new DelimitedStringToArrayConverter(service));
       registry.addConverter(new DelimitedStringToCollectionConverter(service));
   }

總結(jié)

以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • SpringBoot實(shí)現(xiàn)六邊形架構(gòu)的三種不同方式詳解

    SpringBoot實(shí)現(xiàn)六邊形架構(gòu)的三種不同方式詳解

    六邊形架構(gòu),也被稱為端口與適配器架構(gòu)或洋蔥架構(gòu),是一種將業(yè)務(wù)邏輯與外部依賴解耦的架構(gòu)模式,本文將介紹在SpringBoot中實(shí)現(xiàn)六邊形架構(gòu)的三種不同方式
    2025-06-06
  • Java中求Logn/log2 的精度問題

    Java中求Logn/log2 的精度問題

    這篇文章主要介紹了Java中求Logn/log2 的精度問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-08-08
  • Java如何自定義異常打印非堆棧信息詳解

    Java如何自定義異常打印非堆棧信息詳解

    這篇文章主要給大家介紹了關(guān)于Java如何自定義異常打印非堆棧信息的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧。
    2018-04-04
  • Java超詳細(xì)講解設(shè)計(jì)模式之一的單例模式

    Java超詳細(xì)講解設(shè)計(jì)模式之一的單例模式

    單例模式(Singleton Pattern)是 Java 中最簡單的設(shè)計(jì)模式之一。這種類型的設(shè)計(jì)模式屬于創(chuàng)建型模式,它提供了一種創(chuàng)建對(duì)象的最佳方式
    2022-03-03
  • Springboot并發(fā)調(diào)優(yōu)之大事務(wù)和長連接

    Springboot并發(fā)調(diào)優(yōu)之大事務(wù)和長連接

    這篇文章主要介紹了Springboot并發(fā)調(diào)優(yōu)之大事務(wù)和長連接,重點(diǎn)分享長事務(wù)以及長連接導(dǎo)致的并發(fā)排查和優(yōu)化思路和示例,具有一定的參考價(jià)值,感興趣的可以了解一下
    2022-05-05
  • IDEA解決@Slf4j中l(wèi)og報(bào)紅問題

    IDEA解決@Slf4j中l(wèi)og報(bào)紅問題

    在IntelliJ IDEA中使用log.info()時(shí),如果出現(xiàn)錯(cuò)誤,通常是因?yàn)槿鄙貺ombok插件,以下是解決方法:打開IntelliJ IDEA,進(jìn)入設(shè)置(File > Settings 或者 Ctrl+Alt+S),在Plugins部分點(diǎn)擊Browse repositories,搜索Lombok并安裝,安裝完成后,問題通??梢越鉀Q
    2024-12-12
  • springboot上傳文件,url直接訪問資源問題

    springboot上傳文件,url直接訪問資源問題

    這篇文章主要介紹了springboot上傳文件,url直接訪問資源問題。具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-11-11
  • FeignClient支持運(yùn)行時(shí)動(dòng)態(tài)指定URL方式

    FeignClient支持運(yùn)行時(shí)動(dòng)態(tài)指定URL方式

    在實(shí)際開發(fā)中,我們經(jīng)常通過FeignClient接口調(diào)用三方API,當(dāng)面對(duì)不同的環(huán)境對(duì)應(yīng)不同的地址時(shí),可以通過配置文件和占位符來切換,但在同一個(gè)環(huán)境中需要調(diào)用不同地址的相同接口時(shí),這種方法就失效了,此時(shí),可以通過實(shí)現(xiàn)RequestInterceptor接口來動(dòng)態(tài)切換地址
    2024-11-11
  • Java 枚舉的基本使用方法及實(shí)際使用場景

    Java 枚舉的基本使用方法及實(shí)際使用場景

    枚舉是 Java 中一種特殊的類,用于定義一組固定的常量,枚舉類型提供了更好的類型安全性和可讀性,適用于需要定義一組有限且固定的值的場景,本文給大家介紹Java 枚舉的用法及實(shí)際使用場景,感興趣的朋友一起看看吧
    2025-06-06
  • MyBatis動(dòng)態(tài)標(biāo)簽詳解與應(yīng)用實(shí)踐舉例

    MyBatis動(dòng)態(tài)標(biāo)簽詳解與應(yīng)用實(shí)踐舉例

    MyBatis的動(dòng)態(tài)SQL功能通過一組強(qiáng)大的標(biāo)簽實(shí)現(xiàn),使得根據(jù)業(yè)務(wù)條件構(gòu)建靈活SQL查詢變得簡單高效,這些標(biāo)簽基于OGNL表達(dá)式,能夠智能生成SQL,避免了手動(dòng)拼接SQL的復(fù)雜性和風(fēng)險(xiǎn),感興趣的朋友跟隨小編一起看看吧
    2026-01-01

最新評(píng)論

卢氏县| 寻甸| 通许县| 丹寨县| 彭泽县| 威远县| 凉山| 扶余县| 和林格尔县| 永川市| 福清市| 公安县| 宁乡县| 白银市| 龙井市| 保亭| 襄樊市| 纳雍县| 界首市| 卫辉市| 济阳县| 慈溪市| 嘉荫县| 舞阳县| 河间市| 岫岩| 红安县| 晋城| 九江市| 闵行区| 石渠县| 平度市| 紫阳县| 民和| 定兴县| 平顶山市| 慈利县| 汝南县| 东光县| 紫云| 佛冈县|