前言
本文主要的内容,就是讲述,第三方客户端,在指定的文件夹生成了对应的xml文件,java程序需要监听对应的文件夹,并解析xml文件内容,转成javaBean,主要使用到了xjc生成对应的实体类,在经过监听文件变化,加载xml数据,转换成对应的bean实例,采用的技术有Spring boot、XJC、commons-io
一、通过xjc,将xml转成javaBean
通过java工具jar包中的xjc,将xml生成对应的实体类,使用cmd,运行下面指令,参数要参考参数列表说明
java -Dfile.encoding=UTF-8 -cp D:\java\jdk1.6.0_03\lib\tools.jar com.sun.tools.internal.xjc.Driver -p com.geostar.csw.domain.layer -d c:\test
参数 | 参数说明 |
---|---|
tools.jar | 是jdk路径下的一个工具包,路径在jdk路径下面的lib中 |
-Dfile.encoding=UTF-8 | 是指定生成java实体类的文件编码 |
-p | 生成的包路径 |
-d | 生成的路径 |
把生成的实体类放到对应的项目中,对应的实体类中有对应的xml注解
二、编写FileAlterationListenerAdaptor文件监听的实现类
package com.example.sub_demo.service;
import com.example.sub_demo.entity.DecMessage;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.monitor.FileAlterationListenerAdaptor;
import org.apache.commons.io.monitor.FileAlterationObserver;
import org.springframework.stereotype.Component;
import org.springframework.util.ResourceUtils;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Unmarshaller;
import java.io.File;
@Slf4j
public class DirectoryWatchService extends FileAlterationListenerAdaptor {
@Override
public void onStart(FileAlterationObserver observer) {
log.debug("开始对目录:{}进行监听", observer.getDirectory().getPath());
}
@Override
public void onDirectoryCreate(File directory) {
log.info("目录:{}创建", directory.getPath());
}
@Override
public void onDirectoryChange(File directory) {
log.info("目录:{}改变", directory.getPath());
}
@Override
public void onDirectoryDelete(File directory) {
log.info("目录:{}被删除", directory.getPath());
}
@Override
public void onFileCreate(File file) {
log.info("文件:{}创建", file.getPath());
JAXBContext context;
try {
//创建JAXB上下文
context = JAXBContext.newInstance(DecMessage.class);
//Unmarshaller可以将xml内容,转换成javabean
Unmarshaller unmarshaller = context.createUnmarshaller();
//重指定xml文件,解析dom树,并绑定对应的java bean
DecMessage decMessage=(DecMessage)unmarshaller.unmarshal(ResourceUtils.getFile(file.getPath()));
//处理完业务逻辑,删除文件
FileUtils.deleteQuietly(file);
} catch (Exception e) {
}
}
@Override
public void onFileChange(File file) {
log.info("文件:{}改变", file.getPath());
}
@Override
public void onFileDelete(File file) {
log.info("文件:{}删除", file.getPath());
}
@Override
public void onStop(FileAlterationObserver observer) {
log.debug("停止目录{}监听", observer.getDirectory().getPath());
super.onStop(observer);
}
}
三、 创建file的配置类,作用是实例化其他的bean
package com.example.sub_demo.config;
import com.example.sub_demo.service.DirectoryWatchService;
import com.example.sub_demo.service.FileWatchPathService;
import org.apache.commons.io.monitor.FileAlterationMonitor;
import org.apache.commons.io.monitor.FileAlterationObserver;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.io.FileFilter;
import java.util.List;
@Configuration
public class FileConfig {
//创建文件过滤器,过滤哪些文件需要被监听
@Bean
public FileFilter bchtFileFilter(){
return pathname -> {
if(pathname.getPath().endsWith(".xml") || pathname.getPath().endsWith(".XML")){
return true;
}
return false;
};
}
//创建对应的文件监听实现类
@Bean
public DirectoryWatchService directoryWatchService(){
return new DirectoryWatchService();
}
/**
* 目录监听器
*
* @return
*/
@Bean
public FileAlterationMonitor fileAlterationMonitor(FileWatchPathService fileWatchPathService,DirectoryWatchService directoryWatchService, FileFilter bchtFileFilter) {
Logger log=LoggerFactory.getLogger(FileConfig.class);
//监控器 100 监控刷新时间
FileAlterationMonitor monitor = new FileAlterationMonitor(100);
//从service数据库中,获取需要监听的文件夹
List<String> directoryPath=fileWatchPathService.getWatchFilePath();
// 多个文件夹监控,需要add多个观察者
for (String path : directoryPath) {
log.info("监听目录:{}", path);
//对某个路径的观察者
FileAlterationObserver observer = new FileAlterationObserver(path, bchtFileFilter);
// 增加文件过滤,符合文件后缀的文件才进行处理,防止操作系统中生成的临时文件无法处理
//添加监听事件响应,与path无关,rsync同步需要
observer.addListener(directoryWatchService);
//将观察者添加到监控器
monitor.addObserver(observer);
}
return monitor;
}
}
四、启动FileAlterationMonitor
实现spring boot的CommandLineRunner接口,在应用启动后,进行启动FileAlterationMonitor
package com.example.sub_demo.listener;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.monitor.FileAlterationMonitor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.ApplicationRunner;
import org.springframework.boot.CommandLineRunner;
import org.springframework.stereotype.Component;
@Slf4j
@Component
public class RunnerEvent implements CommandLineRunner {
@Autowired
private FileAlterationMonitor fileAlterationMonitor;
@Override
public void run(String... args) throws Exception {
fileAlterationMonitor.start();
}
}
五、番外
如果实体类中加有javax.xml包下的注解,例如XmlRootElement,我们就可以直接通过restful,去接收对于的参数,记得选择参数类型为xml
后端定义请求方法,会自动把xml数据,解析到实体类
2:FileAlterationMonitor类可以动态开启监听、关闭监听,同时也可以动态添加监听路径,和动态删除监听路径
FileAlterationMonitor fileAlterationMonitor=new FileAlterationMonitor();
方法 | 说明 |
---|---|
fileAlterationMonitor.stop(10) | 在多少毫秒后,停止监听,参数可不传 |
fileAlterationMonitor.removeObserver(observer) | 删除监听 |
fileAlterationMonitor.addObserver(observer) | 添加监听 |
fileAlterationMonitor.start() | 启动监听 |
//observer是监听对象,第一个参数就是监听路径,第二个参数就是文件过滤器
FileAlterationObserver observer = new FileAlterationObserver(path, bchtFileFilter);