# pap-bean-spring-boot-starter **Repository Path**: alexgaoyh/pap-bean-spring-boot-starter ## Basic Information - **Project Name**: pap-bean-spring-boot-starter - **Description**: 自定义的Bean维护starter启动类,形如:主键生成器&通用的拦截器 - **Primary Language**: Java - **License**: Not specified - **Default Branch**: v1 - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2019-03-02 - **Last Updated**: 2021-06-10 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # 在项目启动的过程中,进行外置配置参数的校验: 形如 idworker 需要的两个参数,需要在外部引用项目中进行参数配置,类似这种需要在项目启动的时候就需要进行参数校验: 1、对应的 *Properties 文件中增加相关注解: @NotNull @Valid private Integer workerId; 2、新增类文件: package com.pap.beans.idworker; import org.springframework.validation.Errors; import org.springframework.validation.Validator; public class PapConfigPropertiesValidator implements Validator { /** * 这里的方法可以抽离到外部启动类中,原因在于有可能在多个地方都需要进行参数校验,而这里有可能需要配置多个类文件。 * @param aClass * @return */ @Override public boolean supports(Class aClass) { return IdWorkerProperties.class.isAssignableFrom(aClass); } @Override public void validate(Object target, Errors errors) { IdWorkerProperties config = (IdWorkerProperties) target; if (config.getWorkerId() > 10) { errors.rejectValue("workerId", "", "worker-id to big(less than 10)"); } if (config.getDatacenterId() > 10) { errors.rejectValue("datacenterId", "", "datacenter-id to big(less than 10)"); } } } 3、项目启动类增加 @Bean 注解, 注意这里的方法名称必须定义为: configurationPropertiesValidator 可以通过创建一个叫做configurationPropertiesValidator的bean来添加自定义的Spring Validator。 @Bean方法需要声明为static,因为配置属性校验器在应用程序生命周期中创建的比较早, 将@Bean方法声明为static允许该bean在创建时不需要实例化@Configuration类,从而避免了早期实例化(early instantiation)的所有问题。 @Bean public static PapConfigPropertiesValidator configurationPropertiesValidator() { return new PapConfigPropertiesValidator(); } # jackson 属性过滤 PropertyFilter BeanPropertyWriter 启动类( implements WebMvcConfigurer )增加如下代码: @Autowired private RequestMappingHandlerAdapter requestMappingHandlerAdapter; @Bean public HandlerMethodReturnValueHandler completableFutureReturnValueHandler() { return new PapJacksonFilterReturnHandler(); } @PostConstruct public void init() { final List originalHandlers = new ArrayList<>( requestMappingHandlerAdapter.getReturnValueHandlers()); final int deferredPos = obtainValueHandlerPosition(originalHandlers, DeferredResultMethodReturnValueHandler.class); // Add our handler directly after the deferred handler. originalHandlers.add(deferredPos + 1, completableFutureReturnValueHandler()); requestMappingHandlerAdapter.setReturnValueHandlers(originalHandlers); } private int obtainValueHandlerPosition(final List originalHandlers, Class handlerClass) { for (int i = 0; i < originalHandlers.size(); i++) { final HandlerMethodReturnValueHandler valueHandler = originalHandlers.get(i); if (handlerClass.isAssignableFrom(valueHandler.getClass())) { return i; } } return -1; } controller测试部分代码增加对应注解: @PapFilterJSONAnnotation(type = DictDTO.class , filter="createIp,modifyIp,clientLicenseId") @PapFilterJSONAnnotation(type = DictDetailDTO.class, filter="createIp,modifyIp,clientLicenseId") # 日期格式化 - 全局 Springboot 已经为我们提供了日期格式化 ${spring.jackson.date-format:yyyy-MM-dd HH:mm:ss}, 这里我们需要进行全局配置,配置比较简单,也无需在实体类属性上添加@JsonFormat注解。 @Configuration public class LocalDateTimeSerializerConfig { @Value("${spring.jackson.date-format:yyyy-MM-dd HH:mm:ss}") private String pattern; @Bean public LocalDateTimeSerializer localDateTimeDeserializer() { return new LocalDateTimeSerializer(DateTimeFormatter.ofPattern(pattern)); } @Bean public Jackson2ObjectMapperBuilderCustomizer jackson2ObjectMapperBuilderCustomizer() { return builder -> builder.serializerByType(LocalDateTime.class, localDateTimeDeserializer()); } } 这种方式可支持 Date 类型和 LocalDateTime 类型并存,那么有一个问题就是现在全局时间格式是yyyy-MM-dd HH:mm:ss, 但有的字段却需要yyyy-MM-dd格式咋整?那就需要配合@JsonFormat注解使用,在特定的字段属性添加@JsonFormat注解即可, 因为@JsonFormat注解优先级比较高,会以@JsonFormat注解标注的时间格式为主。