ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

x402 Java 实现实战:用 Servlet Filter 构建 HTTP 402 付费墙与 Java 17 客户端

x402 Java 实现实战:用 Servlet Filter 构建 HTTP 402 付费墙与 Java 17 客户端 x402 Java 实现实战用 Servlet Filter 构建 HTTP 402 付费墙与 Java 17 客户端【免费下载链接】x402A payments protocol for the internet. Built on HTTP.项目地址: https://gitcode.com/GitHub_Trending/x4/x402本文是基于 java/README.md 及其配套源码的完整技术指南。x402 是一个构建在 HTTP 之上的去中心化支付协议402正对应 HTTP 状态码Payment Required需要付款。本文将围绕 Java 实现的三大核心组件PaymentFilter、FacilitatorClient、X402HttpClient完整讲解从构建安装、服务端接入付费墙、客户端发起带支付证明的请求到错误处理与底层实现原理的全部内容。读完本文你将掌握如何用纯 Java 17 Servlet 生态为任意 HTTP 资源接入先付费、后访问的能力并与 x402 的 Go、TypeScript 实现保持行为一致。快速开始构建、测试与质量门禁在仓库根目录下进入java模块使用 Maven 即可完成全部构建与质量检查# Build and test mvn clean install # Run tests mvn test # Check code coverage mvn jacoco:report mvn -P coverage verify # Enforces 90% coverage # Check code quality mvn checkstyle:check mvn spotbugs:check以上命令对应 java/pom.xml 中配置的构建管线Java 版本maven.compiler.source/target均为17与 README 的 Java 17 要求一致运行时依赖jackson-databind 2.17.0JSON 序列化、jakarta.servlet-api 6.1.0scope 为provided由 Servlet 容器提供测试依赖junit-jupiter 5.10.2、mockito-junit-jupiter 5.11.0、wiremock 3.13.1模拟外部 HTTP 服务、jetty 12.0.8嵌入式容器做集成测试质量插件maven-checkstyle-plugin 3.4.0校验规则见 java/checkstyle.xml、spotbugs-maven-plugin 4.8.2.0effortMax、thresholdHigh排除规则见 java/spotbugs-exclude.xml、jacoco-maven-plugin 0.8.11。需要说明两点与 README 描述略有出入的事实其一README 顶部徽章标注覆盖率 90%而 pom.xml 中coverageprofile 实际强制执行的阈值是指令覆盖率 ≥ 0.85、分支覆盖率 ≥ 0.75counterINSTRUCTION/counter与counterBRANCH/counter执行mvn -P coverage verify会按此阈值卡关其二README 的 Maven 依赖示例写的是0.1.0-SNAPSHOT而当前 java/pom.xml 声明的版本为1.0.0-SNAPSHOT本地安装后请以pom.xml实际版本号为准。x402 协议与 Java 库的三个核心组件x402 是一个用于API 调用、网页内容和其他 HTTP 资源的去中心化支付系统其命名直接取自 HTTP 状态码402 Payment Required。核心交互是客户端在请求头中携带支付证明X-PAYMENT由独立的Facilitator促进者服务负责验证与结算服务端本身不直接接触链上交易从而保持了实现简洁与可扩展性。Java 库提供了三个核心组件对应 java/src/main/java/org/x402 目录结构组件包路径职责PaymentFilterorg.x402.serverServlet 过滤器认证支付并拒绝未授权请求FacilitatorClientorg.x402.client与 Facilitator 服务交互完成支付验证与结算X402HttpClientorg.x402.client便捷 HTTP 客户端构造并发送带支付证明的请求兼容性Java 17java.net.http.HttpClient原生 API支持 Jakarta Servlet API 或javax.servletPaymentFilter实现标准jakarta.servlet.Filter接口适用于任何 Servlet 容器Tomcat、Jetty 等兼容 Spring Boot、Quarkus 等主流 Java 框架。安装与依赖坐标由于该库未发布到公共 Maven 中央仓库需要先克隆仓库并本地构建安装# Clone the repository git clone https://github.com/x402-foundation/x402.git cd x402/java # Build and install to your local Maven repository mvn clean install然后在你的 Maven 项目中加入依赖dependency groupIdorg.x402/groupId artifactIdx402/artifactId version0.1.0-SNAPSHOT/version /dependency注意如上文所述当前仓库pom.xml中的版本为1.0.0-SNAPSHOT请以mvn install实际安装进本地仓库的版本为准避免坐标不一致导致依赖解析失败。服务端接入用 PaymentFilter 给接口加付费墙服务端的使用方式是定义需要付费的路径与价格表创建HttpFacilitatorClient指向 Facilitator 服务再把PaymentFilter注册进 Servlet 容器import org.x402.server.PaymentFilter; import org.x402.client.HttpFacilitatorClient; import java.math.BigInteger; import java.util.Map; // 1. Define paths that require payment and their prices MapString, BigInteger priceTable Map.of( /api/premium, BigInteger.valueOf(1000), // 1000 wei /content/exclusive, BigInteger.valueOf(500) ); // 2. Create a facilitator client String facilitatorUrl https://x402.org/facilitator; HttpFacilitatorClient facilitator new HttpFacilitatorClient(facilitatorUrl); // 3. Create and register the filter String payToAddress 0xYourReceiverAddress; PaymentFilter paymentFilter new PaymentFilter(payToAddress, priceTable, facilitator); // 4. Register the filter with your servlet container // In a standard servlet app: FilterRegistration.Dynamic registration servletContext.addFilter(paymentFilter, paymentFilter); registration.addMappingForUrlPatterns(EnumSet.of(DispatcherType.REQUEST), true, /*); // Or in Spring Boot: Bean public FilterRegistration paymentFilter(ServletContext servletContext) { FilterRegistration.Dynamic registration servletContext.addFilter( paymentFilter, new PaymentFilter(payToAddress, priceTable, new HttpFacilitatorClient(facilitatorUrl)) ); registration.addMappingForUrlPatterns(EnumSet.of(DispatcherType.REQUEST), true, /*); return registration; }PaymentFilter 的路径匹配与价格单位语义阅读 PaymentFilter 源码 的构造器 Javadoc可以提炼出几个容易踩坑的关键语义路径匹配规则对HttpServletRequest#getRequestURI()做精确、大小写敏感的比较查询字符串包含在匹配范围内HTTP 方法被忽略GET/POST 同价不在 priceTable 中的路径完全免费放行。价格单位金额默认按6 位小数的代币如 USDC解释即10000 0.01 USDC、1000000 1.00 USDC若使用 18 位小数代币如 ETH/WETH需要乘以 10¹²换算。官方推荐的价格表示例如下MapString, BigInteger priceTable Map.of( /api/premium, BigInteger.valueOf( 10000), // 0.01 USDC /api/report, BigInteger.valueOf(1000000) // 1.00 USDC );PaymentFilter 的内部处理流程从doFilter的实现PaymentFilter.java可以看到完整决策链请求非 HTTP无HttpServletRequest/HttpServletResponse时直接放行路径不在价格表中 → 直接chain.doFilter不产生任何拦截开销路径需要付费但缺少X-PAYMENT请求头 → 返回 402解析X-PAYMENT头Base64 解码 JSON 反序列化为PaymentPayload并校验payload.resource必须与当前 URI 路径一致不一致视为 402resource mismatch调用facilitator.verify(header, buildRequirements(path))做链下验证验证通过 →chain.doFilter放行到业务代码仅当响应状态码 400时调用facilitator.settle(...)完成结算并回写X-PAYMENT-RESPONSE响应头Base64 编码的 JSON含success、txHash、networkId、payer同时设置Access-Control-Expose-Headers: X-PAYMENT-RESPONSE以便浏览器端 JS 读取该头。其中buildRequirementsPaymentFilter.java为每个受保护路径构造默认的支付要求对象schemeexact、networkbase-sepolia、assetUSDC、mimeTypeapplication/json、maxTimeoutSeconds30payTo即构造时传入的收款地址。这意味着当前 Java 实现的默认定位是 Base Sepolia 测试网上的 ERC-3009 exact 方案实际部署时需按你的代币与网络调整这些字段。客户端接入用 X402HttpClient 发起带支付证明的请求客户端侧需要两个要素一个实现CryptoSigner接口的签名器负责用私钥签名以及一个X402HttpClient实例import org.x402.client.X402HttpClient; import org.x402.crypto.CryptoSigner; import java.math.BigInteger; import java.net.URI; import java.net.http.HttpResponse; import java.util.Map; // 1. Implement the CryptoSigner interface with your crypto library // This example uses a stub - youd integrate with web3j, Solana-J, etc. CryptoSigner signer new CryptoSigner() { Override public String sign(MapString, Object payload) { // Sign the payload with your private key return 0xYourSignatureHere; } }; // 2. Create the client X402HttpClient client new X402HttpClient(signer); // 3. Make a GET request with payment BigInteger amount BigInteger.valueOf(1000); String asset 0xTokenContractAddress; // Or USDC, etc. String payTo 0xReceiverAddress; URI uri URI.create(https://api.example.com/premium); HttpResponseString response client.get(uri, amount, asset, payTo); System.out.println(Response: response.body());CryptoSigner 签名接口的协议约定CryptoSigner.java 定义了统一的签名契约实现方需要按 scheme 返回协议的规范编码exact-evm对应 ERC-3009 的transferWithAuthorizationpayload 键为from, to, value, validAfter, validBefore, nonce返回0x 前缀的 65 字节十六进制串r∥s∥vv 27 或 28exact-solana对规范 JSON payload 做 Ed25519 签名返回Base58 编码的 64 字节签名。payload 字段缺失或类型错误应抛IllegalArgumentException底层密码学失败应抛CryptoSignException。实际项目中可以用 web3j、Solana-J 等库实现该接口。X402HttpClient 如何构造 X-PAYMENT 头从 X402HttpClient.java 的实现可以看到get(...)方法会构造一个 scheme 相关的 payload map包含amount原子单位字符串、asset代币合约地址或符号、payTo收款地址、resourceuri.getPath()必须与服务端价格表中的路径一致、nonceUUID.randomUUID()防重放以及signer.sign(...)产出的signature。随后它把整个对象封装为PaymentPayload { x402Version1, schemeexact, networkbase-sepolia, payload }通过 PaymentPayload.toHeader()先序列化为 JSON、再 Base64 编码后写入X-PAYMENT请求头。服务端收到后通过PaymentPayload.fromHeader(header)逆向解码。也就是说整个支付证明在网络上表现为一个 Base64 编码的 JSON 字符串结构清晰、可审计。完整示例Spring Boot 付费笑话 APIREADME 提供了一个可直接运行的 Spring Boot 完整示例涵盖过滤器注册 受保护 Controller的完整体验/api/joke需付费 1000 wei 才能访问import org.x402.server.PaymentFilter; import org.x402.client.HttpFacilitatorClient; import javax.servlet.DispatcherType; import javax.servlet.FilterRegistration; import javax.servlet.ServletContext; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.web.servlet.ServletContextInitializer; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; import java.math.BigInteger; import java.util.EnumSet; import java.util.Map; SpringBootApplication public class PaidJokeApplication implements ServletContextInitializer { public static void main(String[] args) { SpringApplication.run(PaidJokeApplication.class, args); } Override public void onStartup(ServletContext servletContext) { // Set up the payment filter String facilitatorUrl https://x402.org/facilitator; HttpFacilitatorClient facilitator new HttpFacilitatorClient(facilitatorUrl); // Define which URLs require payment and their prices MapString, BigInteger priceTable Map.of( /api/joke, BigInteger.valueOf(1000) // 1000 wei for a premium joke ); // Create and register the filter String payToAddress 0xYourReceiverAddress; PaymentFilter paymentFilter new PaymentFilter(payToAddress, priceTable, facilitator); FilterRegistration.Dynamic registration servletContext.addFilter(paymentFilter, paymentFilter); registration.addMappingForUrlPatterns( EnumSet.of(DispatcherType.REQUEST), true, /*); } RestController static class JokeController { GetMapping(/api/joke) public MapString, String getPremiumJoke() { // If this code runs, payment was already verified by the filter return Map.of(joke, Why do programmers prefer dark mode? Because light attracts bugs!); } } }这个示例有一个优雅的设计业务代码JokeController对支付逻辑零感知只要getPremiumJoke()被执行就说明支付已经由PaymentFilter验证通过——付费墙被完整地封装在过滤器层面。工作原理与支付流程README 给出了六个步骤的完整流程说明服务端定义需要付费的端点及其价格请求到达时PaymentFilter检查该路径是否需要付费若需要付费则查找X-PAYMENT请求头Facilitator 验证支付决定批准或拒绝请求批准则继续执行业务逻辑拒绝则返回402 Payment Required响应完成服务后过滤器调用 Facilitator 结算这笔支付。对应的时序图如下这套先 402 协商、再携带证明重试、最后验证放行 异步结算的模式与 Go 版go/server.go和 TypeScript 版typescript/packages/http实现保持了一致的协议语义。错误处理与响应格式PaymentFilter针对不同类型的错误返回对应的 HTTP 状态码与 JSON 结构响应体由PaymentRequiredResponse与PaymentRequirements模型序列化生成见 java/src/main/java/org/x402/model。Payment Required402缺少或无效的支付证明{ x402Version: 1, accepts: [ { scheme: exact, network: base-sepolia, maxAmountRequired: 1000, asset: USDC, resource: /api/premium, mimeType: application/json, payTo: 0xReceiverAddress, maxTimeoutSeconds: 30 } ], error: missing payment header }accepts数组中的每个元素即一个 PaymentRequirements 对象它完整声明了这份资源接受怎样的支付支付方案scheme、网络network、最大所需金额maxAmountRequireduint256/原子单位、代币asset、资源路径resource、期望的响应 MIMEmimeType、收款地址payTo、超时时间maxTimeoutSeconds。客户端拿到这个 402 响应后即可据此构造匹配的X-PAYMENT头。从源码可以确认触发 402 的场景还包括X-PAYMENT头缺失或为空、resource与请求路径不匹配resource mismatch、头部 Base64/JSON 解析失败IllegalArgumentException返回malformed X-PAYMENT header、Facilitator 验证返回isValidfalse错误原因透传自invalidReason。Server Errors500Facilitator 不可用当验证阶段与 Facilitator 通信失败如连接超时时返回 500{ error: Payment verification failed: Connection timeout }其他意外内部错误统一返回{ error: Internal server error during payment verification }Settlement Errors结算失败值得特别强调的是即使支付验证成功、业务内容已经生成如果结算阶段失败过滤器仍会返回 402 状态防止用户在没有完成支付结算的情况下拿到内容。这与 Go 和 TypeScript 实现的行为保持一致{ x402Version: 1, accepts: [...], error: settlement failed: insufficient balance }源码中的对应逻辑是chain.doFilter之后、且响应状态 400 时执行facilitator.settle(...)若settle返回successfalse或抛异常则在响应尚未committed的前提下改写为 402settlement failed: ...或settlement error: ...。此外结算成功后构造X-PAYMENT-RESPONSE响应头失败时也会返回 500Failed to create settlement response header。深入源码FacilitatorClient 接口与 HTTP 实现PaymentFilter并不直接依赖具体的 Facilitator 实现而是面向 FacilitatorClient 接口 编程这为接入自建 Facilitator 或测试替身提供了便利。接口包含三个方法verify(paymentHeader, requirements)验证支付、settle(paymentHeader, requirements)结算支付、supported()查询支持的方案类型。默认实现 HttpFacilitatorClient.java 使用 Java 17 内置的java.net.http.HttpClientconnectTimeout5 秒将 POST/verify、POST/settle与 GET/supported三个 REST 端点封装为同步调用/verify请求体为{ x402Version: 1, paymentHeader, paymentRequirements }响应反序列化为VerificationResponse { isValid, invalidReason }/settle同样的请求体结构响应反序列化为SettlementResponse { success, error, txHash, networkId }/supported响应为{ kinds: [...] }映射为SetKind。测试如何印证上述行为仓库测试提供了两层验证PaymentFilterTest.java基于 Mockito 的单元测试覆盖freeEndpoint免费路径直接放行、不设置任何状态码、missingHeader无X-PAYMENT头 → 402 且不进入业务链、validHeader构造 resource 匹配的合法头部 → 验证通过继续执行等关键分支FilterIntegrationTest.java基于嵌入式 Jetty 12 的集成测试真实启动 HTTP 服务将PaymentFilter注册在/*上配合一个始终放行的桩FacilitatorClient与一个返回 JSON 的业务 Servlet用真实HttpClient走完整 HTTP 链路——这直接证明了该库与任何 Servlet 容器Tomcat、Jetty 等兼容的声明。小结x402 的 Java 实现以最小的概念集一个过滤器、一个客户端接口、一个便捷 HTTP 客户端完成了HTTP 资源付费墙的完整闭环服务端通过PaymentFilter声明价格、校验X-PAYMENT头并与 Facilitator 协作完成验证与结算客户端通过X402HttpClientCryptoSigner一键构造带支付证明的请求。它的路径匹配、价格单位6 位小数代币基准、默认网络Base Sepolia / exact 方案以及结算失败即 402的语义都是实际接入时需要重点理解的契约细节。结合 PaymentFilter 源码、FacilitatorClient 接口 与两套测试用例开发者可以快速将其接入 Tomcat/Jetty 或 Spring Boot/Quarkus 项目也可以仿照HttpFacilitatorClient自行实现FacilitatorClient对接私有 Facilitator 服务。【免费下载链接】x402A payments protocol for the internet. Built on HTTP.项目地址: https://gitcode.com/GitHub_Trending/x4/x402创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表