springboot数据格式验证——自定义日期格式验证及list验证

本文介绍了如何在SpringBoot项目中自定义日期格式验证注解,包括创建`@DateFormat`注解、验证逻辑处理类及在控制器层的应用,同时提及了List集合校验的方法。

我们在工作中经常需要对日期格式进行定义,如果客户端传来的日期字符串不符合要求,那么根本无法保存,但是已有的注解并没有日期格式的验证,那我们就自己实现一个

一、自定义日期格式验证的注解@DateFormat

import javax.validation.Constraint;
import javax.validation.Payload;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 * @Author: LiuXingJie
 * @Description:
 * @Date Create in 9:32 2023/12/1
 * @Modified By:
 */
@Target({ElementType.PARAMETER, ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = DateFormatValidator.class)
public @interface DateFormat {
    String message() default "日期格式错误";

    String format() default "yyyy-MM-dd";

    Class<?>[] groups() default {};

    Class<? extends Payload>[] payload() default {};
}

二、验证逻辑处理类

import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeFormatterBuilder;
import java.time.temporal.ChronoField;

/**
 * @Author: best_liu
 * @Description:
 * @Date Create in 9:32 2023/12/1
 * @Modified By:
 */
public class DateFormatValidator implements ConstraintValidator<DateFormat, String> {

    private DateFormat dateFormat;

    @Override
    public void initialize(DateFormat dateFormat) {
        this.dateFormat = dateFormat;
    }

    @Override
    public boolean isValid(String s, ConstraintValidatorContext constraintValidatorContext) {
        String format = dateFormat.format();
        if (format.equals("yyyy-MM")) {
            DateTimeFormatter dtf1 = new DateTimeFormatterBuilder()
                    .appendPattern(format)
                    .parseDefaulting(ChronoField.DAY_OF_MONTH, 1)
                    .toFormatter();
            try {
                LocalDate.parse(s, dtf1);
            } catch (Exception e) {
                return false;
            }
        } else {
            SimpleDateFormat simpleDateFormat = new SimpleDateFormat(format);
            try {
                simpleDateFormat.parse(s);
            } catch (Exception e) {
                return false;
            }
        }
        return true;
    }
}

这个月数据yyyy-MM需要特殊处理的原因在于,如果提供的是yyyy-MM-dd的格式的字符串,使用SimpleDateFormat("yyyy-MM")去解析也不会失败

三、自定义注解的应用

@ApiModelProperty("化验时间")
    @NotBlank(message = "assayTime是必填项")
    @DateFormat(format = "yyyy-MM-dd HH:mm:ss",message = "日期格式错误,正确格式为yyyy-MM-dd HH:mm:ss")
    private String assayTime;

四、controller层的使用 

然后在controller方法中用@RequestBody表示这个参数接收的类

@PostMapping("/save")
    @RequiredLog(methodType="1")
    public AjaxResult save(@RequestBody @Validated ProcessQualityAlarm processQualityAlarm) {

        return processQualityAlarmService.saveInfo(processQualityAlarm);
    }

五、最终效果

六、SpringBoot关于List集合的校验

 1、针对List集合的校验有两种方案

1)在controller上添加@Validated

2)则集合校验变成如下方式

 3)QualityAlarmVo如下

@Data
public class QualityAlarmVo {
    @NotBlank(message = "assayTime是必填项")
    @DateFormat(format = "yyyy-MM-dd HH:mm:ss",message = "日期格式错误,正确格式为yyyy-MM-dd HH:mm:ss")
    private String assayTime;
    @NotBlank(message = "factoryArea是必填项")
    private String factoryArea;
    @NotBlank(message = "qualityPositionName是必填项")
    private String qualityPositionName;
    @NotEmpty
    private List<@NotNull @Valid ProcessQualityAlarm> list;
}

4)效果

### 如何在Spring Boot项目中使用POITL库通过自定义生成策略来合并Word文档中的单元格 #### 1. POITL概述与依赖配置 `poi-tl` 是基于 Apache POI 的扩展工具包,用于简化 Word 和 Excel 文档的操作。它提供了强大的模板解析能力,支持动态数据填充、表格生成等功能[^1]。 为了实现单元格合并的功能,在 `Spring Boot` 项目中引入必要的依赖项: ```xml <dependency> <groupId>cn.afterturn</groupId> <artifactId>easypoi-base</artifactId> <version>4.4.0</version> </dependency> <dependency> <groupId>cn.hutool</groupId> <artifactId>hutool-all</artifactId> <version>5.8.20</version> </dependency> ``` 以上依赖包含了 `easypoi` 及其基础组件,以及辅助开发的 `Hutool` 工具集[^1]。 --- #### 2. 自定义生成策略类 要实现单元格合并功能,可以通过继承 `AbstractWordExportorHandler` 或者重写默认的生成逻辑完成自定义操作。以下是具体代码示例: ```java import cn.afterturn.easypoi.word.entity.params.ExcelListEntity; import cn.afterturn.easypoi.word.export.handler.IExcelExportServer; import org.apache.poi.xwpf.usermodel.XWPFTableCell; import java.util.List; public class CustomMergeStrategy implements IExcelExportServer { @Override public void createCell(XWPFTableCell cell, Object data) { // 定义单元格创建后的处理逻辑 if (data instanceof List<?>) { List<?> dataList = (List<?>) data; int size = dataList.size(); if (size > 1 && dataList.get(0).equals(dataList.get(size - 1))) { // 如果首尾相同,则设置跨行/列属性 cell.getCTTc().addNewTcPr().addNewVMerge().setVal("restart"); } else { cell.getCTTc().addNewTcPr().addNewVMerge().setVal("continue"); } } } @Override public boolean isCreateCell(Object entity, String title) { return true; // 默认返回true表示所有字段都需要创建对应的单元格 } } ``` 此代码片段展示了如何通过覆盖方法来自定义单元格的行为,并利用 Poi-TL 提供的 API 实现单元格合并[^1]。 --- #### 3. 使用模板文件进行渲染 假设已经准备好了带有占位符 `${}` 的 `.docx` 文件作为模板,可以按照如下方式调用服务层接口完成最终输出: ```java import cn.afterturn.easypoi.word.WordExportUtil; import org.apache.poi.xwpf.usermodel.XWPFDocument; import org.springframework.core.io.ClassPathResource; import javax.servlet.http.HttpServletResponse; import java.io.*; import java.util.HashMap; import java.util.Map; public class WordGeneratorService { public static void export(HttpServletResponse response) throws IOException { Map<String, Object> map = new HashMap<>(); // 动态数据填充到map对象里 map.put("title", "测试标题"); ClassPathResource resource = new ClassPathResource("/templates/example.docx"); InputStream inputStream = resource.getInputStream(); XWPFDocument document = WordExportUtil.exportWithTemplate(inputStream, map, false); OutputStream out = null; try { File tempFile = File.createTempFile("output-", ".docx"); FileOutputStream fos = new FileOutputStream(tempFile); // 将document保存至临时文件流 document.write(fos); fos.close(); // 设置响应头以便浏览器下载 response.setHeader("Content-Disposition", "attachment; filename=exported_file.docx"); response.setContentType("application/vnd.openxmlformats-officedocument.wordprocessingml.document"); out = response.getOutputStream(); FileInputStream fis = new FileInputStream(tempFile); byte[] buffer = new byte[1024]; while ((fis.read(buffer)) != -1) { out.write(buffer); } fis.close(); } finally { if (out != null) { out.flush(); out.close(); } } } } ``` 上述代码实现了从模板加载、数据注入到最后导出整个流程[^1]。 --- #### 4. 测试效果验证 运行程序后访问对应 URL 地址即可触发文件下载动作,打开生成好的 `.docx` 文件确认是否满足预期需求——即某些特定区域内的多个连续单元格被成功合并且显示单一值。 ---
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值