我从服务器获得XML响应。但我需要以JSON格式显示它。
有没有办法在没有任何第三方API的情况下进行转换?我使用了杰克逊,但为此我需要创建POJO。
来自服务器的响应是这样的:
<?xml version='1.0'?>
<errors><error><status>400</status><message>The field 'quantity' is invalid.</message><details><invalid_reason>The quantity specified is greater than the quantity of the product that is available to ship.</invalid_reason><available_quantity>0</available_quantity><order_product_id>12525</order_product_id></details></error></errors>
答案 0 :(得分:20)
你可以用Jackson做到这一点,并且不需要POJO:
String xml = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
"<errors>\n" +
" <error>\n" +
" <status>400</status>\n" +
" <message>The field 'quantity' is invalid.</message>\n" +
" <details>\n" +
" <invalid_reason>The quantity specified is greater than the quantity of the product that is available to ship.</invalid_reason>\n" +
" <available_quantity>0</available_quantity>\n" +
" <order_product_id>12525</order_product_id>\n" +
" </details>\n" +
" </error>\n" +
"</errors>";
XmlMapper xmlMapper = new XmlMapper();
JsonNode node = xmlMapper.readTree(xml.getBytes());
ObjectMapper jsonMapper = new ObjectMapper();
String json = jsonMapper.writeValueAsString(node);
需要以下依赖项:
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.8.2</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.8.2</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>2.8.2</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.dataformat</groupId>
<artifactId>jackson-dataformat-xml</artifactId>
<version>2.8.2</version>
</dependency>
请注意documentation中所述的XmlMapper
限制:
仅以有限的方式支持树模型:具体而言,可以编写Java数组和
Collections
,但无法读取,因为无法区分数组和对象其他信息。
您也可以使用JSON.org:
String xml = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
"<errors>\n" +
" <error>\n" +
" <status>400</status>\n" +
" <message>The field 'quantity' is invalid.</message>\n" +
" <details>\n" +
" <invalid_reason>The quantity specified is greater than the quantity of the product that is available to ship.</invalid_reason>\n" +
" <available_quantity>0</available_quantity>\n" +
" <order_product_id>12525</order_product_id>\n" +
" </details>\n" +
" </error>\n" +
"</errors>";
String json = XML.toJSONObject(xml).toString();
需要以下依赖项:
<dependency>
<groupId>org.json</groupId>
<artifactId>json</artifactId>
<version>20160810</version>
</dependency>
答案 1 :(得分:3)
我知道我来不及回答了。但是我是为那些偶然发现这个问题并想使用@Cassio答案的新人写的。
使用XmlMpper
反序列化为JsonNode
的问题是,当在同一级别有多个具有相同名称的元素时,它将用新元素替换前一个元素一并最终导致数据丢失。通常,我们必须将此添加到数组中。为了解决这个问题,我们可以重写_handleDuplicateField()
类的JsonNodeDeserializer
方法。聊够了。让我们看一下代码
public class DuplicateToArrayJsonNodeDeserializer extends JsonNodeDeserializer {
@Override
protected void _handleDuplicateField(JsonParser p, DeserializationContext ctxt,
JsonNodeFactory nodeFactory,String fieldName, ObjectNode objectNode,
JsonNode oldValue, JsonNode newValue) throws JsonProcessingException {
ArrayNode node;
if(oldValue instanceof ArrayNode){
node = (ArrayNode) oldValue;
node.add(newValue);
} else {
node = nodeFactory.arrayNode();
node.add(oldValue);
node.add(newValue);
}
objectNode.set(fieldName, node);
}
}
由于我们已经覆盖了默认的反序列化器,因此我们还需要在XmlMapper
中进行注册才能使其正常工作。
XmlMapper xmlMapper = new XmlMapper();
xmlMapper.registerModule(new SimpleModule().addDeserializer(
JsonNode.class,
new DuplicateToArrayJsonNodeDeserializer()
));
JsonNode node = xmlMapper.readTree(payLoad);
答案 2 :(得分:2)
有没有办法在不使用任何第三方API的情况下将xml转换为json?
如果你是实际的,那就没有了。
解析XML的步骤可以使用属于Java SE的API来执行。但是,从解析的XML(例如DOM)到JSON需要JSON支持库,而Java SE不包含JSON。
(理论上你可以自己编写这样一个库,但这样做有什么意义呢?)
@Cassio指出杰克逊允许你在不编写POJO的情况下进行翻译。或者,查看Java的其他(第三方)JSON API;请参阅http://www.json.org以获取备选方案列表。一些较简单的不涉及定义POJO我使用了杰克逊,但为此我需要创建POJO。
答案 3 :(得分:0)
package com.src.test;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import org.apache.commons.io.IOUtils;
import net.sf.json.JSON;
import net.sf.json.xml.XMLSerializer;
public class JSONConverter {
private static URL url = null;
private static InputStream input = null;
public static void main(String args[]) throws IOException {
try {
url = JSONConverter.class.getClassLoader().getResource("sampleXmlFilePath.xml");
input = url.openStream();
String xmlData = IOUtils.toString(input);
XMLSerializer xmlSerializer = new XMLSerializer();
JSON json = xmlSerializer.read(xmlData);
System.out.println("JSON format : " + json);
} catch (Exception e) {
e.printStackTrace();
} finally {
input.close();
}
}
}
答案 4 :(得分:0)
使用杰克逊
import com.fasterxml.jackson.dataformat.xml.XmlMapper;
import java.io.IOException;
public class JsonUtil {
private static XmlMapper XML_MAPPER = new XmlMapper();
private static ObjectMapper JSON_MAPPER = new ObjectMapper();
public static ObjectMapper getJsonMapper(){
return JSON_MAPPER;
}
public static XmlMapper getXmlMapper(){
return XML_MAPPER;
}
public static String xmlToJson(String xml){
try {
return getJsonMapper().writeValueAsString(getXmlMapper().readTree(xml));
} catch (IOException e) {
e.printStackTrace();
return "";
}
}
}
答案 5 :(得分:0)
我刚刚遵循了卡西莫林步骤。使用jackson 2.x库时,我遇到了以下异常。
Cannot create XMLStreamReader or XMLEventReader from a org.codehaus.stax2.io.Stax2ByteArraySource
如果您也遇到上述异常。添加以下代码以解决该问题。然后,您可以看到没有命名空间的转换后的JSON。
JacksonXmlModule module = new JacksonXmlModule();
module.setDefaultUseWrapper(false);
XmlMapper xmlMapper = new XmlMapper(module);
提示: 如果要转换不带名称空间的XML,请使用jackson库。不要去org.json库。它不支持此用例。
答案 6 :(得分:0)
根据 Jackson 的作者,Jackson 2.12 is able to read XML with readTree even with duplicate elements:
<块引用>注意:Jackson 2.12 版允许使用 readTree() 读取重复元素。 (也适用于 java.lang.Object 的名义类型,即所谓的“无类型”绑定)。
所以你可以使用
z = -(a*x +b*y + d)/c