Servlets Java servlet和ImageIO错误

Servlets Java servlet和ImageIO错误,servlets,thread-safety,javax.imageio,dicom,dcm4che,Servlets,Thread Safety,Javax.imageio,Dicom,Dcm4che,我正在尝试编写一个Web应用程序,它可以查看一些DICOM文件。我的想法是通过调用servlet将DICOM文件动态转换为JPEG。 我使用dcm4che 2.0.27转换文件 servlet被称为like <img src="pathToServlet/PathToDICOMFile">. 。 问题是:当我有许多标记(当然是寻址不同的DICOM文件)时,有时会出现java.util.ConcurrentModificationException类型的异常 下面是我的servle

我正在尝试编写一个Web应用程序,它可以查看一些DICOM文件。我的想法是通过调用servlet将DICOM文件动态转换为JPEG。 我使用dcm4che 2.0.27转换文件

servlet被称为like

<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();

}
void convertFile(字符串路径,输出流到)引发IOException{
File myDicomFile=新文件(路径);
BuffereImage myJpegImage=null;
ImageIO.scanForPlugins();
迭代器iter=ImageIO.getImageReadersByFormatName(“DICOM”);
ImageReader=(ImageReader)iter.next();
DicomImageReadParam=(DicomImageReadParam)读取器。getDefaultReadParam();
ImageInputStream iis=ImageIO.createImageInputStream(myDicomFile);
reader.setInput(iis,false);
myJpegImage=reader.read(0,参数);
iis.close();
写入(MyJPEG图像,“JPEG”,至);
to.close();
}
“path”是dicom文件的绝对路径,“out”只是response.getOutputStream()

异常可以在3个位置引发:

  • getImageReadersByFormatName(“DICOM”)
  • myJpegImage=reader.read(0,参数)
  • 写入(MyJPEG图像,“JPEG”,至) 下面是调用ImageIO.getImageReadersByFormatName(“DICOM”)时抛出的堆栈跟踪:

    java.util.ConcurrentModificationException
    位于java.util.HashMap$HashIterator.nextery(HashMap.java:806)
    在java.util.HashMap$ValueIterator.next(HashMap.java:835)
    位于javax.imageio.spi.partialOrderWriter。(PartiallyOrderedSet.java:177)
    在javax.imageio.spi.partialyorderedset.iterator(partialyorderedset.java:85)
    位于javax.imageio.spi.subistry.getServiceProviders(ServiceRegistry.java:759)
    位于javax.imageio.spi.ServiceRegistry.getServiceProviders(ServiceRegistry.java:451)
    位于javax.imageio.spi.ServiceRegistry.getServiceProviders(ServiceRegistry.java:507)
    位于javax.imageio.imageio.getImageReadersByFormatName(imageio.java:708)
    例如.project.dicomtest.myDicomConverter.ConvertHelper.convertFile(ConvertHelper.java:32)
    例如.project.dicomtest.mydicomconconverter.GetImage.doGet(GetImage.java:40)
    位于javax.servlet.http.HttpServlet.service(HttpServlet.java:621)
    位于javax.servlet.http.HttpServlet.service(HttpServlet.java:722)
    位于org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:304)
    位于org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
    位于org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:224)
    位于org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:185)
    位于org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472)
    位于org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:151)
    位于org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:100)
    位于org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:929)
    位于org.apache.catalina.core.StandardEnginateValve.invoke(StandardEngineValve.java:118)
    位于org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:405)
    位于org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:269)
    位于org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:515)
    位于org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:302)
    位于java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1110)
    位于java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603)
    运行(Thread.java:722)
    
    是因为ImageIO不是线程安全的吗?我能做些什么来解决这个问题?
    非常感谢您的帮助和问候

    使用同步方法防止并发修改可能会有所帮助。读这个问题

    stackoverflow.com/questions/9884148/在affable bean购物车中使用同步方法

    这两行:

    ImageIO.scanForPlugins();
    Iterator<ImageReader> iter = ImageIO.getImageReadersByFormatName("DICOM");
    
    ImageIO.scanForPlugins();
    迭代器iter=ImageIO.getImageReadersByFormatName(“DICOM”);
    

    只需在应用程序加载或servlet初始化时执行一次。特别是,第一行
    ImageIO.scanForPlugins()
    确实改变了ImageIO类内部使用的共享数据。这可能是导致并发修改异常的原因。考虑将这两条线移到servlet过滤器,或servlet的init(Servlet CONFIG)方法。

    非常感谢!这就是解决办法!
    ImageIO.scanForPlugins();
    Iterator<ImageReader> iter = ImageIO.getImageReadersByFormatName("DICOM");