xstream xstreammarshaller cannotresolveclassexception java.util.arraylist

mefy6pfw  于 2021-07-22  发布在  Java
关注(0)|答案(2)|浏览(317)

我必须使用springbatch读取多个xml文件。
我使用的是xstream,我正在努力读取对象的数组列表。
错误堆栈:

at org.springframework.boot.devtools.restart.RestartLauncher.run(RestartLauncher.java:49) ~[spring-boot-devtools-2.4.3.jar:2.4.3]
Caused by: com.thoughtworks.xstream.converters.ConversionException: 
---- Debugging information ----
cause-exception     : com.thoughtworks.xstream.mapper.CannotResolveClassException
cause-message       : workCompany
class               : java.util.ArrayList
required-type       : java.util.ArrayList
converter-type      : com.thoughtworks.xstream.converters.collections.CollectionConverter
path                : /person/works/Work/workCompany
line number         : 15
class[1]            : com.oualid.xmltojava.model.Works
converter-type[1]   : com.thoughtworks.xstream.converters.reflection.ReflectionConverter
class[2]            : com.oualid.xmltojava.model.Person
version             : 5.3.4
-------------------------------
    at com.thoughtworks.xstream.core.TreeUnmarshaller.convert(TreeUnmarshaller.java:79) ~[xstream-1.4.9.jar:1.4.9]

我的波乔:

package com.oualid.xmltojava.model;

import com.thoughtworks.xstream.annotations.XStreamAlias;

import java.util.List;

@XStreamAlias("Person")
public class Person {
    @XStreamAlias("personId")
    private Integer personId;
    @XStreamAlias("firstName")
    private String firstName;
    @XStreamAlias("lastName")
    private String lastName;
    @XStreamAlias("email")
    private String email;
    @XStreamAlias("age")
    private Integer age;
    @XStreamAlias("contactDetails")
    private List<String> contactDetails;
    @XStreamAlias("works")
    private Works works;

    public Person(String firstName, String lastName) {
        this.firstName = firstName;
        this.lastName = lastName;
    }

    public Integer getPersonId() {
        return personId;
    }
    public void setPersonId(Integer personId) {
        this.personId = personId;
    }
    public String getFirstName() {
        return firstName;
    }
    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }
    public String getLastName() {
        return lastName;
    }
    public void setLastName(String lastName) {
        this.lastName = lastName;
    }
    public String getEmail() {
        return email;
    }
    public void setEmail(String email) {
        this.email = email;
    }
    public Integer getAge() {
        return age;
    }
    public void setAge(Integer age) {
        this.age = age;
    }

    public List<String> getContactDetails() {
        return contactDetails;
    }

    public void setContactDetails(List<String> contactDetails) {
        this.contactDetails = contactDetails;
    }

    public Works getWorks() {
        return works;
    }

    public void setWorks(Works works) {
        this.works = works;
    }
}
package com.oualid.xmltojava.model;

import com.thoughtworks.xstream.annotations.XStreamAlias;
import com.thoughtworks.xstream.annotations.XStreamImplicit;

import java.util.List;

@XStreamAlias("works")
public class Works {

   @XStreamImplicit(itemFieldName = "Work")
    private List<Work> Work;

    public List<Work> getWorks() {
        return Work;
    }

    public void setWorks(List<Work> works) {
        this.Work = works;
    }
}
package com.oualid.xmltojava.model;

import com.thoughtworks.xstream.annotations.XStreamAlias;

@XStreamAlias("Work")
public class Work {

    @XStreamAlias("workCompany")
    private String workCompany;
    @XStreamAlias("workMission")
    private String workMission;

    public String getWorkCompany() {
        return workCompany;
    }

    public void setWorkCompany(String workCompany) {
        this.workCompany = workCompany;
    }

    public String getWorkMission() {
        return workMission;
    }

    public void setWorkMission(String workMission) {
        this.workMission = workMission;
    }
}

我的一个xml文件:

<?xml version="1.0" encoding="UTF-8"?>
<persons>
    <person>
        <personId>1</personId>
        <firstName>PETER</firstName>
        <lastName>SCHMIDT</lastName>
        <email>pschmidt0@aboutads.info</email>
        <contactDetails>
            <string>contact1</string>
            <string>contact2</string>
        </contactDetails>
        <age>28</age>
        <works>
            <Work>
                <workCompany>ESI</workCompany>
                <workMission>Java Developper</workMission>
            </Work>
            <Work>
                <workCompany>ESI</workCompany>
                <workMission>JS Developper</workMission>
            </Work>
        </works>

    </person>
</persons>

ther阅读器

@Bean
    public StaxEventItemReader<Person> reader(){
        StaxEventItemReader<Person> reader = new StaxEventItemReader<Person>();
        //reader.setResource(new ClassPathResource("persons.xml"));
        reader.setFragmentRootElementName("person");

        Map<String,String> aliasesMap =new HashMap<String,String>();
        aliasesMap.put("person", "com.oualid.xmltojava.model.Person");
        aliasesMap.put("works", "com.oualid.xmltojava.model.Works");
        aliasesMap.put("Work", "com.oualid.xmltojava.model.Work");
        XStreamMarshaller marshaller = new XStreamMarshaller();
        marshaller.setAliases(aliasesMap);

        reader.setUnmarshaller(marshaller);

        return reader;
    }

有关信息,请将此读取器传递到 multiResourceItemReader 如果我没有 <works></works> 在我的xml文件中

vtwuwzda

vtwuwzda1#

springbatch不直接处理解组,而是将其委托给 org.springframework.oxm.Unmarshaller 从Spring开始。所以这个问题与springbatch本身无关,而是xstream的Map问题。
也就是说,根据你对集合的定义 Person.works 以及 Works.Work ,您需要在封送拆收器定义中添加隐式集合Map,如下所示:

Map<Class<?>, String> implicitCollections = new HashMap<>();
implicitCollections.put(Works.class, "Work");
marshaller.setImplicitCollections(implicitCollections);

编辑:你可以在这里找到一个完整的例子。

1yjd4xko

1yjd4xko2#

如果其他人也会面临同样的问题,我会发布回复:
即使我加了 @XStreamImplicit(itemFieldName = "Work") 我发现元帅不知道这个注解。
所以对我来说有两种可能的解决方案:
1-@马哈茂德本哈辛溶液。
2-只需激活自动检测注解 true ```
XStreamMarshaller marshaller = new XStreamMarshaller();
marshaller.setAutodetectAnnotations(true);

当然,不要忘记为列表添加注解:

@XStreamImplicit(itemFieldName = "Work")
private List Work;

我更喜欢第二个,因为我有一个非常复杂的xml,需要读取大量的对象集合,所以我想注解应该是干净的。
快乐编码:)

相关问题