0

У меня есть xmlStream, который я конвертирую в jsonStream, используя org.apache.wink.json4j.utils.XML. Вот кодОбработка Исключения в потоках трубопровода java

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 для дальнейшей обработки? Я был бы очень признателен за любые предложения. Большое спасибо!

+0

Вы, безусловно, необходимо, чтобы убедиться, что 'jsonStream' закрывается, предпочтительно в' finally' блока. – EJP

+0

EJP, спасибо за это. Исключением является «SAXParseException: сущность« торговля »была указана, но не объявлена». Я могу потенциально изменить xml, чтобы объявить объекты и решить проблему. Но это выявило ошибку в моем коде - когда выбрано исключение, я вижу, что основная программа не выходит. Я уже установил поток в качестве демона, что-нибудь еще, что я должен делать? – user1739372

+0

Да, я закрыл ресурсы. Я обновил код, чтобы показать его – user1739372

ответ

1

Проблема в том, что исключение в дочернем потоке должно быть возвращено в основной поток. Это может быть сложно сделать, если вы не поместите читателя и писателя в отдельные потоки.

Как я сделать это, чтобы обернуть обе части в 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(); 
    } 
} 
+0

Майкл, это сработало как шарм, ценю вашу помощь! – user1739372