在服务器上有一个进程,每隔一个特定的时间间隔(例如5分钟)从特定目录中获取文件。 正在拾取的文件是由Web服务生成的。 JAXB编组将文件从对象转换为xml文件。 问题是文件在完成之前被频繁拾取。 解决方案是将文件放在临时目录中,或者为它们提供临时的特定扩展,让轮询过程知道跳过这些。 之后,可以将文件移动到处理目录,也可以更改扩展名,以便轮询过程可以将其取出。
该方法如下所示;
private void writeToFile(Object obj, String outputFileName) {
LOG.debug("Executing operation writeToFile using filename '{}' and object of type '{}'.", outputFileName, obj.getClass());
try {
Marshaller jaxbMarshaller = JAXB_CONTEXT.createMarshaller();
jaxbMarshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
jaxbMarshaller.marshal(obj, new File(outputFileName));
LOG.debug("Wrote request to file '{}'.", outputFileName);
} catch (JAXBException e) {
LOG.error("Exception occurred while writing request to file:", e);
}
LOG.debug("Done executing operation writeToFile.");
}
我的问题很热,要确定编组过程已完成,以便文件可以发布以便进一步处理?
答案 0 :(得分:1)
请从此链接下载代码[https://turreta.com/2017/03/07/jaxb-perform-pre-and-post-processing-with-unmarshaller-listener/]将以下Person Marshall Listener代码添加到源代码,因为这将调用每个节点已检查Person内部的根节点实例(这需要修改作为基本节点)在Marshall方法之前和之后,也使用了2的计数,因为每次开始和结束节点都会调用它,因为这应该仅在结束节点上调用,如果count == 2
package com.turreta.jaxb.unmarshaller.listener;
public class PersonMarshallListener extends javax.xml.bind.Marshaller.Listener {
int beforeCount = 1;
int afterCount = 1;
@Override
public void beforeMarshal(Object source) {
super.beforeMarshal(source);
if (source instanceof Person) {
if (beforeCount == 2) {
beforeCount = 1;
System.out.println("BEFORE MARSHAL");
} else {
beforeCount++;
}
}
}
@Override
public void afterMarshal(Object source) {
super.afterMarshal(source);
if (source instanceof Person) {
if (afterCount == 2) {
afterCount = 1;
System.out.println("AFTER MARSHAL");
// System.out.println("This will be called once the marshall has been completed");
} else {
afterCount++;
}
}
}
}
用以下代码替换DemoApp
package com.turreta.jaxb.unmarshaller.listener;
import java.io.FileInputStream;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLStreamReader;
public class DemoApp {
public static void main(String[] args) throws Exception {
JAXBContext jc = JAXBContext.newInstance(Person.class);
XMLInputFactory xif = XMLInputFactory.newFactory();
FileInputStream xml = new FileInputStream("src/main/resources/person.xml");
XMLStreamReader xsr = xif.createXMLStreamReader(xml);
Unmarshaller unmarshaller = jc.createUnmarshaller();
PersonUnmarshallListener pul = new PersonUnmarshallListener();
unmarshaller.setListener(pul);
Person person = (Person) unmarshaller.unmarshal(xsr);
System.out.println(person);
Marshaller marshaller = jc.createMarshaller();
marshaller.setListener(new PersonMarshallListener());
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
marshaller.marshal(person, System.out);
}
}
答案 1 :(得分:0)
以下是一些代码,我是如何解决它的(Spring Integration)
您创建一个缓冲区来存储不够大的文件,并在以后处理它们。
我知道这不是完美的(有了睡眠),但它有效。更好的解决方案不是使用文件交换,而是使用REST-api传输数据。
import com.google.common.collect.Lists;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.integration.core.MessageSource;
import org.springframework.messaging.Message;
import java.io.File;
import java.util.List;
public class LastModifiedFileReadingMessageSource implements MessageSource<File> {
private final Logger log = LoggerFactory.getLogger(LastModifiedFileReadingMessageSource.class);
private final MessageSource fileReadingMessageSource;
private final List<Message<File>> buffer = Lists.newArrayList();
private final long age = 60;
public LastModifiedFileReadingMessageSource(MessageSource fileReadingMessageSource) {
this.fileReadingMessageSource = fileReadingMessageSource;
}
public Message<File> receive() {
Message<File> message = fileReadingMessageSource.receive();
while (message != null) {
if (isOldEnough(message)) {
return message;
} else {
buffer.add(message);
log.info("Buffering file which is not old enough: {}; Buffer size: ", message, buffer.size());
}
message = fileReadingMessageSource.receive();
}
while (!buffer.isEmpty()) {
message = buffer.stream().filter(this::isOldEnough).findFirst().orElse(null);
if (message != null) {
buffer.remove(message);
log.info("Use file from buffer: {}; Buffer size: ", message, buffer.size());
return message;
}
sleep();
}
return message;
}
private void sleep() {
try {
log.info("Go to sleep for a while... ({} seconds)", age);
Thread.sleep(this.age * 1000);
} catch (InterruptedException e) {
log.error("Thread.sleep was never a good idea ;(", e);
}
}
private boolean isOldEnough(Message<File> message) {
long now = System.currentTimeMillis() / 1000;
return (message.getPayload().lastModified() / 1000 + this.age <= now);
}
}