[英]JAXB Unmarshalling to Java POJO
我想將此 XMl 轉換為 java Object 但不知道如何為它制作 POJO ZA2F21ED4F8EBC2CDCB4。 我無法更改此 xml,因為它作為請求來自遠程服務器,我需要它包含的所有信息才能響應。
<?xml version="1.0" encoding="utf-8"?>
<methodCall>
<methodName>name</methodName>
<params>
<param><value><struct>
<member>
<name>subscriberInput</name>
<value><string>678</string></value>
</member>
<member>
<name>language</name>
<value><string>en</string></value>
</member>
<member>
<name>sessionId</name>
<value><string>16414746570268014</string></value>
</member>
<member><name>msisdn</name><value><string>1234</string></value>
</member>
<member>
<name>newRequest</name>
<value><string>1</string></value>
</member>
<member>
<name>transactionId</name>
<value><string>0122716414746578950</string>
</value>
</member>
</struct>
</value>
</param>
</params>\</methodCall>
您可以使用以下工具的組合:
結果如下:
// import com.fasterxml.jackson.databind.ObjectMapper; // version 2.11.1
// import com.fasterxml.jackson.annotation.JsonProperty; // version 2.11.1
/* ObjectMapper om = new ObjectMapper();
Root root = om.readValue(myJsonString), Root.class); */
public class Value2{
public String string;
public Struct struct;
}
public class Member{
public String name;
public Value value;
}
public class Struct{
public List<Member> member;
}
public class Param{
public Value value;
}
public class Params{
public Param param;
}
public class MethodCall{
public String methodName;
public Params params;
}
public class Root{
public MethodCall methodCall;
}
我希望我能幫助你。
將此 xml 轉換為https://codebeautify.org/xml-to-java-converter ,它會產生我們(“快速”,“好”)的結果:
我們可以復制並粘貼生成的 class,但仍然需要少量重構:
Struct
但是,我們“已經懷疑”:問題在於細節,細節在於結構:
package com.example.simpleschema;
import java.util.ArrayList;
public class MethodCall {
private String methodName;
Params ParamsObject;
// Getter Methods
public String getMethodName() {
return methodName;
}
public Params getParams() {
return ParamsObject;
}
// Setter Methods
public void setMethodName(String methodName) {
this.methodName = methodName;
}
public void setParams(Params paramsObject) {
this.ParamsObject = paramsObject;
}
}
class Params {
Param ParamObject;
// Getter Methods
public Param getParam() {
return ParamObject;
}
// Setter Methods
public void setParam(Param paramObject) {
this.ParamObject = paramObject;
}
}
class Param {
Value ValueObject;
// Getter Methods
public Value getValue() {
return ValueObject;
}
// Setter Methods
public void setValue(Value valueObject) {
this.ValueObject = valueObject;
}
}
class Value {
Struct StructObject;
// Getter Methods
public Struct getStruct() {
return StructObject;
}
// Setter Methods
public void setStruct(Struct structObject) {
this.StructObject = structObject;
}
}
class Struct {
ArrayList< Object> member = new ArrayList< Object>();
public ArrayList<Object> getMember() {
return member;
}
public void setMember(ArrayList<Object> member) {
this.member = member;
}
}
在我們的 pom 中使用(僅)這個:
<dependency>
<groupId>com.fasterxml.jackson.dataformat</groupId>
<artifactId>jackson-dataformat-xml</artifactId>
<version>2.13.1</version> <!-- or newer -->
</dependency>
我們能做到這一點:
package com.example.xmltest.simple;
import com.example.simpleschema.MethodCall;
import com.fasterxml.jackson.dataformat.xml.XmlMapper;
import java.io.IOException;
public class MainSimple {
public static void main(String[] args) throws IOException {
final XmlMapper xmlMapper = new XmlMapper();
MethodCall value = xmlMapper
.readValue(MainSimple.class.getResourceAsStream("/test.xml"), MethodCall.class);
System.out.println(value);
xmlMapper.writeValue(System.out, value);
}
}
印刷:
com.example.simpleschema.MethodCall@23529fee
<MethodCall><methodName>name</methodName><params><param><value><struct><member><member>transactionId</member><member><string>0122716414746578950</string></member></member></struct></value></param></params></MethodCall>
我們首先需要一個 xsd:我們可以:
“快速”查找將我們引導至https://docs.microsoft.com/en-us/visualstudio/xml-tools/how-to-create-an-xml-schema-from-一個 XML 文檔。 在vscode中單擊,我們的 xsd 看起來像:
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="methodCall">
<xs:complexType>
<xs:sequence>
<xs:element name="methodName" type="xs:string" />
<xs:element name="params">
<xs:complexType>
<xs:sequence>
<xs:element name="param">
<xs:complexType>
<xs:sequence>
<xs:element name="value">
<xs:complexType>
<xs:sequence>
<xs:element name="struct">
<xs:complexType>
<xs:sequence>
<xs:element name="member" maxOccurs="unbounded">
<xs:complexType>
<xs:sequence>
<xs:element name="name" type="xs:string" />
<xs:element name="value">
<xs:complexType>
<xs:sequence>
<xs:element name="string" type="xs:string" />
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
將此test.xsd
放在src/main/xsd
下(codehaus 的標准位置:jaxb2-maven-plugin),並將以下內容添加到我們的 pom 中(對不起@allgradel-users):
...
<build>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>jaxb2-maven-plugin</artifactId>
<version>2.5.0</version> <!-- this depends on org.glassfish.jaxb:2.3.2!! -->
<executions>
<execution>
<id>xjc</id>
<goals>
<goal>xjc</goal>
</goals>
</execution>
</executions>
<configuration>
<!-- The (target) package of your generated sources -->
<packageName>com.example.jaxbschema</packageName> <!-- .${project.version} -->
</configuration>
</plugin>
</plugins>
</build>
...
在下一個mvn process-classes
(或以上/或由 IDE 完成)上,這將在src/target/generated-sources/jaxb/
中為我們生成一些“精細”類......這些是不可編譯的,(或結構太遞歸了,或者是 jaxb(impl)-bug,隨意考慮)
手動...但必須將生成的com.example.myschema
移動到“主”源,停用 jaxb-plugin,並修復由最內部Value
引起的名稱沖突:
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "value", propOrder = {
"string"
})
public static class Value2 { ...
...並解決剩余的編譯器沖突。
至少對於 jackson,這個(生成和調整的模型)似乎仍然存在問題。
有了這個, spring-boot和spring-oxm :
...
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.6.2</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<!-- Spring OXM: needs jaxb -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-oxm</artifactId>
<!-- managed by spring-boot: 5.3.14 -->
</dependency>
<dependency>
<groupId>javax.xml.bind</groupId>
<artifactId>jaxb-api</artifactId>
<!-- managed by spring-boo: 2.3.1 -->
</dependency>
<dependency>
<groupId>org.glassfish.jaxb</groupId>
<artifactId>jaxb-runtime</artifactId>
<scope>runtime</scope>
<!-- managed by spring-boo: 2.3.5 -->
</dependency>
</dependencies>
...
我們可以:
// ...
import com.example.jaxbschema.MethodCall; // !! same as generated/refactored.
// ...
@SpringBootApplication
public class SpringMain {
public static void main(String[] args) {
SpringApplication.run(SpringMain.class, args);
}
@Bean
org.springframework.oxm.jaxb.Jaxb2Marshaller jaxb2Marshaller() {
Jaxb2Marshaller mler = new org.springframework.oxm.jaxb.Jaxb2Marshaller();
mler.setClassesToBeBound(MethodCall.class);
return mler;
}
@Bean
@Autowired
CommandLineRunner runner(
@Value("test.xml") Resource xmlFile,
org.springframework.oxm.jaxb.Jaxb2Marshaller jaxb2Marshaller
) {
return (args) -> {
MethodCall readValue2 = (MethodCall) jaxb2Marshaller.unmarshal(new StreamSource(xmlFile.getInputStream()));
jaxb2Marshaller.marshal(readValue2, new StreamResult(System.out));
};
}
}
...打印:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?><methodCall><methodName>name</methodName><params><param><value><struct><member><name>subscriberInput</name><value><string>678</string></value></member><member><name>language</name><value><string>en</string></value></member><member><name>sessionId</name><value><string>16414746570268014</string></value></member><member><name>msisdn</name><value><string>1234</string></value></member><member><name>newRequest</name><value><string>1</string></value></member><member><name>transactionId</name><value><string>0122716414746578950</string></value></member></struct></value></param></params></methodCall>
..我們只需要“很少值”的形式,我們應該考慮一種更有效(基於解析器)的方法......
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.