java管道流中的异常处理

java管道流中的异常处理,java,xml,exception-handling,stream-processing,java-threads,Java,Xml,Exception Handling,Stream Processing,Java Threads,我有一个xmlStream,我正在使用org.apache.wink.json4j.utils.XML将其转换为jsonStream。这是密码 public void process(InputStream xmlStream) { final BufferedInputStream bufferedXmlStream = new BufferedInputStream(xmlStream); PipedInputStream pipedJsonInputStream = ne

我有一个xmlStream,我正在使用
org.apache.wink.json4j.utils.XML
将其转换为jsonStream。这是密码

public void process(InputStream xmlStream) {
    final BufferedInputStream bufferedXmlStream = new BufferedInputStream(xmlStream);

    PipedInputStream pipedJsonInputStream = new PipedInputStream();
    final PipedOutputStream jsonStream = new PipedOutputStream(pipedJsonInputStream);
    Thread xmlToJsonThread = new Thread(new Runnable() {
        @Override
        public void run() {
            // put your code that writes data to the outputstream here.
            try {
                XML.toJson(bufferedXmlStream, jsonStream, true);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    });
    xmlToJsonThread.setDaemon(true);
    xmlToJsonThread.start();

    //process data from piped stream
    BufferedReader reader = new BufferedReader(new InputStreamReader(
            pipedJsonInputStream, StandardCharsets.UTF_8));
    try {
        // use reader to further process json in main thread...
        parseJsonStream(reader);
    } finally {
        reader.close();
        jsonStream.close();
    }
}
当XML.toJson抛出异常时,我看到主线程没有退出。 我该怎么处理?
你们认为这是一种将XML流转换为Json流以便进一步处理的好方法吗?如果有任何建议,我将不胜感激。非常感谢

问题是子线程上的异常需要报告回主线程。除非将读写器放在不同的线程中,否则这可能很棘手

我这样做的方式是将这两部分都包装在一个
ExecutionCompletionService
-如下所示:

public void process(InputStream xmlStream) {
    ExecutorService threadPool = Executors.newFixedThreadPool(2);
    ExecutorCompletionService<Void> ecs = new ExecutorCompletionService<>(threadPool);

    final BufferedInputStream bufferedXmlStream = new BufferedInputStream(xmlStream);

    PipedInputStream pipedJsonInputStream = new PipedInputStream();
    final PipedOutputStream jsonStream = new PipedOutputStream(pipedJsonInputStream);

    ecs.submit( new Callable<Void>() {
       @Override
       public Void call() {
          // put your code that writes data to the outputstream here.
          try {
              XML.toJson(bufferedXmlStream, jsonStream, true);
          } catch (Exception e) {
              e.printStackTrace();
              throw e;
          }
          return null;
        }
    });

    ecs.submit( new Callable<Void>() {
       @Override
       public Void call() {
          try {
              // use reader to further process json in main thread...
              parseJsonStream(reader);
          } finally {
              reader.close();
              jsonStream.close();
          }
          return null;
      }
    });

    // Wait for all tasks to be done.
    // Kill the other thread if one hits an exception.
    try {
        for (int i = 0; i < 2; ++i) {
            ecs.take().get();
        }
    } finally {
        threadPool.shutdownNow();
    } 
}
公共作废流程(InputStream xmlStream){
ExecutorService线程池=Executors.newFixedThreadPool(2);
ExecutorCompletionService ecs=新的ExecutorCompletionService(线程池);
final BufferedInputStream bufferedXmlStream=新的BufferedInputStream(xmlStream);
PipedInputStream pipedJsonInputStream=新的PipedInputStream();
最终PipedOutputStream jsonStream=新的PipedOutputStream(pipedJsonInputStream);
ecs.submit(新的可调用(){
@凌驾
公开作废通知(){
//将将数据写入outputstream的代码放在此处。
试一试{
toJson(bufferedXmlStream,jsonStream,true);
}捕获(例外e){
e、 printStackTrace();
投掷e;
}
返回null;
}
});
ecs.submit(新的可调用(){
@凌驾
公开作废通知(){
试一试{
//使用reader在主线程中进一步处理json。。。
parseJsonStream(阅读器);
}最后{
reader.close();
jsonStream.close();
}
返回null;
}
});
//等待所有任务完成。
//如果一个线程遇到异常,则杀死另一个线程。
试一试{
对于(int i=0;i<2;++i){
ecs.take().get();
}
}最后{
threadPool.shutdownNow();
} 
}

您当然需要确保
jsonStream
被关闭,最好是在
finally
block.EJP中关闭,谢谢您的关注。异常为“SAXParseException:实体“trade”已被引用,但未声明”。我可以修改xml来声明实体并解决这个问题。但这暴露了我代码中的一个bug——当抛出异常时,我看到主程序没有退出。我已经将线程设置为守护进程,还有什么我应该做的吗?是的,我已经关闭了资源。我更新了代码,以显示它迈克尔,这就像魅力工作,感谢您的帮助!