我正在尝试编写一个在 Tomee 应用程序服务器上运行的 Java Web 应用程序。该应用程序使用多种 Jakarta EE 技术,例如 JAX-RS、Jakarta Faces 和 CDI。基本应用运行良好;我对此没有任何问题。
但是,在某一时刻,我需要更新我们的 Odoo 服务器。 Odoo 提供了一个 REST API,如下所述:Odoo 外部 API
该页面提供了多种编程语言的示例,包括 Java。不幸的是,Java 示例使用了 Apache XML-RPC 包,据我从 Maven Central 了解到,该包已有大约 14 年没有更新,并且可能存在安全漏洞。
所以我不想使用它,并且正在寻找某种利用现有技术与 Odoo 进行通信的方法,例如使用 JAX-RS 客户端。
Odoo 文档提供了一个用于获取服务器版本的 Apache 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,
}
请注意,我没有安装 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);
这真的根本不起作用。该请求似乎确实到达了 Odoo 服务器,并且 Odoo 服务器感觉到它正在与之交谈,但我发送的请求格式显然是错误的。服务器响应如下,这不是预期的结果。
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 消息作为输入而不是文本。但我根本找不到任何有关预期消息格式的文档。任何人都可以提供指向 Odoo 文档的指针以获取预期的实际消息吗?我的 JAX-RS 客户端是要使用的正确工具,或者是否有更好的替代方案?谁能提供一个使用 Odoo REST API 和 Jax-RS 的示例吗? Odoo 可能有基于 Json 的 REST 接口吗?
感谢您的帮助!
我已经很好地解决了这个问题,足以满足我的目的。您可以使用根据此处描述形成的 XML 消息与 Odoo 进行通信:XML RPC 规范 .
为了使上面的代码示例正常工作,我必须像这样更改代码:
StringBuilder txt = new StringBuilder(128);
txt.append("<?xml version=\"1.0\"?>\n");
txt.append("<methodCall>\n");
txt.append(" <methodName>version</methodName>\n");
txt.append(" <params>\n");
txt.append(" </params>\n");
txt.append("</methodCall>\n");
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(txt.toString());
Response resp = invoker.post(e);
这给了我预期的回应,即:
<?xml version='1.0'?>
<methodResponse>
<params>
<param>
<value><struct>
<member>
<name>server_version</name>
<value><string>13.0</string></value>
</member>
<member>
<name>server_version_info</name>
<value><array><data>
<value><int>13</int></value>
<value><int>0</int></value>
<value><int>0</int></value>
<value><string>final</string></value>
<value><int>0</int></value>
<value><string></string></value>
</data></array></value>
</member>
<member>
<name>server_serie</name>
<value><string>13.0</string></value>
</member>
<member>
<name>protocol_version</name>
<value><int>1</int></value>
</member>
</struct></value>
</param>
</params>
</methodResponse>
这样,我就能找出我需要的其他消息。 :-)