我正在尝试使用spring batch将XML解析为Java对象,并且我将HierarchicalStreamReader用作转换器来解析并将XML标记中的对象值转换为POJO字段。但是,在进行转换时,我必须使用moveup()和moveDown()方法来解析数据,我认为这不是遵循的好习惯,因为如果XML标记中的字段位置发生更改,则会导致代码重写。我已经尝试过getAttribute(String name)方法,以使用其标记名来实现对我要获取的参数的更多控制,但是这给了我我无法修复的错误。
此外,该接口没有足够的文档。请帮助我解决这个问题,或建议我采用一种受控转换器的方法。预先感谢...
Student.xml
<students>
<student>
<name>Tony Tester</name>
<rollNo>1</rollNo>
<enrollmentDate>2016-10-31</enrollmentDate>
<sampleTimeStamp>2016-11-07T05:50:45</sampleTimeStamp>
<salary>16.57</salary>
</student>
<student>
<name>Nick Newbie</name>
<rollNo>2</rollNo>
<enrollmentDate>2017-10-31</enrollmentDate>
<sampleTimeStamp>2016-11-07T05:50:45</sampleTimeStamp>
<salary>29.68</salary>
</student>
<student>
<name>Ian Intermediate</name>
<rollNo>3</rollNo>
<enrollmentDate>2018-10-31</enrollmentDate>
<sampleTimeStamp>2016-11-07T05:50:45</sampleTimeStamp>
<salary>789.62</salary>
</student>
</students>
StudentDTO.java
@XmlRootElement(name="student")
public class StudentDTO
{
private String name;
private Integer rollNo;
private Date enrollmentDate;
private Date sampleTimeStamp;
private BigDecimal salary;
... getter, setter and constructor
}
StudentConverter.java
public class StudentConverter implements Converter
{
@Override
public boolean canConvert(@SuppressWarnings("rawtypes") Class type)
{
return type.equals(StudentDTO.class);
}
@Override
public void marshal(Object source, HierarchicalStreamWriter writer, MarshallingContext context)
{
// Nothing to marshal
}
@Override
public Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext context)
{
//reader.getAttribute(0) -- line causing error
//reader.getAttribute("name") -- return null
//reader.getAttributeCount() -- always return 0
reader.moveDown();
StudentDTO student = new StudentDTO();
student.setName(reader.getValue());
reader.moveUp();
reader.moveDown();
student.setRollNo(Integer.parseInt(reader.getValue()));
reader.moveUp();
reader.moveDown();
try
{
student.setEnrollmentDate(new SimpleDateFormat("yyyy-MM-dd").parse(reader.getValue()));
}
catch (ParseException e)
{
e.printStackTrace();
}
reader.moveUp();
reader.moveDown();
try
{
student.setSampleTimeStamp(new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss").parse(reader.getValue()));
}
catch (ParseException e)
{
e.printStackTrace();
}
reader.moveUp();
reader.moveDown();
student.setSalary(new BigDecimal(reader.getValue()));
return student;
}
}
用于reader.getAttribute(0)的StackTrace
java.lang.IllegalArgumentException
at org.springframework.util.xml.XMLEventStreamReader.getAttribute(XMLEventStreamReader.java:211)
at org.springframework.util.xml.XMLEventStreamReader.getAttributeValue(XMLEventStreamReader.java:192)
at com.thoughtworks.xstream.io.xml.StaxReader.getAttribute(StaxReader.java:92)
at com.thoughtworks.xstream.io.ReaderWrapper.getAttribute(ReaderWrapper.java:56)
at com.example.demo.utility.StudentConverter.unmarshal(StudentConverter.java:33)
at com.thoughtworks.xstream.core.TreeUnmarshaller.convert(TreeUnmarshaller.java:72)
at com.thoughtworks.xstream.core.AbstractReferenceUnmarshaller.convert(AbstractReferenceUnmarshaller.java:70)
at com.thoughtworks.xstream.core.TreeUnmarshaller.convertAnother(TreeUnmarshaller.java:66)
at com.thoughtworks.xstream.core.TreeUnmarshaller.convertAnother(TreeUnmarshaller.java:50)
at com.thoughtworks.xstream.core.TreeUnmarshaller.start(TreeUnmarshaller.java:134)
at com.thoughtworks.xstream.core.AbstractTreeMarshallingStrategy.unmarshal(AbstractTreeMarshallingStrategy.java:32)
at com.thoughtworks.xstream.XStream.unmarshal(XStream.java:1230)
at org.springframework.oxm.xstream.XStreamMarshaller.doUnmarshal(XStreamMarshaller.java:826)
at org.springframework.oxm.xstream.XStreamMarshaller.unmarshalXmlStreamReader(XStreamMarshaller.java:786)
at org.springframework.oxm.xstream.XStreamMarshaller.unmarshalXmlEventReader(XStreamMarshaller.java:777)
at org.springframework.oxm.support.AbstractMarshaller.unmarshalStaxSource(AbstractMarshaller.java:411)
at org.springframework.oxm.support.AbstractMarshaller.unmarshal(AbstractMarshaller.java:354)
at org.springframework.batch.item.xml.StaxEventItemReader.doRead(StaxEventItemReader.java:255)
at org.springframework.batch.item.support.AbstractItemCountingItemStreamItemReader.read(AbstractItemCountingItemStreamItemReader.java:92)
at org.springframework.batch.item.support.SynchronizedItemStreamReader.read(SynchronizedItemStreamReader.java:55)
at org.springframework.batch.item.support.SynchronizedItemStreamReader$$FastClassBySpringCGLIB$$987ea09.invoke(<generated>)
at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218)
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:749)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163)
at org.springframework.aop.support.DelegatingIntroductionInterceptor.doProceed(DelegatingIntroductionInterceptor.java:136)
at org.springframework.aop.support.DelegatingIntroductionInterceptor.invoke(DelegatingIntroductionInterceptor.java:124)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:688)
at org.springframework.batch.item.support.SynchronizedItemStreamReader$$EnhancerBySpringCGLIB$$66d53b5e.read(<generated>)
at org.springframework.batch.core.step.item.SimpleChunkProvider.doRead(SimpleChunkProvider.java:94)
at org.springframework.batch.core.step.item.SimpleChunkProvider.read(SimpleChunkProvider.java:161)
at org.springframework.batch.core.step.item.SimpleChunkProvider$1.doInIteration(SimpleChunkProvider.java:119)
at org.springframework.batch.repeat.support.RepeatTemplate.getNextResult(RepeatTemplate.java:375)
at org.springframework.batch.repeat.support.RepeatTemplate.executeInternal(RepeatTemplate.java:215)
at org.springframework.batch.repeat.support.RepeatTemplate.iterate(RepeatTemplate.java:145)
at org.springframework.batch.core.step.item.SimpleChunkProvider.provide(SimpleChunkProvider.java:113)
at org.springframework.batch.core.step.item.ChunkOrientedTasklet.execute(ChunkOrientedTasklet.java:69)
at org.springframework.batch.core.step.tasklet.TaskletStep$ChunkTransactionCallback.doInTransaction(TaskletStep.java:407)
at org.springframework.batch.core.step.tasklet.TaskletStep$ChunkTransactionCallback.doInTransaction(TaskletStep.java:331)
at org.springframework.transaction.support.TransactionTemplate.execute(TransactionTemplate.java:140)
at org.springframework.batch.core.step.tasklet.TaskletStep$2.doInChunkContext(TaskletStep.java:273)
at org.springframework.batch.core.scope.context.StepContextRepeatCallback.doInIteration(StepContextRepeatCallback.java:82)
at org.springframework.batch.repeat.support.TaskExecutorRepeatTemplate$ExecutingRunnable.run(TaskExecutorRepeatTemplate.java:262)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:748)
[注意]::我尝试使用以下属性进行调试:
reader.getAttribute(0)
-引发错误
reader.getAttribute("name")
-返回null
reader.getAttributeCount()
-始终返回0
我不确定为什么reader.getAttributeCount()返回零,因为每个学生条目有5个字段。
我想要做的是对StudentConverter.unmarshal部分进行更多控制,我想通过属性名称或标识符来获取属性值,而不是通过xml中的位置来获取属性值,因为位置是动态的,以后可能会更改。
答案 0 :(得分:0)
从XML的角度来看,当您拥有 > uncenter.distance(matrix(1:6,nrow=2))
[,1] [,2]
[1,] -0.3163105 -0.3591645
[2,] -0.3591645 -0.4142136
之类的内容时,<a b="...">...</a>
是一个元素,而a
是一个属性。
您的XML没有任何属性。这就是为什么b
的值为零,而.getAttributeCount()
的例外。
实现所需目标的一种常用方法是使用杰克逊(Jackson)这样的工具,并根据需要的输入和输出使用相关的配置/注释来匹配每个字段。有关如何处理的基本说明,请参见here。