关于 java-xmlrpc-guideline
面向 Java 开发者的 XML-RPC API 设计指南,适用于构建可互操作的接口。它将成功返回值与通过 XmlRpcException 表示的失败区分开,并建议用 JAXB 序列化 DTO。
主要功能
- 01API 方法声明 XmlRpcException
- 02用 int 表示类 void 操作
- 03区分成功返回值与失败
- 04使用 JAXB 序列化 DTO
- 05记录操作的幂等性
适用场景
- 01设计 Java XML-RPC 接口
- 02定义查询和操作的结果
- 03创建跨语言 DTO 格式
- 04检查 API 错误处理
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ gabia/ agent-skills --skill java-xmlrpc-guideline安装后在 Claude Code 中输入/java-xmlrpc-guideline确认已加载。
详细介绍
Java XML-RPC API 设计指南
概述
设计 XML-RPC API 时,应明确处理异常、正确设置返回类型,并使用可互操作的序列化方式。
**核心原则:**异常表示失败,返回值表示成功。使用 JAXB 实现跨语言兼容。
快速参考
| 场景 | 模式 |
|---|---|
| API 接口方法 | ReturnType method(Param p) throws XmlRpcException |
| 类似 void 的操作 | 返回 int,始终为 0(该值没有意义,是对规范限制的变通处理) |
| 成功结果 | 返回值(DTO、基本类型等) |
| 失败结果 | 抛出 XmlRpcException |
| DTO 序列化 | 使用 JAXB 注解(@XmlRootElement、@XmlAttribute) |
异常处理
所有 API 方法都必须声明 XmlRpcException
每个接口方法都必须包含 throws XmlRpcException:
public interface SomeApi {
SomeDto someAction(SomeParameterDto request) throws XmlRpcException;
}
**原因:**XML-RPC 库可以向客户端传递一种异常类型。大多数项目会使用启用此功能的扩展。异常序列化后的形式如下:
<?xml version="1.0" encoding="UTF-8"?>
<methodResponse xmlns:ex="http://ws.apache.org/xmlrpc/namespaces/extensions">
<fault>
<value>
<struct>
<member>
<name>faultCode</name>
<value><i4>1</i4></value>
</member>
<member>
<name>faultString</name>
<value>failed to execute api</value>
</member>
</struct>
</value>
</fault>
</methodResponse>
避免使用:enabledForException 功能。它会序列化 Java 异常(包括链式异常),但仅适用于 Java 客户端。
返回类型指南
Void 方法必须返回 int
XML-RPC 库不支持 void 返回类型,因此应使用 int:
public interface ServiceControlApi {
int start(String name) throws XmlRpcException;
}
规则:
- 始终返回
0(无论成功还是失败) - 通过抛出
XmlRpcException表示失败 - 返回值没有意义——它的存在仅仅是因为 XML-RPC 规范不支持
void
**原因:**这纯粹是对 XML-RPC 库限制的变通处理。如果规范支持 void,我们就会使用 void。int 返回值没有意义;失败完全通过异常传达。
明确区分成功与失败
| 结果 | 信号方式 |
|---|---|
| 操作成功 | 返回值 |
| 查询无结果 | 返回空值/false(这属于成功) |
| 操作失败 | 抛出 XmlRpcException |
示例 - 查询 API:
public interface PublicIpApi {
boolean isExists(InetAddress address) throws XmlRpcException;
}
- IP 存在 → 返回
true - IP 不存在 → 返回
false(成功情况——查询正常完成) - 查询期间发生系统错误 → 抛出
XmlRpcException
示例 - 操作 API:
public interface ServiceControlApi {
int start(String name) throws XmlRpcException;
}
- 服务已启动 → 返回
0 - 服务已在运行 → 返回
0(该值没有意义) - 服务启动失败 → 抛出
XmlRpcException(通过这种方式表示失败)
这很重要,原因如下:
- 在响应中返回错误码(例如
-1或 DTO 中的错误字段)会让 XML-RPC 请求看起来像是成功的 - 服务端日志会显示成功,且没有堆栈跟踪
- 客户端必须检查响应才能发现失败
- 调试会变得困难
DTO 序列化
使用 JAXB,而非 Serializable
DTO 必须使用 JAXB 将数据序列化为 XML 结构,以实现跨语言兼容:
// GOOD: JAXB DTO
@XmlRootElement
public class ComplexJaxbDto implements Element {
@XmlAttribute
private String type;
@XmlAttribute
private String number;
private List<NestedDto> nestedDtos;
private ComplexJaxbDto() { }
public static final class NestedDto {
private String value;
private NestedDto() { }
}
}
// BAD: Serializable DTO (Java-only)
public class SerializableDto implements Serializable {
private String value;
public SerializableDto(String value) {
this.value = value;
}
}
序列化方式对比
Serializable 输出(难以阅读,仅适用于 Java):
<ex:serializable>rO0ABXNyACx0aWwueG1scnBj...</ex:serializable>
JAXB 输出(可读,支持跨语言):
<ex:jaxb>
<complexJaxbDto number="number" type="type">
<nestedDtos>
<value>test</value>
</nestedDtos>
<nestedDtos>
<value>test2</value>
</nestedDtos>
</complexJaxbDto>
</ex:jaxb>
使用 JAXB 的原因:
- XML-RPC 的设计目标是实现互操作性
- Serializable 会将客户端限制为 Java
- JAXB 可生成易读的 XML
- 有利于长期维护
常见错误
| 错误 | 问题 | 修正方法 |
|---|---|---|
缺少 throws XmlRpcException | 客户端无法接收错误 | 为所有 API 方法添加声明 |
使用 void 返回类型 | XML-RPC 库不支持 | 使用 int,并始终返回 0 |
返回 -1 或其他错误码 | 没有意义,容易造成混淆 | 始终返回 0,通过异常表示失败 |
| 在 DTO 字段中使用错误码 | 请求看起来像是成功的 | 抛出 XmlRpcException |
使用 Serializable | 仅适用于 Java,难以阅读 | 使用 JAXB 注解 |
使用 enabledForException | 仅适用于 Java | 避免使用,改用标准错误 |
幂等性决策
对于操作 API,请决定操作是否应具备幂等性:
幂等方式:
- 对正在运行的服务调用
start()→ 返回0 - 对客户端更简单,容错性更好
严格方式:
- 对正在运行的服务调用
start()→ 抛出XmlRpcException - 明确状态转换
请在 API 契约中记录你的选择。两种方式都有效,关键在于保持一致。
检查清单
完成 XML-RPC API 设计前:
- 所有接口方法都声明
throws XmlRpcException - 不使用
void返回类型(使用int,始终返回0) - 成功时返回值(对于非
void方法) - 失败时抛出异常(绝不使用返回码)
- 对于类似
void的方法:返回值始终为0,失败时仅通过异常表示 - 已记录幂等性行为
评论
支持 Markdown