JAXB对Java POJO的解组



我想把这个XMl转换成java Object,但不知道如何为它创建POJO类。我不能更改这个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>

您可以使用以下工具的组合:

  1. 将XML解析为JSON(https://www.convertjson.com/xml-to-json.htm)
  2. 从JSON创建POJO(https://json2csharp.com/json-to-pojo)

结果是下一个:

// 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;
}

我希望我能帮助你。

Pojo方法

将此xml带到https://codebeautify.org/xml-to-java-converter,它给我们带来了("快"、"好"(结果:

我们可以复制&粘贴生成的类,但仍需要少量重构:

  • 取消公开所有类(或将它们移动到单独的文件中(
  • Struct的完全getter/setter

但是,我们;嫌疑犯已经":问题在于细节,细节在于结构:

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>

使用JAXB

我们需要先创建xsd!我们可以:

  • 询问我们的供应商,他是否会为我们提供…或
  • 我们自己生成

A";快速";查找引导我们(如今,使用开源(https://learn.microsoft.com/en-us/visualstudio/xml-tools/how-to-create-an-xml-schema-from-an-xml-document。在vscode中单击clack,我们的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插件的标准操作(下,并将以下内容添加到我们的pom中(对不起@所有gradel用户(:

...
<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(错误,可以随意考虑(


我们可以修复

手动。。。但必须将生成的CCD_ 6移动到"0";主";源代码,取消激活jaxb插件,并修复由最内部的Value:引起的名称冲突

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "value", propOrder = {
"string"
})
public static class Value2 { ...

以及解决剩余的编译器冲突。


这个(生成和调整的模型(似乎仍然有问题,至少对jackson来说是这样。


有了这个,弹簧套和弹簧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>

当结构/XML较大/复杂时

而我们只需要";"很少的值";因此,我们应该考虑一种更有效的(基于解析器的(方法。。。

最新更新