java-xmlrpc-guideline
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseJava XML-RPC API Design Guideline
Java XML-RPC API设计指南
Overview
概述
Design XML-RPC APIs with clear exception handling, proper return types, and interoperable serialization.
Core principle: Exceptions signal failure, return values signal success. Use JAXB for cross-language compatibility.
设计具备清晰异常处理、合适返回类型和可互操作序列化机制的XML-RPC API。
核心原则: 异常表示失败,返回值表示成功。使用JAXB实现跨语言兼容性。
Quick Reference
快速参考
| Scenario | Pattern |
|---|---|
| API interface method | |
| Void-like operation | Return |
| Success result | Return value (DTO, primitive, etc.) |
| Failure result | Throw |
| DTO serialization | Use JAXB annotations ( |
| 场景 | 模式 |
|---|---|
| API接口方法 | |
| 类void操作 | 返回 |
| 成功结果 | 返回值(DTO、基本类型等) |
| 失败结果 | 抛出 |
| DTO序列化 | 使用JAXB注解( |
Exception Handling
异常处理
All API Methods Must Declare XmlRpcException
所有API方法必须声明XmlRpcException
Every interface method must include :
throws XmlRpcExceptionjava
public interface SomeApi {
SomeDto someAction(SomeParameterDto request) throws XmlRpcException;
}Why: XML-RPC library can transmit one exception type to client. Most projects use extension features enabling this. The exception serializes as:
xml
<?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>Avoid: feature. It serializes Java exceptions including chained exceptions, but only works with Java clients.
enabledForException每个接口方法都必须包含:
throws XmlRpcExceptionjava
public interface SomeApi {
SomeDto someAction(SomeParameterDto request) throws XmlRpcException;
}原因: XML-RPC库只能向客户端传输一种异常类型。大多数项目会使用支持此功能的扩展特性。异常的序列化格式如下:
xml
<?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>避免: 使用特性。它会序列化包含链式异常的Java异常,但仅对Java客户端有效。
enabledForExceptionReturn Type Guidelines
返回类型指南
Void Methods Must Return int
Void方法必须返回int
XML-RPC library doesn't support return type. Use instead:
voidintjava
public interface ServiceControlApi {
int start(String name) throws XmlRpcException;
}Rules:
- Always return (regardless of success or failure)
0 - Signal failure by throwing
XmlRpcException - The return value has no meaning - it exists only because XML-RPC spec doesn't support
void
Why: This is purely a workaround for XML-RPC library limitation. If the spec supported , we would use . The return is meaningless; failure is communicated exclusively through exceptions.
voidvoidintXML-RPC库不支持返回类型,应使用替代:
voidintjava
public interface ServiceControlApi {
int start(String name) throws XmlRpcException;
}规则:
- 始终返回(无论成功或失败)
0 - 通过抛出表示失败
XmlRpcException - 返回值无实际意义——仅因XML-RPC规范不支持而存在
void
原因: 这纯粹是针对XML-RPC库限制的变通方案。如果规范支持,我们会直接使用。返回值无实际意义,失败仅通过异常传递。
voidvoidintSuccess vs Failure: Clear Separation
成功与失败:明确区分
| Outcome | How to Signal |
|---|---|
| Operation succeeded | Return value |
| Query found nothing | Return empty/false (this is success) |
| Operation failed | Throw |
Example - Query API:
java
public interface PublicIpApi {
boolean isExists(InetAddress address) throws XmlRpcException;
}- IP exists → return
true - IP doesn't exist → return (success case - query worked)
false - System error during query → throw
XmlRpcException
Example - Action API:
java
public interface ServiceControlApi {
int start(String name) throws XmlRpcException;
}- Service started → return
0 - Service already running → return (value is meaningless)
0 - Service failed to start → throw (this is how failure is signaled)
XmlRpcException
Why this matters:
- Returning error codes in response (like or error field in DTO) makes XML-RPC request appear successful
-1 - Server logs show success, no stack trace
- Client must inspect response to detect failure
- Debugging becomes difficult
| 结果 | 传递方式 |
|---|---|
| 操作成功 | 返回值 |
| 查询无结果 | 返回空值/false(属于成功情况) |
| 操作失败 | 抛出 |
示例 - 查询API:
java
public interface PublicIpApi {
boolean isExists(InetAddress address) throws XmlRpcException;
}- IP存在 → 返回
true - IP不存在 → 返回(成功情况——查询正常执行)
false - 查询过程中出现系统错误 → 抛出
XmlRpcException
示例 - 操作API:
java
public interface ServiceControlApi {
int start(String name) throws XmlRpcException;
}- 服务启动成功 → 返回
0 - 服务已在运行 → 返回(值无实际意义)
0 - 服务启动失败 → 抛出(以此表示失败)
XmlRpcException
重要性:
- 在响应中返回错误码(如或DTO中的错误字段)会让XML-RPC请求看起来执行成功
-1 - 服务器日志会显示成功,无堆栈跟踪
- 客户端必须检查响应才能发现失败
- 调试难度加大
DTO Serialization
DTO序列化
Use JAXB, Not Serializable
使用JAXB,而非Serializable
DTOs must use XML structures via JAXB for cross-language compatibility:
java
// 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() { }
}
}java
// BAD: Serializable DTO (Java-only)
public class SerializableDto implements Serializable {
private String value;
public SerializableDto(String value) {
this.value = value;
}
}DTO必须通过JAXB使用XML结构,以实现跨语言兼容性:
java
// 推荐: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() { }
}
}java
// 不推荐:Serializable DTO(仅支持Java)
public class SerializableDto implements Serializable {
private String value;
public SerializableDto(String value) {
this.value = value;
}
}Serialization Comparison
序列化对比
Serializable output (unreadable, Java-only):
xml
<ex:serializable>rO0ABXNyACx0aWwueG1scnBj...</ex:serializable>JAXB output (readable, cross-language):
xml
<ex:jaxb>
<complexJaxbDto number="number" type="type">
<nestedDtos>
<value>test</value>
</nestedDtos>
<nestedDtos>
<value>test2</value>
</nestedDtos>
</complexJaxbDto>
</ex:jaxb>Why JAXB:
- XML-RPC is designed for interoperability
- Serializable limits clients to Java
- JAXB produces human-readable XML
- Long-term maintainability
Serializable输出(不可读,仅支持Java):
xml
<ex:serializable>rO0ABXNyACx0aWwueG1scnBj...</ex:serializable>JAXB输出(可读,跨语言):
xml
<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
- 长期可维护性更强
Common Mistakes
常见错误
| Mistake | Problem | Fix |
|---|---|---|
Missing | Client can't receive errors | Add to all API methods |
Using | XML-RPC library doesn't support it | Use |
Returning | Meaningless, creates confusion | Always return |
| Error codes in DTO fields | Request appears successful | Throw |
Using | Java-only, unreadable | Use JAXB annotations |
Using | Java-only | Avoid, use standard faults |
| 错误 | 问题 | 修复方案 |
|---|---|---|
未声明 | 客户端无法接收错误信息 | 为所有API方法添加该声明 |
使用 | XML-RPC库不支持 | 使用 |
返回 | 无实际意义,造成混淆 | 始终返回 |
| DTO字段中包含错误码 | 请求看起来执行成功 | 抛出 |
使用 | 仅支持Java,输出不可读 | 使用JAXB注解 |
使用 | 仅支持Java | 避免使用,使用标准错误机制 |
Idempotency Decisions
幂等性决策
For action APIs, decide if operation should be idempotent:
Idempotent approach:
- on running service → return
start()0 - Easier for clients, more forgiving
Strict approach:
- on running service → throw
start()XmlRpcException - Explicit about state transitions
Document your choice in the API contract. Either is valid - consistency matters.
对于操作类API,需决定操作是否应具备幂等性:
幂等性方案:
- 对已运行的服务调用→ 返回
start()0 - 对客户端更友好,容错性更强
严格方案:
- 对已运行的服务调用→ 抛出
start()XmlRpcException - 明确状态转换
请在API契约中记录你的选择。两种方案均有效——保持一致性至关重要。
Checklist
检查清单
Before completing XML-RPC API design:
- All interface methods declare
throws XmlRpcException - No return types (use
void, always returnint)0 - Success cases return values (for non-void methods)
- Failure cases throw exceptions (never use return codes)
- For void-like methods: return value is always , failure via exception only
0 - Idempotency behavior documented
完成XML-RPC API设计前,请检查:
- 所有接口方法均声明
throws XmlRpcException - 无返回类型(使用
void,始终返回int)0 - 成功情况返回值(非void方法)
- 失败情况抛出异常(绝不使用返回码)
- 类void方法:返回值始终为,仅通过异常表示失败
0 - 幂等性行为已记录