サーバーから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>
あなたはジャクソンでそれを行うことができ、そのために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>
ドキュメント に記載されている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>
ここで答えるには遅すぎることを知っています。しかし、私はこの質問に出くわし、@ Cassioの答えを使用することを考えた新しい人のためにこれを書いています。
XmlMpper
を使用してJsonNode
に逆シリアル化する問題は、同じレベルに同じ名前の要素が複数ある場合、前の要素を新しい要素に置き換えることです。そして、データが失われます。通常、これを配列に追加する必要があります。この問題に取り組むために、JsonNodeDeserializer
クラスの_handleDuplicateField()
メソッドをオーバーライドできます。十分な話。コードを見てみましょう
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);
サードパーティのAPIを使用せずにxmlをjsonに変換する方法はありますか?
あなたが実用的であるなら、ありません。
XMLを解析するステップは、Java SEの一部であるAPIを使用して実行できます。ただし、解析されたXML(DOMなど)からJSONに移行するにはJSONサポートライブラリが必要であり、Java SEには含まれていません。
(理論的には、あなたはcould自分でそのようなライブラリを書くことができますが、それを行う意味は何ですか?)
私はジャクソンを使用しましたが、このためにPOJOを作成する必要があります。
@Cassioは、Jacksonを使用すると、POJOを作成せずにこの変換を実行できることを指摘しています。または、Java用の他の(サードパーティ)JSON APIをご覧ください。代替のリストについては、 http://www.json.org を参照してください。単純なものの中には、POJOの定義を必要としないものもあります
ジャクソンを使用する
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 "";
}
}
}
cassiomolinステップに従いました。 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);
Tips:名前空間なしでXMLを変換する場合は、jacksonライブラリを使用します。 org.json libsを使用しないでください。このユースケースはサポートしていません。
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();
}
}
}