繁体   English   中英

JAXB 解组到 Java POJO

[英]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>

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

  1. 将 XML 解析为 JSON ( https://www.convertjson.com/xml-to-json.htm )
  2. 从 JSON ( https://json2csharp.com/json-to-pojo ) 创建 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 ,它会产生我们(“快速”,“好”)的结果:

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

  • 取消公开所有类(或将它们移动到单独的文件)
  • 结构的完整 getter/ 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>

带 JAXB

我们首先需要一个 xsd:我们可以:

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

“快速”查找将我们引导至https://docs.microsoft.com/en-us/visualstudio/xml-tools/how-to-create-an-xml-schema-from-一个 XML 文档 中单击,我们的 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,这个(生成和调整的模型)似乎仍然存在问题。


有了这个,

...
  <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 大/复杂时

..我们只需要“很少值”的形式,我们应该考虑一种更有效(基于解析器)的方法......

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM