2013-03-15 47 views
4

我正在嘗試編寫一個查看一些DICOM文件的WebApplication。我的想法是通過調用我的servlet,將DICOM文件轉換爲JPEG。 我使用dcm4che 2.0.27來轉換文件。Java Servlets和ImageIO錯誤

該servlet被稱爲像

<img src="pathToServlet/PathToDICOMFile">. 

的問題:當我有很多標籤(當然針對不同的DICOM文件)有時候我型java.util.ConcurrentModificationException的異常

這裏該方法,我的servlet呼籲:

void convertFile(String path, OutputStream to) throws IOException { 
    File myDicomFile = new File(path); 

    BufferedImage myJpegImage = null; 
    ImageIO.scanForPlugins(); 
    Iterator<ImageReader> iter = ImageIO.getImageReadersByFormatName("DICOM"); 

    ImageReader reader = (ImageReader) iter.next(); 

    DicomImageReadParam param = (DicomImageReadParam) reader.getDefaultReadParam(); 

    ImageInputStream iis = ImageIO.createImageInputStream(myDicomFile); 
    reader.setInput(iis, false); 
    myJpegImage = reader.read(0, param); 
    iis.close(); 
    ImageIO.write(myJpegImage, "JPEG", to); 

    to.close(); 

} 

「路徑」是對DICOM文件的絕對路徑和「out」只是response.getOutputStream()。

異常可以在3個地方被拋出:

  1. ImageIO.getImageReadersByFormatName( 「DICOM」);
  2. myJpegImage = reader.read(0,param);
  3. ImageIO.write(myJpegImage,「JPEG」,to);

這裏是一個堆棧跟蹤它調用ImageIO.getImageReadersByFormatName時( 「DICOM」)被拋出:

java.util.ConcurrentModificationException 
at java.util.HashMap$HashIterator.nextEntry(HashMap.java:806) 
at java.util.HashMap$ValueIterator.next(HashMap.java:835) 
at javax.imageio.spi.PartialOrderIterator.<init>(PartiallyOrderedSet.java:177) 
at javax.imageio.spi.PartiallyOrderedSet.iterator(PartiallyOrderedSet.java:85) 
at javax.imageio.spi.SubRegistry.getServiceProviders(ServiceRegistry.java:759) 
at javax.imageio.spi.ServiceRegistry.getServiceProviders(ServiceRegistry.java:451) 
at javax.imageio.spi.ServiceRegistry.getServiceProviders(ServiceRegistry.java:507) 
at javax.imageio.ImageIO.getImageReadersByFormatName(ImageIO.java:708) 
at example.project.dicomtest.myDicomConverter.ConvertHelper.convertFile(ConvertHelper.java:32) 
at example.project.dicomtest.myDicomConverter.GetImage.doGet(GetImage.java:40) 
at javax.servlet.http.HttpServlet.service(HttpServlet.java:621) 
at javax.servlet.http.HttpServlet.service(HttpServlet.java:722) 
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:304) 
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210) 
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:224) 
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:185) 
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472) 
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:151) 
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:100) 
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:929) 
at org.apache.catalina.core.StandardEnginateValve.invoke(StandardEngineValve.java:118) 
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:405) 
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:269) 
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:515) 
at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:302) 
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1110) 
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603) 
at java.lang.Thread.run(Thread.java:722) 

是因爲ImageIO的不是線程安全的?我能做些什麼來解決這個問題? 非常感謝您的任何幫助和最好的問候!

回答

6

這兩條線:

ImageIO.scanForPlugins(); 
Iterator<ImageReader> iter = ImageIO.getImageReadersByFormatName("DICOM"); 

只需要一次完成,當你的應用程序加載或你的servlet被初始化時。特別是,第一行ImageIO.scanForPlugins()在內部突變了ImageIO類使用的共享數據。這可能是您的併發修改異常的原因。考慮將這兩行移至servlet過濾器或者servlet的init(ServletConfig)方法。

+0

非常感謝!這是解決方案! – mesx 2013-03-18 09:18:03

1

使用同步方法來防止併發修改可以有所幫助。閱讀這個問題

stackoverflow.com/questions/9884148/use-of-synchronized-method-in-affable-bean-shopping-cart