Repository navigation
Module Web
本页回答:
coco-features/coco-web(框架里最大的模块,144 个主类)有哪些子能力、过滤器顺序、可替换的扩展点、自动配置注册、以及coco.web.*配置属性与默认值。 依据:pom.xml、src/main/java与META-INF实读,内容对应仓库main分支;密钥映射只写键名与结构,不写任何密钥值。
| 项 | 内容 |
|---|---|
| 坐标 / 路径 |
io.github.patton174:coco-web,coco-features/coco-web
|
| 职责 | pom 描述为“统一响应与异常处理的 Web 功能实现”;AGENTS.md 的范围更完整:Servlet Web 集成,含响应封装、异常响应处理、Trace、请求上下文、访问日志、签名、加密、进程内重放保护,以及显式选择的 JDBC 重放存储参考实现 |
| 依赖 |
coco-context、coco-exception、coco-i18n、coco-logging、coco-spring-boot-autoconfigure;spring-web、spring-webmvc、jackson-databind、jakarta.servlet-api、slf4j-api
|
| optional |
spring-boot-starter-data-redis、spring-boot-jdbc、spring-jdbc(Redis / JDBC 重放存储才需要) |
| 测试 |
src/test 22 个 *Test 类;测试依赖含 h2
|
| Feature |
web,运行期由 @ConditionalOnCocoFeature(CocoFeature.WEB) 控制;模块级没有总开关,各子能力有自己的 enabled
|
| 包 |
io.github.coco.feature.web.*(Java 包名带 feature,与 artifactId coco-web 不同) |
CocoWebFeature 是只有私有构造器的空标记类。
下表为各 FilterRegistrationBean 的 setOrder 实读值(数字越小越靠前)。coco-security 的过滤器也在这个序列里。
| 顺序 | Bean(@ConditionalOnMissingBean(name=...)) |
过滤器 | 默认是否注册 |
|---|---|---|---|
HIGHEST_PRECEDENCE |
cocoRequestBodyCachingFilterRegistration |
CocoRequestBodyCachingFilter |
是(coco.web.request-body.enabled,缺省 true) |
HIGHEST_PRECEDENCE(可由 order 调整) |
cocoSecurityHeadersFilterRegistration |
CocoSecurityHeadersFilter |
是(coco.web.security-headers.enabled,缺省 true) |
+1 |
cocoTraceFilterRegistration |
CocoTraceFilter |
是(coco.web.trace.enabled,缺省 true) |
+2 |
cocoReplayRequestShapeFilterRegistration |
CocoReplayRequestShapeFilter |
是(coco.web.replay.enabled,缺省 true) |
+3 |
cocoSignatureFilterRegistration |
CocoSignatureFilter |
是(coco.web.signature.enabled,缺省 true) |
+4 |
cocoEncryptionFilterRegistration |
CocoEncryptionFilter |
是(coco.web.encryption.enabled,缺省 true) |
+5 |
cocoReplayFilterRegistration;coco-security 的 cocoSecurityWebFilterRegistration
|
CocoReplayFilter;CocoSecurityWebFilter
|
是 |
签名、加密、重放的 required 默认都是 false:只有请求带了相应元数据才会校验,不会拒绝没有签名的请求。各过滤器仅在 @ConditionalOnWebApplication(type = SERVLET) 下注册。
签名、加密、重放三者各有一组 matcher.required|ignored 规则列表(默认空,类型 CocoWebRequestMatchRule,由 CocoWebRequestMatcher 判定),用来按路径等条件强制或排除校验。匹配语义取自 DefaultCocoWebRequestMatcher 与 CocoWebRequestMatchRule 源码:
- 一条规则含
methods(HTTP 方法集合,统一转大写,大小写无关)与path-patterns(SpringAntPathMatcher模式,缺少前导/时自动补上);两者同时配置时必须同时匹配,任意一侧为空表示不限制该侧。 - 两侧都为空的规则会被丢弃;规则列表为空时永远不命中;列表中任一规则命中即视为命中。
- 匹配路径取请求 URI,去掉 context-path 之后参与匹配。
-
ignored命中的请求会跳过对应的签名 / 加密 / 重放过滤逻辑;required命中的请求等同于该功能required=true,即缺少元数据时拒绝请求。
另外有一个 Spring MVC 拦截器:CocoPageInterceptor(web.page),由 cocoPageMvcConfigurer 注册,把 page / size / sort 查询参数写入 CocoPageContextHolder,afterCompletion 里清除,防止线程池复用泄漏。
META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports:
| 顺序 | 自动配置 | 说明 |
|---|---|---|
| 1 | io.github.coco.feature.web.CocoWebJdbcReplayAutoConfiguration |
before = CocoWebAutoConfiguration、after = JdbcTemplateAutoConfiguration;条件:@ConditionalOnCocoFeature(WEB)、JdbcOperations 类存在且单一候选、coco.web.replay.store-type=jdbc;Bean JdbcCocoReplayStore(destroyMethod=close,@ConditionalOnMissingBean(CocoReplayStore)) |
| 2 | io.github.coco.feature.web.CocoWebRedisReplayAutoConfiguration |
before = CocoWebAutoConfiguration;条件:store-type=redis 且 StringRedisTemplate 存在;Bean redisCocoReplayStore
|
| 3 | io.github.coco.feature.web.CocoWebAutoConfiguration |
before = CocoCommonAutoConfiguration;@EnableConfigurationProperties({CocoWebProperties, CocoCommonProperties});@Import 9 个内部配置 |
| 4 | io.github.coco.feature.web.cors.CocoCorsAutoConfiguration |
coco.web.cors.enabled=true 才生效,默认关闭 |
| 5 | io.github.coco.feature.web.page.CocoPageAutoConfiguration |
coco.web.page.enabled 缺省 true,仅 Servlet |
| 6 | io.github.coco.feature.web.headers.CocoSecurityHeadersAutoConfiguration |
coco.web.security-headers.enabled 缺省 true,需 Filter 类 |
CocoWebAutoConfiguration @Import 的 9 个内部配置(同包,不在 imports 文件中):
| 配置类 | 主要 Bean |
|---|---|
CocoWebI18nAutoConfiguration |
cocoWebLocaleResolver(CocoLocaleResolver)、cocoWebMessageBundleRegistrar(资源包 coco-feature-web-messages) |
CocoWebResponseAutoConfiguration |
CocoSystemCodeProvider、CocoResponseBodyFactory、CocoResponseWrapAdvice(条件 coco.web.response-wrap.enabled) |
CocoWebExceptionAutoConfiguration |
CocoExceptionHttpStatusResolver、CocoWebExceptionHandler、CocoFilterExceptionResponseWriter、CocoWebErrorResponseWriter
|
CocoWebRequestBodyAutoConfiguration |
CocoRequestBodyResolver、请求体缓存过滤器注册 |
CocoWebContextAutoConfiguration |
CocoClientIpResolver、CocoBrowserFingerprintResolver、CocoRequestHeaderResolver、CocoRequestCookieResolver、CocoPayloadParameterResolver、CocoRequestParameterResolver、CocoWebRequestTargetResolver、CocoWebRequestSecurityInputResolver、CocoWebRequestSecurityMetadataResolver、CocoWebRequestContextResolver、CocoWebRequestCanonicalizer、CocoWebRequestMatcher
|
CocoWebTraceAutoConfiguration |
CocoTraceIdValidator、Trace 过滤器注册(注入 CocoAccessLogRecorder) |
CocoWebSignatureAutoConfiguration |
CocoSignatureSecretResolver、CocoSignatureVerifier、签名过滤器注册 |
CocoWebEncryptionAutoConfiguration |
CocoEncryptionKeyResolver、CocoRequestDecryptor、加密过滤器注册 |
CocoWebReplayAutoConfiguration |
CocoReplayKeyResolver、CocoReplayStore(store-type 缺省 in-memory)、两个重放过滤器注册 |
上面带 @ConditionalOnMissingBean 的 Bean 都可以用同类型 Bean 替换。
下表只列公开类型。
CocoReplayRequestShape、CocoReplayCleanupLifecycle、CocoEncryptionCodecs是包私有类,不属于公开 API。
包(io.github.coco.feature.web. 之后) |
主要类型 |
|---|---|
response |
CocoApiResponse<T>(record:success、code、message、data、traceId、path,后两者 @JsonInclude(NON_NULL);success(...) / error(...) 静态工厂)、CocoResponseWrapAdvice(@RestControllerAdvice,ResponseBodyAdvice<Object>)、CocoIgnoreResponseWrap(注解,@Target({TYPE, METHOD}))、CocoResponseBodyFactory / DefaultCocoResponseBodyFactory、CocoResponseMetadata、CocoResponseMetadataMode(NONE、COOKIE、TRACE、DEBUG)、CocoResponsePayload、CocoSystemCodeProvider(success()、invalidArgument()、unauthorized()、forbidden()、notFound()、conflict()、internalError())/ CocoSystemCodes、CocoResponseProperties、CocoResponseWrapProperties
|
exception |
CocoWebExceptionHandler(@RestControllerAdvice:处理 CocoException、参数类异常、NoHandlerFoundException、HttpRequestMethodNotSupportedException、兜底 Exception)、CocoExceptionHttpStatusResolver / DefaultCocoExceptionHttpStatusResolver、CocoWebErrorResponseWriter、CocoFilterExceptionResponseWriter、CocoFieldError、CocoPayloadTooLargeException(继承 CocoRequestException) |
trace |
CocoTraceFilter、CocoTraceIdValidator / DefaultCocoTraceIdValidator、CocoTraceProperties
|
i18n |
CocoWebLocaleResolver |
body |
CocoRequestBodyCachingFilter、CocoCachedBodyHttpServletRequest、CocoCachedRequestBody、CocoRequestBodyResolver / DefaultCocoRequestBodyResolver、CocoRequestBodyCachingMode(SECURITY_HEADERS、ALWAYS)、CocoRequestBodyStage、CocoRequestBodyMetadata、CocoResolvedRequestBody、CocoRequestBodyProperties
|
context |
CocoWebRequestContextResolver / DefaultCocoWebRequestContextResolver、CocoWebRequestContextPhase(TRANSPORT_CAPTURED、SIGNATURE_VERIFIED、DECRYPTED、REPLAY_VERIFIED)、CocoClientIpResolver(+CocoClientIpResolution、CocoClientIpSource)、CocoBrowserFingerprintResolver(+CocoBrowserFingerprint)、CocoRequestHeaderResolver、CocoRequestCookieResolver、CocoRequestParameterResolver、CocoSensitiveRequestHeaderContributor、CocoWebRequestCanonicalizer(+CocoWebRequestCanonicalForm、CocoWebRequestCanonicalizationContext、...Purpose)、CocoWebRequestMatcher(+CocoWebRequestMatchRule)、CocoWebRequestSnapshot、CocoWebContextProperties、CocoWebParameterProperties、CocoWebRequestMatcherProperties、CocoWebRequestCanonicalizationProperties 等,各有 Default* 实现 |
context.payload |
CocoPayloadParameterResolver / DefaultCocoPayloadParameterResolver、CocoWebPayloadParseResult、CocoWebPayloadParseStatus、CocoPayloadParameterProperties
|
context.target |
CocoWebRequestTargetResolver / DefaultCocoWebRequestTargetResolver、CocoWebRequestTarget、CocoWebRequestTargetResolution、CocoWebRequestTargetSource、CocoWebRequestTargetProperties
|
request.metadata |
CocoWebRequestSecurityMetadataResolver、CocoWebRequestSecurityInputResolver(各有 Default*)、CocoWebRequestSecurityMetadata、CocoWebRequestSecurityInput、CocoWebSecurityMetadataSource(含 HEADER) |
signature |
CocoSignatureFilter、CocoSignatureVerifier / HmacSha256CocoSignatureVerifier、CocoSignatureSecretResolver / PropertiesCocoSignatureSecretResolver、CocoSignatureRequest、CocoSignatureSecret、CocoSignatureVerificationContext、CocoSignatureProperties
|
encryption |
CocoEncryptionFilter、CocoRequestDecryptor / AesGcmCocoRequestDecryptor、CocoEncryptionKeyResolver / PropertiesCocoEncryptionKeyResolver、CocoEncryptionKey、CocoEncryptedRequest、CocoRequestDecryptionContext、CocoRequestDecryptException、CocoEncryptionAssociatedData、CocoCryptoTextEncoding、CocoEncryptionProperties
|
replay |
CocoReplayFilter、CocoReplayRequestShapeFilter、CocoReplayStore(唯一方法 boolean reserve(CocoReplayKey key, Instant expiresAt))、InMemoryCocoReplayStore / JdbcCocoReplayStore / RedisCocoReplayStore、CocoReplayKeyResolver / DefaultCocoReplayKeyResolver、CocoReplayKey、CocoReplayStoreType(IN_MEMORY、JDBC、REDIS)、CocoReplayProperties
|
cors |
CocoCorsAutoConfiguration、CocoCorsProperties
|
headers |
CocoSecurityHeadersAutoConfiguration、CocoSecurityHeadersFilter、CocoSecurityHeadersProperties
|
page |
CocoPageAutoConfiguration、CocoPageInterceptor、CocoPageProperties
|
accesslog |
CocoAccessLogCaptureProperties(仅 enabled) |
统一响应由 CocoResponseWrapAdvice 把正常返回值包成 CocoApiResponse。String 转换器场景下会手工序列化成 JSON 字符串。已经是 CocoApiResponse 的返回值不会被二次包装;方法或类上标注 @CocoIgnoreResponseWrap 可跳过;coco.web.response-wrap.max-body-bytes ≥ 0 时,已知长度超过该值的响应体也会跳过包装。设计背景见规格 coco-support/coco-document/superpowers/specs/2026-07-05-coco-web-response-wrap-design.md。
下列接口都带 Default* 或 Properties* 默认实现,并通过 @ConditionalOnMissingBean 暴露,业务声明同类型 Bean 即可替换。
| 想替换的行为 | 接口 / Bean 类型 |
|---|---|
| 系统响应码 | CocoSystemCodeProvider |
| 响应体结构 | CocoResponseBodyFactory |
| 异常 → HTTP 状态 | CocoExceptionHttpStatusResolver |
| TraceId 合法性校验 | CocoTraceIdValidator |
| 请求体读取与解码 | CocoRequestBodyResolver |
| 客户端 IP、浏览器指纹、Header / Cookie / 参数、请求目标解析 |
CocoClientIpResolver、CocoBrowserFingerprintResolver、CocoRequestHeaderResolver、CocoRequestCookieResolver、CocoRequestParameterResolver、CocoWebRequestTargetResolver、CocoPayloadParameterResolver
|
| 请求上下文构建 / 规范化 / 匹配 |
CocoWebRequestContextResolver、CocoWebRequestCanonicalizer、CocoWebRequestMatcher
|
| 安全元数据来源 |
CocoWebRequestSecurityInputResolver、CocoWebRequestSecurityMetadataResolver
|
| 签名密钥 / 算法 |
CocoSignatureSecretResolver、CocoSignatureVerifier
|
| 解密密钥 / 算法 |
CocoEncryptionKeyResolver、CocoRequestDecryptor
|
| 重放键 / 存储 |
CocoReplayKeyResolver、CocoReplayStore(也可以按 store-type 选 JDBC / Redis 实现) |
| 敏感请求头补充 |
CocoSensitiveRequestHeaderContributor(函数式接口,coco-idempotency 用它登记 Idempotency-Key 头) |
| 过滤器自身 | 声明同名 FilterRegistrationBean Bean(名称见 §2 表) |
签名 / 加密密钥属于敏感配置:
coco.web.signature.secrets、coco.web.encryption.keys是Map<String, String>,默认空。文档与示例里只写键名与结构,不要提交真实密钥;生产建议自定义CocoSignatureSecretResolver/CocoEncryptionKeyResolver从密钥管理系统读取。
主入口 CocoWebProperties(前缀 coco.web)的子树:trace、response、response-wrap、access-log、request-body、signature、encryption、replay、context。cors、security-headers、page 是独立的 @ConfigurationProperties 前缀。模块带有 META-INF/additional-spring-configuration-metadata.json。
| 前缀 | 键 → 默认值 |
|---|---|
coco.web.response |
metadata-mode=NONE(NONE / COOKIE / TRACE / DEBUG) |
coco.web.response-wrap |
enabled=true、success-message-code="coco.web.response.success"、max-body-bytes=-1(负数表示不限制) |
coco.web.trace |
enabled=true、header-name="X-Trace-Id"、mdc-key="traceId"、response-header-enabled=true、response-cookie-enabled=false、cookie-name="COCO_TRACE_ID"、cookie-path="/"、cookie-max-age=-1、cookie-http-only=false、cookie-secure=false、cookie-same-site="Lax"、max-length=128、allowed-pattern="[A-Za-z0-9._:-]+"
|
coco.web.access-log |
enabled=true(仅控制 Web 侧采集;输出格式见 coco.logging.access-log.*,在 基础模块) |
| 键 | 默认值 |
|---|---|
coco.web.request-body.enabled |
true |
...mode |
SECURITY_HEADERS(另有 ALWAYS) |
...max-cache-bytes |
1048576(1 MiB) |
...cache-methods |
POST、PUT、PATCH、DELETE
|
...trigger-header-names |
content-md5、x-coco-sign、x-coco-signature、x-coco-encrypted
|
...included-content-types |
application/json、application/*+json、text/plain、application/xml、text/xml
|
...excluded-content-type-prefixes |
multipart/、application/octet-stream
|
| 键 | 默认值 |
|---|---|
client-ip-header-names |
Forwarded、X-Forwarded-For、X-Real-IP、Proxy-Client-IP、WL-Proxy-Client-IP、HTTP_CLIENT_IP、HTTP_X_FORWARDED_FOR
|
trusted-proxy-cidrs |
空 |
include-headers |
true |
included-header-names |
host、content-type、user-agent、accept、accept-language、referer、origin
|
masked-header-names |
authorization、cookie、set-cookie、x-api-key、x-auth-token
|
security-header-names |
content-md5、content-type、x-coco-app-id、x-coco-timestamp、x-coco-nonce、x-coco-sign、x-coco-signature、x-coco-encrypted、x-coco-key-id、x-coco-iv、x-coco-algorithm、x-coco-sign-algorithm
|
canonical-header-names |
content-md5、content-type、x-coco-app-id、x-coco-timestamp、x-coco-nonce、x-coco-key-id、x-coco-iv、x-coco-algorithm、x-coco-sign-algorithm
|
fingerprint-header-names |
user-agent、accept、accept-language、dnt、sec-ch-ua、sec-ch-ua-mobile、sec-ch-ua-platform、sec-ch-ua-platform-version、sec-ch-ua-arch、sec-ch-ua-bitness、sec-ch-ua-model、sec-ch-ua-full-version-list
|
max-header-value-length |
256 |
included-cookie-names / canonical-cookie-names
|
空 |
masked-cookie-names |
jsessionid、session、sessionid、token、access_token、refresh_token
|
max-cookie-value-length |
128 |
parameter.include-parameters / parameter.max-parameter-value-length
|
true / 256
|
parameter.masked-parameter-names |
password、passwd、pwd、secret、token、access_token、refresh_token、authorization
|
parameter.payload.enabled |
true;included-content-types:application/json、application/*+json、application/x-www-form-urlencoded;max-json-depth=8;max-parameter-count=128
|
target.proto-header-names |
X-Forwarded-Proto、X-Forwarded-Protocol、X-Forwarded-Ssl、Front-End-Https
|
target.host-header-names / port-header-names / prefix-header-names
|
X-Forwarded-Host、X-Original-Host / X-Forwarded-Port / X-Forwarded-Prefix、X-Forwarded-PathBase、X-Original-Prefix
|
target.apply-forwarded-prefix |
true |
canonicalization.version |
"coco-v2";include-version=false、include-purpose=false、include-method=true、include-path=true、include-query-string=true、include-headers=true、include-cookies=false、include-browser-fingerprint=false、include-browser-fingerprint-signals=false、include-parameters=true、include-parameter-sources=true、include-body-sha256=true、include-body-length=true、sort-parameter-values=true、parameter-value-separator=","
|
trusted-proxy-cidrs 默认为空:不信任任何代理,客户端 IP 的转发头解析是否生效取决于该设置,部署在网关后面时需要显式配置。
| 前缀 | 键 → 默认值 |
|---|---|
coco.web.signature |
enabled=true、required=false、timestamp-required=true、timestamp-validation-enabled=true、max-clock-skew-seconds=300、metadata-source=HEADER、default-algorithm="HMAC-SHA256"、secrets(Map,默认空)、`matcher.required |
coco.web.encryption |
enabled=true、required=false、metadata-source=HEADER、default-algorithm="AES-GCM"、gcm-tag-length-bits=128、key-encoding / iv-encoding / payload-encoding=BASE64、keys(Map,默认空)、matcher.*。头名:X-Coco-Encrypted、X-Coco-App-Id、X-Coco-Key-Id、X-Coco-IV、X-Coco-Algorithm;参数名:encrypted、appId、keyId、iv、algorithm、payload
|
coco.web.replay |
enabled=true、required=false、protect-signed-requests=true、protect-encrypted-requests=true、include-method=true、include-path=true、store-type=IN_MEMORY、metadata-source=HEADER、ttl-seconds=300、cleanup-interval-seconds=60、max-clock-skew-seconds=300、jdbc.table-name="coco_replay_key"、redis.key-prefix="coco:replay:"、matcher.*;元数据头与参数名同签名(X-Coco-App-Id / X-Coco-Key-Id / X-Coco-Timestamp / X-Coco-Nonce) |
重放存储的取舍:默认 IN_MEMORY 是进程内存储,多实例部署需要换成共享存储。JDBC 是显式选择的参考实现(见规格 2026-07-10-coco-jdbc-replay-store.md);REDIS 使用 Lua 脚本。redis 子树另有 template-bean-name(指定要使用的 StringRedisTemplate Bean 名,默认未设置)。
| 前缀 | 键 → 默认值 |
|---|---|
coco.web.cors |
enabled=false、allowed-origins=["*"]、allowed-methods=[GET, POST, PUT, DELETE, OPTIONS]、allowed-headers=["*"]、exposed-headers=[]、allow-credentials=false、max-age=1800
|
coco.web.security-headers |
enabled=true、order=Ordered.HIGHEST_PRECEDENCE、content-type-options="nosniff"、frame-options="DENY"、referrer-policy="strict-origin-when-cross-origin";content-security-policy、permissions-policy、strict-transport-security 默认不设置 |
coco.web.page |
enabled=true、page-parameter-name="page"、size-parameter-name="size"、default-page=1、default-size=20、max-size=100、sort-parameter-name="sort"
|
分页拦截器对 page / size 做边界校验(page < 1 与 size 超过 max-size 的处理见 CocoPageInterceptor 源码),sort 参数形如 字段,desc,解析为 CocoSortOrder 列表(缺省升序)。与 coco-mybatis-plus 的配合见 数据与安全类 Feature。
coco-features/coco-web/src/test 下 22 个 *Test。运行单模块测试:mvn -pl :coco-web -am test(需要 JDK 21,见 快速开始)。
- 官网用户文档:web-runtime、request-security、pagination
- 设计规格:
coco-support/coco-document/superpowers/specs/2026-07-05-coco-web-response-wrap-design.md、2026-07-10-coco-jdbc-replay-store.md、2026-07-08-coco-web-server-framework-boundary.md
仓库 · CHANGELOG · CONTRIBUTING · GOVERNANCE · SECURITY · 许可证 Apache-2.0
本 Wiki 镜像自仓库的 docs/wiki 目录,请通过 PR 修改,不要在网页上直接编辑。
开始
架构
模块参考
约定与指南
速查与排障
仓库