简体   繁体   中英

Error java.lang.IllegalStateException: Unable to obtain OutputStream because Writer is already in use

I'm trying to download an Excel in a liferay portlet but when I'm going to get the outPutPortletStream I obtain the next exception:

java.lang.IllegalStateException: Unable to obtain OutputStream because Writer is already in use

This is the method I'm using to download the Excel:

public static void descargaFichero(ResourceRequest resourceRequest, ResourceResponse resourceResponse) throws Exception {

        HttpServletRequest request = PortalUtil.getOriginalServletRequest(PortalUtil.getHttpServletRequest(resourceRequest));
        OutputStreamWriter osWriter = null;
        BufferedWriter bWriter = null;
        OutputStream outputStream = null;
        InputStream is = null;
        InputStreamReader isr = null;
        File tempFile = null;
        
        try {
            String idDescarga = request.getParameter("id-descarga");
            String rutaFicheroDescarga = Encriptador.decrypt(ConstantesFlujos.CLAVE_ENCRIPTADO_JSON, idDescarga);
            
            String extension = FileUtil.getExtension(rutaFicheroDescarga);
            String nombreArchivo = String.format("%s%s.%s", 
                    ConstantesFlujos.PREFIJO_NOMBRE_FICHERO_RENOVACION,
                    fechaDesglosada(),
                    extension);
            
            if(GestorLog.isInfoEnabled(clase)){
                GestorLog.info(clase, String.format("Descargando fichero temporal: '%s' a '%s'", rutaFicheroDescarga, nombreArchivo));
            }
            
            if (extension.equalsIgnoreCase("xls")) {
                resourceResponse.setContentType("application/vnd.ms-excel");
                
            } else {
                resourceResponse.setContentType("application/octet-stream");
            }
            
            ((PortletResponse) resourceResponse).addProperty("Content-disposition", String.format("atachment; filename=%s", nombreArchivo));
            
            tempFile = new File(rutaFicheroDescarga);
            
            outputStream = resourceResponse.getPortletOutputStream();
            osWriter = new OutputStreamWriter(outputStream, "ISO-8859-1");
            
            char[] buf = new char[8192];
            is = new FileInputStream(tempFile);
            isr = new InputStreamReader(is, "ISO-8859-1");
            int c = 0;
            
            while ((c = isr.read(buf, 0, buf.length)) > 0) {
                osWriter.write(buf, 0, c);
                osWriter.flush();
            }
            
        } catch(Exception e){
            GestorLog.error(clase, "Error en el metodo descargaFichero: " + e.getMessage());
            throw e;
            
        } finally {
            if (isr != null) {
                isr.close();
            }
            if (is != null) {
                is.close();
            }
            if (bWriter != null) {
                bWriter.close();
            }
            if (outputStream != null) {
                outputStream.close();
            }
            if (tempFile != null) {
                tempFile.delete();
            }
        }
    }

And I get the error in the line:

outputStream = resourceResponse.getPortletOutputStream();

This might be due to resourceResponse.addProperty being called before accessing the stream. Those operations can be nasty, as two parties will now try to write data to the output.

An easy way to omit all problems is to just delegate it all to the portal: PortletResponseUtil.sendFile exists in a couple of different variations, eg

PortletResponseUtil.sendFile(
      resourceRequest,
      resourceResponse,
      fileName,
      inputStream,
      contentLength,
      contentType,
      contentDispositionType); // e.g. HttpHeaders.CONTENT_DISPOSITION_ATTACHMENT

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM