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

如何创建接收指定JSON的Spring Boot微服务满足约束实现接口

Spring Boot 微服务实现分步指南

全程不用搞复杂配置,新手按步骤搭就能跑通:

第一步:搭项目骨架

直接从Spring官方初始化工具生成项目,选这几个必备依赖就行:

  • Spring Web:支撑REST接口对外提供服务
  • Spring Data JPA:处理数据存储逻辑,不用手写基础SQL
  • H2 Database:内存数据库,本地调试不用额外装MySQL,启动就能用
  • Validation:做参数合法性校验
  • Lombok(可选):自动生成get/set方法,少写样板代码
    项目生成后直接启动,确认8080端口能正常跑起来不报错就算第一步完成。

第二步:定义核心数据结构

对应你给出的JSON结构,存数据时要额外加自增主键id,注意给totalCount加上范围校验规则:

@Entity
@Data
public class IpRecord {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id; // 存储时自动生成的记录id
    private String type;
    private String value;
    private String firstSeen;
    @Min(0)
    @Max(100) // 直接用注解限制取值范围,框架自动拦截非法值
    private Integer totalCount;
}

注意:不要直接用这个实体类接前端请求参数,单独写个字段完全一致的RecordRequest DTO类接参,避免被恶意传参篡改id。

第三步:实现日期格式转换逻辑

这部分是需求核心,不要用Spring默认的单格式日期解析,自己写个工具类实现多格式兼容+统一转ISO 8601:

  • 把常用的日期格式(比如yyyy-MM-dd HH:mm:ss.SSS、yyyy/MM/dd、yyyyMMdd、yyyy-MM-dd'T'HH:mm:ss等)都放到候选格式列表里
  • 接收到firstSeen参数后,循环用所有候选格式尝试解析,只要解析成功就转成UTC时区的ISO 8601标准格式字符串
  • 所有格式都解析失败时直接抛出参数非法异常,后续统一返回错误响应
    参考实现代码:
public class DateConvertUtil {
    private static final List<DateTimeFormatter> CANDIDATE_FORMATS = Arrays.asList(
            DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS"),
            DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"),
            DateTimeFormatter.ofPattern("yyyy/MM/dd"),
            DateTimeFormatter.ofPattern("yyyyMMdd"),
            DateTimeFormatter.ISO_LOCAL_DATE_TIME
    );
    private static final DateTimeFormatter ISO_FORMATTER = DateTimeFormatter.ISO_OFFSET_DATE_TIME;

    public static String convertToIso8601(String dateStr) {
        for (DateTimeFormatter format : CANDIDATE_FORMATS) {
            try {
                LocalDateTime parsedTime = LocalDateTime.parse(dateStr, format);
                return parsedTime.atOffset(ZoneOffset.UTC).format(ISO_FORMATTER);
            } catch (Exception ignored) {}
        }
        throw new IllegalArgumentException("传入日期格式非法,无法解析");
    }
}

第四步:写数据访问层

直接继承JPA提供的基础Repository接口,不用自己写实现,框架会自动按方法名生成查询逻辑:

public interface RecordRepository extends JpaRepository<IpRecord, Long> {
    // 自动实现按value字段匹配查询的逻辑
    List<IpRecord> findAllByValue(String value);
}

本地调试可以在配置文件加两行配置开启H2控制台,启动后访问/h2-console就能直接看到存进去的数据,排查问题很方便:

spring.datasource.url=jdbc:h2:mem:testdb
spring.h2.console.enabled=true

第五步:实现对外接口

一共两个接口,按RESTful规范写就行:

  • 新增记录接口:用POST方法,路径/api/records
    逻辑:接收到合法请求参数后,调用日期转换工具把firstSeen转成标准ISO格式,调用Repository存数据,返回带自动生成id的完整记录
  • 查询记录接口:用GET方法,路径/api/records
    逻辑:接收请求参数里的value值,调用Repository查询匹配的所有记录返回即可
    参考Controller代码:
@RestController
@RequestMapping("/api/records")
@Validated
public class RecordController {
    @Autowired
    private RecordRepository recordRepository;

    @PostMapping
    public ResponseEntity<IpRecord> addRecord(@Valid @RequestBody RecordRequest request) {
        IpRecord record = new IpRecord();
        record.setType(request.getType());
        record.setValue(request.getValue());
        record.setFirstSeen(DateConvertUtil.convertToIso8601(request.getFirstSeen()));
        record.setTotalCount(request.getTotalCount());
        IpRecord savedRecord = recordRepository.save(record);
        return ResponseEntity.ok(savedRecord);
    }

    @GetMapping
    public ResponseEntity<List<IpRecord>> queryByValue(@RequestParam String value) {
        return ResponseEntity.ok(recordRepository.findAllByValue(value));
    }
}

第六步:加全局异常处理

写个全局异常拦截类,把参数校验失败、日期解析失败的异常统一拦截,返回清晰的错误信息,不要把后台堆栈抛给前端:

@RestControllerAdvice
public class GlobalExceptionHandler {
    @ExceptionHandler({ConstraintViolationException.class, IllegalArgumentException.class})
    public ResponseEntity<Map<String, Object>> handleBadRequest(Exception e) {
        Map<String, Object> resp = new HashMap<>();
        resp.put("code", 400);
        resp.put("msg", e.getMessage());
        return ResponseEntity.badRequest().body(resp);
    }
}

上线前必测场景

写完跑起来后把这几个场景测一遍,确保符合需求:

  • 传totalCount=-1或者totalCount=101,接口返回400错误
  • 传不同格式的firstSeen参数(比如2020/07/10、20200710),存储后的值都是统一的ISO 8601格式
  • 传乱码字符串作为firstSeen,接口返回400日期非法错误
  • 新增记录后传对应value查询,能查到刚新增的记录,返回的id是服务端自动生成的
  • 传不存在的value查询,返回空列表即可

内容的提问来源于stack exchange,提问作者bella

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 02:01:07