我有一个REST Web服务,它反过来调用Soap请求。我想将 soap 响应转换为 json,以便它可以作为输出返回到 REST 服务。实现这一目标的最有效方法是什么?
为了详细说明这个问题,假设我得到一个如下所示的 Soap xml 响应。
<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope/" soap:encodingStyle="http://www.w3.org/2003/05/soap-encoding">
<soap:Body xmlns:m="http://www.example.org/stock">
<m:GetStockPriceResponse>
<m:Price>344.5</m:Price>
</m:GetStockPriceResponse>
</soap:Body>
</soap:Envelope>
我希望 json 是这样的
{"价格" : "344.5"}
我已经尝试了org.json.XML.toJSONObject((方法。但它没有给出我期望的输出。
你试过吗:
public String XMLtoJSON(String xml) {
JSONObject jsonObj = XML.toJSONObject(xml);
String json = jsonObj.toString();
return json;
}
如果你使用的是Java 8或更高版本,你应该看看我的开源库:unXml。 unXml 基本上是从 Xpath 映射到 Json 属性。
它在Maven Central上可用。
例
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.nerdforge.unxml.factory.ParsingFactory;
import com.nerdforge.unxml.parsers.Parser;
import org.w3c.dom.Document;
public class Parser {
public ObjectNode parseXml(String xml){
Parsing parsing = ParsingFactory.getInstance(namespaces()).create();
Document document = parsing.xml().document(xml);
Parser<ObjectNode> parser = parsing.obj("//m:GetStockPriceResponse")
.attribute("price", "m:Price", parsing.number())
.build();
ObjectNode result = parser.apply(document);
return result;
}
private Map<String, String> namespaces(){
return new HashMap<String, String>(){{
put("m", "http://www.example.org/stock");
}};
}
}
它将返回一个杰克逊ObjectNode
,并带有以下 json:
{"price":344.5}
我假设您已经在使用 Jakarta XML Web Services 和 Jakarta XML Binding。带注释的类jakarta.ws.WebService
将 Java 对象隐式转换为 XML,并隐式地转换为jakarta.ws.WebMethod
和返回 Java Bean 实例的方法。您只需将这些实例传递给 Jakarta JSON 绑定即可:
import jakarta.ejb.Stateless;
import jakarta.jws.WebMethod;
import jakarta.jws.WebParam;
import jakarta.jws.WebService;
import jakarta.json.bind.Jsonb;
import jakarta.json.bind.JsonbBuilder;
@Stateless
@WebService
public class Manager {
@WebMethod(operationName = "getMyJavaBeanAsJson")
public String getMyJavaBeanAsJson(@WebParam(name = "id") final BigDecimal id) {
final MyJavaBean myJavaBeanInstance = MyJavaBeanService.getInstance().find(id);
try (final Jsonb jsonb = JsonbBuilder.create()) {
return jsonb.toJson(myJavaBeanInstance);
}
}
}
请注意,我的回答仅使用标准的Jakarta EE(>= 9(API,没有第三方依赖项。
另一种解决方案是使用Java Stax(Java API for XML Processing(读取SOAP信封,SOAP主体,SOAP响应,SOAP返回,然后仅将接收到的XML的这一部分转换为JSON。要么将 XML 转换为 Java Bean 并使用上面的解决方案转换为 JSON,要么在不使用 Java Bean 的情况下将 XML 转换为 JSON。以我的拙见,如果您不想在 JSON 中返回 SOAP 内容,请使用 Stax 仅获取 SOAP 返回并将其传递给org.json.XML.toJSONObject(final String xml)
或任何其他能够将 XML 转换为 JSON 的工具。