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
相关产品推荐
相关产品推荐

