DDK Web Starter
Web 层的默认件:统一的
ApiResponse异常处理、以 customizer 方式参与的 Jackson 默认行为、默认关闭且可配置的跨域,并聚合 Spring MVC 与 Bean Validation 依赖。
能做什么
全局异常处理
BaseExceptionHandler:把异常翻译成ApiResponse,状态码与真实原因一致,响应里不泄漏原始异常信息。异常 状态码 codeBusinessException400 业务错误码,消息按参数填充 ConcurrentUpdateException、AggregateBusyException、DuplicateRequestException409 CONCURRENT_UPDATE、AGGREGATE_BUSY、DUPLICATE_REQUESTSystemException500 系统错误码 BindException(含@Valid请求体)400 VALIDATION_ERROR,消息列出每个字段ConstraintViolationException400 VALIDATION_ERRORTypeMismatchException(路径变量、查询参数转换失败)400 VALIDATION_ERROR,如id: must be LongHttpMessageNotReadableException(坏 JSON)400 MALFORMED_REQUESTSpring MVC 自身的 ErrorResponse(405、415、404…)沿用原状态码 状态名,如 METHOD_NOT_ALLOWED其他未预料的异常 500 SYSTEM_ERROR,只返回通用文案,完整堆栈写日志Jackson 默认行为:基于 Jackson 3,以
JsonMapperBuilderCustomizer参与构建,不替换JsonMapperBean,spring.jackson.*照常生效。- 时间序列化为 ISO-8601 字符串(Jackson 3 已内置 Java 时间类型支持);
- 忽略请求体里的未知字段,前端多传一个字段不会打挂后端;
Long/long序列化为 JSON 字符串(可关闭)。雪花 ID 超出 JavaScript 能精确表示的 2^53,数字形式在浏览器里会被静默改成另一个值。
diff- {"id": 2100517430039306240} 浏览器解析为 2100517430039306200 + {"id": "2100517430039306240"}接口文档里的错误约定:应用引入 springdoc 后自动生效(可用
ddk.web.openapi=false关闭)。全局异常处理器返回的是ResponseEntity,springdoc 推断不出错误响应,生成的文档里每个接口只有 200。本 starter 补上:- 每个接口的
400、409、500响应,响应体是ApiErrorResponse(失败时的ApiResponse);接口自己声明过的响应不覆盖; components.schemas.ErrorCode:全部错误码的枚举,描述里附「错误码—消息」表。来源是CommonError加上应用包下所有实现了ErrorCode的枚举,第一次生成文档时扫描;- 成功响应不需要处理,springdoc 会按泛型把
ApiResponse<UserResponse>展开成带具体data类型的 schema。
xml<dependency> <groupId>org.springdoc</groupId> <artifactId>springdoc-openapi-starter-webmvc-ui</artifactId> <!-- 版本由 DDK 的 BOM 管理 --> </dependency>- 每个接口的
跨域:默认关闭;开启后按
ddk.web.cors.*配置。同时设置allow-credentials=true与allowed-origins=*时启动失败——那等于让任意站点带着用户凭证调用接口。依赖聚合:
spring-boot-starter-webmvc、spring-boot-starter-validation、ddk-core。不再强制带上 springdoc 与 Swagger UI,需要接口文档时自行引入。
引入方式
xml
<dependency>
<groupId>com.ddk</groupId>
<artifactId>ddk-web-starter</artifactId>
<version>${ddk.version}</version>
</dependency>配置项
| 配置项 | 类型 | 默认值 | 说明 |
|---|---|---|---|
ddk.web.exception-handler | boolean | true | 是否注册全局异常处理器 |
ddk.web.jackson | boolean | true | 是否应用 DDK 的 Jackson 默认行为 |
ddk.web.write-long-as-string | boolean | true | Long / long 是否序列化为字符串,需 ddk.web.jackson 启用 |
ddk.web.openapi | boolean | true | 引入 springdoc 时,是否为接口文档补上错误响应与错误码清单 |
ddk.web.cors.enabled | boolean | false | 是否开启跨域 |
ddk.web.cors.path-pattern | String | /** | 生效路径 |
ddk.web.cors.allowed-origins | List | 空 | 允许的来源,支持通配模式如 https://*.acme.com |
ddk.web.cors.allowed-methods | List | GET, POST, PUT, PATCH, DELETE, OPTIONS | 允许的方法 |
ddk.web.cors.allowed-headers | List | * | 允许的请求头 |
ddk.web.cors.exposed-headers | List | 空 | 浏览器可读取的响应头,例如 X-Trace-Id |
ddk.web.cors.allow-credentials | boolean | false | 是否允许携带凭证 |
ddk.web.cors.max-age | Duration | 1h | 预检结果缓存时间 |
yaml
ddk:
web:
cors:
enabled: true
allowed-origins: [ "https://admin.acme.com" ]
exposed-headers: [ "X-Trace-Id" ]装配条件与降级行为
- 自动配置类:
com.ddk.web.config.WebAutoConfiguration,@ConditionalOnWebApplication(SERVLET),排在 Boot 的JacksonAutoConfiguration与WebMvcAutoConfiguration之前。 baseExceptionHandler:@ConditionalOnMissingBean,应用自己声明同类型 Bean 即可替换。ddkCorsConfigurer:按 Bean 名判定是否已存在,应用里其他WebMvcConfigurer(拦截器、消息转换器)不会让它消失。- 本 starter 不携带任何日志配置文件,日志完全由应用自己决定。
- 本 starter 不依赖外部组件,没有「组件不可用」的降级路径。
不适用的场景 / 已知问题
- 不支持 WebFlux,响应式栈用不上本 starter。
- 开启
write-long-as-string后,计数、时间戳等 64 位整数也以字符串返回。规则按类型统一处理,不区分字段含义;前端需要按字符串解析,或在不需要时关闭。 - 错误码是枚举名字符串(
VALIDATION_ERROR、USER_NOT_FOUND),不是数字编码。 - 接口文档里的错误码是整个 API 一份清单,没有细到每个接口:哪个用例会抛哪个错误码只有领域层知道,而适配层不能引用领域类型。
- 校验失败的消息是拼接后的字符串,没有逐字段的结构化列表。