You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring MVC Rest多参数URL:运输管理系统日报表接口开发求助

实现Spring框架下的日报表接口方案

嘿,既然你已经搞定了Spring Data的新增接口,那这个日报表接口就很顺手了,我给你拆解成几个关键步骤:

1. 创建统计结果的DTO类

首先我们需要一个专门的类来封装返回的统计数据,这样Spring就能自动把它序列化成JSON:

public class DailyReportDto {
    private String totalDistance;
    private String totalPrice;

    // 全参构造方法
    public DailyReportDto(String totalDistance, String totalPrice) {
        this.totalDistance = totalDistance;
        this.totalPrice = totalPrice;
    }

    // Getter方法(必须要有,否则JSON序列化会失败)
    public String getTotalDistance() {
        return totalDistance;
    }

    public String getTotalPrice() {
        return totalPrice;
    }
}

注意:Spring默认会把小驼峰字段映射成JSON的下划线格式(比如totalDistance对应total_distance),如果你的配置没开启这个规则,也可以给字段加@JsonProperty("total_distance")注解指定键名。

2. 在Spring Data Repository中添加统计查询方法

假设你的运输记录实体类是TransitRecord,包含distance(距离)、price(价格)、createTime(记录创建时间,用于日期筛选)字段,那可以在对应的Repository里添加统计方法:

public interface TransitRecordRepository extends JpaRepository<TransitRecord, Long> {
    // 统计指定日期范围内的总距离
    @Query("SELECT SUM(t.distance) FROM TransitRecord t WHERE t.createTime BETWEEN :startDate AND :endDate")
    BigDecimal sumTotalDistance(@Param("startDate") LocalDate startDate, @Param("endDate") LocalDate endDate);

    // 统计指定日期范围内的总价格
    @Query("SELECT SUM(t.price) FROM TransitRecord t WHERE t.createTime BETWEEN :startDate AND :endDate")
    BigDecimal sumTotalPrice(@Param("startDate") LocalDate startDate, @Param("endDate") LocalDate endDate);
}

这里用BigDecimal是因为金额、距离涉及精度问题,比Double更可靠;如果你的字段是Integer等其他类型,对应修改即可。

3. 编写Controller层处理GET请求

接下来写Controller接收请求参数,调用Repository统计数据,最后返回DTO:

@RestController
@RequestMapping("/reports")
public class ReportController {

    private final TransitRecordRepository transitRecordRepository;

    // 构造注入(Spring推荐的依赖注入方式)
    public ReportController(TransitRecordRepository transitRecordRepository) {
        this.transitRecordRepository = transitRecordRepository;
    }

    @GetMapping("/daily")
    public ResponseEntity<DailyReportDto> getDailyReport(
            @RequestParam("start_date") @DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate startDate,
            @RequestParam("end_date") @DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate endDate) {
        
        // 调用Repository统计数据
        BigDecimal totalDistance = transitRecordRepository.sumTotalDistance(startDate, endDate);
        BigDecimal totalPrice = transitRecordRepository.sumTotalPrice(startDate, endDate);

        // 处理统计结果为null的情况(比如无符合条件的记录)
        String distanceStr = totalDistance != null ? totalDistance.toString() : "0";
        String priceStr = totalPrice != null ? totalPrice.toString() : "0";

        // 构造返回的DTO
        DailyReportDto reportDto = new DailyReportDto(distanceStr, priceStr);

        return ResponseEntity.ok(reportDto);
    }
}

*这里的关键点:

  • 用@DateTimeFormat指定参数的日期格式,确保Spring能正确把字符串转成LocalDate
  • 处理统计结果为null的情况,避免返回null给前端,默认返回"0"更友好
  • 用ResponseEntity可以灵活控制HTTP状态码,比如日期参数格式错误时,Spring会自动返回400错误*

4. 额外优化建议

  • 参数校验:可以加@NotNull注解确保start_date和end_date不为空,配合@Validated开启校验:
    @Validated
    @RestController
    @RequestMapping("/reports")
    public class ReportController {
        @GetMapping("/daily")
        public ResponseEntity<DailyReportDto> getDailyReport(
                @RequestParam("start_date") @NotNull @DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate startDate,
                @RequestParam("end_date") @NotNull @DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate endDate) {
            // ... 逻辑不变
        }
    }
    
  • 日期范围合理性校验:可以在方法里判断startDate是否晚于endDate,如果是就返回400错误:
    if (startDate.isAfter(endDate)) {
        return ResponseEntity.badRequest().body(null);
        // 也可以返回自定义的错误信息DTO
    }
    

这样整个接口就实现完成了,测试时直接请求http://example.com/reports/daily?start_date=2024-05-01&end_date=2024-05-01就能得到你要的JSON结果啦!

内容的提问来源于stack exchange,提问作者D.Zet

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 04:14:23