You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用JAX-RS对接Odoo REST服务?技术实现咨询

对接Odoo API的JAX-RS实现问题

背景

我正在开发运行于TomEE的Java Web应用,使用JAX-RS、Jakarta Faces、CDI等Jakarta EE技术,基础功能正常。现在需要对接Odoo服务器执行更新操作,Odoo官方文档里的Java示例依赖Apache XML-RPC包,但该包已14年未更新,存在安全漏洞,所以想改用JAX-RS客户端替代。

Odoo官方XML-RPC示例(获取服务器版本)

官方示例代码:

final String url = "myServer";
final XmlRpcClientConfigImpl common_config = new XmlRpcClientConfigImpl();
common_config.setServerURL(new URL(String.format("%s/xmlrpc/2/common", url)));
client.execute(common_config, "version", emptyList());

预期返回:

{
    "server_version": "13.0",
    "server_version_info": [13, 0, 0, "final", 0],
    "server_serie": "13.0",
    "protocol_version": 1,
}

我的JAX-RS尝试及错误

我未安装Apache XML-RPC,尝试用JAX-RS实现相同功能,代码如下:

private final static String pathCommon = "/xmlrpc/2/common";
private final static String odooServer = "http://my.server";
Client client = ClientBuilder.newClient();
WebTarget server = client.target(odooServer);
WebTarget common = server.path(pathCommon);
Invocation.Builder invoker = common.request(MediaType.TEXT_PLAIN);
Entity<String> e = Entity.text("version");
Response resp = invoker.post(e);

请求返回格式错误,响应内容:

Response status: 200, Status type:OK, Status family:SUCCESSFUL, Status phrase:OK
 Length: 783, has entity: true
Data :
entity as string: 
<?xml version='1.0'?>
<methodResponse>
<fault>
<value><struct>
<member>
<name>faultCode</name>
<value><int>1</int></value>
</member>
<member>
<name>faultString</name>
<value><string>Traceback (most recent call last):
  File "/opt/odoo/odoo/odoo/addons/base/controllers/rpc.py", line 69, in xmlrpc_2
    response = self._xmlrpc(service)
  File "/opt/odoo/odoo/odoo/addons/base/controllers/rpc.py", line 48, in _xmlrpc
    params, method = loads(data)
  File "/usr/local/lib/python3.8/xmlrpc/client.py", line 1017, in loads
    p.close()
  File "/usr/local/lib/python3.8/xmlrpc/client.py", line 447, in close
    parser.Parse(b"", True) # end of data
xml.parsers.expat.ExpatError: syntax error: line 1, column 0
</string></value>
</member>
</struct></value>
</fault>
</methodResponse>

需求

  • Odoo XML-RPC请求格式的文档指引
  • JAX-RS是否适合对接Odoo的这类接口
  • JAX-RS调用Odoo接口的示例代码
  • Odoo是否提供基于JSON的REST接口

解答

1. Odoo XML-RPC请求格式说明

Odoo的/xmlrpc/2/common接口遵循XML-RPC 2.0规范,要求POST请求的主体是符合XML-RPC格式的XML文档,而非纯文本。XML-RPC的请求结构必须包含<methodCall>节点,明确指定方法名和参数数组。

2. JAX-RS是否适合对接

完全适合。JAX-RS客户端可以构造符合要求的XML请求体,处理XML响应,无需依赖老旧的Apache XML-RPC包,能直接利用现有Jakarta EE技术栈完成对接。

3. JAX-RS调用Odoo版本接口的示例

以下是构造正确XML-RPC请求的JAX-RS代码:

private final static String pathCommon = "/xmlrpc/2/common";
private final static String odooServer = "http://my.server";

// 构造符合XML-RPC规范的请求体
String xmlRequest = """
<?xml version="1.0"?>
<methodCall>
  <methodName>version</methodName>
  <params>
  </params>
</methodCall>
""";

Client client = ClientBuilder.newClient();
try {
    WebTarget target = client.target(odooServer).path(pathCommon);
    Response response = target.request(MediaType.APPLICATION_XML)
                              .post(Entity.xml(xmlRequest));

    if (response.getStatus() == Response.Status.OK.getStatusCode()) {
        String xmlResponse = response.readEntity(String.class);
        System.out.println(xmlResponse);
        // 可使用JAXB或手动解析XML转为Java对象
    } else {
        System.err.println("请求失败,状态码:" + response.getStatus());
    }
} finally {
    client.close();
}

如果需要调用带参数的方法(比如认证),只需在<params>节点下添加<param>子节点,示例:

<params>
  <param><value><string>数据库名</string></value></param>
  <param><value><string>用户名</string></value></param>
  <param><value><string>密码</string></value></param>
</params>

4. Odoo的JSON REST接口

Odoo提供JSON-RPC接口,路径为/jsonrpc,相比XML-RPC更适合Java应用处理。请求需发送JSON格式的POST数据,示例请求体:

{
  "jsonrpc": "2.0",
  "method": "call",
  "params": {
    "service": "common",
    "method": "version",
    "args": []
  },
  "id": 1
}

对应的JAX-RS调用示例:

private final static String pathJsonRpc = "/jsonrpc";
private final static String odooServer = "http://my.server";

// 构造JSON-RPC请求体
String jsonRequest = """
{
  "jsonrpc": "2.0",
  "method": "call",
  "params": {
    "service": "common",
    "method": "version",
    "args": []
  },
  "id": 1
}
""";

Client client = ClientBuilder.newClient();
try {
    WebTarget target = client.target(odooServer).path(pathJsonRpc);
    Response response = target.request(MediaType.APPLICATION_JSON)
                              .post(Entity.json(jsonRequest));

    if (response.getStatus() == Response.Status.OK.getStatusCode()) {
        String jsonResponse = response.readEntity(String.class);
        System.out.println(jsonResponse);
        // 可使用Jackson等JSON库直接转为Java对象
    } else {
        System.err.println("请求失败,状态码:" + response.getStatus());
    }
} finally {
    client.close();
}

JSON-RPC接口返回格式为JSON,处理成本更低,推荐优先使用。


内容的提问来源于stack exchange,提问作者Scott Nicklous

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.20 11:33:15