Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/374.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java:使用REST服务下载CSV文件_Java_Spring_Rest_Csv_Spring Mvc - Fatal编程技术网

Java:使用REST服务下载CSV文件

Java:使用REST服务下载CSV文件,java,spring,rest,csv,spring-mvc,Java,Spring,Rest,Csv,Spring Mvc,我正在尝试从REST端点下载csv文件。这就是我正在尝试的 @ApiOperation(value = "export", notes = "Export Cache details for a given criteria") @ApiImplicitParams({ }) @ApiResponses(value = { @ApiResponse(code = 400, message = "Bad Request"), @ApiRespons

我正在尝试从REST端点下载csv文件。这就是我正在尝试的

@ApiOperation(value = "export",
        notes = "Export Cache details for a given criteria")
@ApiImplicitParams({

})
@ApiResponses(value = {
        @ApiResponse(code = 400, message = "Bad Request"),
        @ApiResponse(code = 404, message = "Not Found"),
        @ApiResponse(code = 500, message = "Internal Server Error") })
@RequestMapping(method = RequestMethod.GET, value = "/export")
public ResponseEntity export( HttpServletRequest request )
{
    CacheDataManager cacheResultHandler = new CacheDataManager();
    InputStreamResource inputStreamResource = null;
    HttpHeaders httpHeaders = new HttpHeaders();
    long contentLengthOfStream;

    try
    {
        inputStreamResource = cacheResultHandler.exportCacheResults( request );
        httpHeaders.set( HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=" + "test.csv" );

        contentLengthOfStream = inputStreamResource.contentLength();
        httpHeaders.setContentLength( contentLengthOfStream );
    }
    catch ( IOException e )
    {
        e.printStackTrace();
    }

    return new ResponseEntity( inputStreamResource, httpHeaders, HttpStatus.OK );

}
我的导出功能

@Override
public InputStreamResource export( HttpServletRequest request )
{
    StringBuilder sb = new StringBuilder();
    StringBuilder fileName = new StringBuilder( VALIDATION_REPORT );

    sb.append( "Column A" );
    sb.append( "," );
    sb.append( "Column B" );
    sb.append( "\n" );

    try
    {

            sb.append( "TEST A");
            sb.append( ',' );
            sb.append( "TEST B" );
            sb.append( '\n' );



        fileName.append( "_" ).append( sdf.format( new Date() ) ).append( ".csv" );
        return CsvFileWriter.csvFileWrite( fileName.toString(), sb );

    }
    catch ( Exception e )
    {
        e.printStackTrace();

    }

    return null;
}
CsvFileWriter.java

package it.app.ext.dashboard.util;

import org.springframework.core.io.InputStreamResource;

import java.io.*;

public class CsvFileWriter
{

public static InputStreamResource csvFileWrite( String fileName, StringBuilder content ) throws FileNotFoundException
{
    File file = null;
    PrintWriter pw = null;
    try
    {
        file = new File( fileName );
        pw = new PrintWriter( file );
        pw.write( content.toString() );
    }
    catch ( FileNotFoundException e )
    {
        e.printStackTrace();
    }
    finally
    {
        pw.flush();
        pw.close();
    }

    InputStream inputStream = new FileInputStream( file );

    return new InputStreamResource( inputStream );
}
}

正在生成包含tomcat/bin文件夹中内容的文件,但发生异常

java.lang.IllegalStateException: InputStream has already been read - do not use InputStreamResource if a stream needs to be read multiple times.
调用此端点后,我想下载一个.csv文件

如有任何建议,我们将不胜感激


谢谢您不要两次使用同一个文件,请使用单独的代码返回InputStream:


返回新的InputStreamResource(新文件InputStream(新文件名))

不要两次使用同一文件,请使用单独的代码返回InputStream:


返回新的InputStreamResource(新文件InputStream(新文件名))

解释:

您首先获得inputStream:

contentLengthOfStream=inputStreamResource.contentLength()

然后Spring的ReturnValueHandler再次获得inputStream:

新响应属性(inputStreamResource、httpHeaders、HttpStatus.OK)

但是由inputStreamResource包装的inputStream只能使用一次:

/**
 * This implementation throws IllegalStateException if attempting to
 * read the underlying stream multiple times.
 */
public InputStream getInputStream() throws IOException, IllegalStateException {
    if (this.read) {
        throw new IllegalStateException("InputStream has already been read - " +
                "do not use InputStreamResource if a stream needs to be read multiple times");
    }
    this.read = true;
    return this.inputStream;
}
解决方案:您可以从inputStream获取字节,并返回带有字节的响应

@ApiOperation(value = "export",
        notes = "Export Cache details for a given criteria")
@ApiImplicitParams({

})
@ApiResponses(value = {
        @ApiResponse(code = 400, message = "Bad Request"),
        @ApiResponse(code = 404, message = "Not Found"),
        @ApiResponse(code = 500, message = "Internal Server Error") })
@RequestMapping(method = RequestMethod.GET, value = "/export")
public ResponseEntity export( HttpServletRequest request )
{
    CacheDataManager cacheResultHandler = new CacheDataManager();
    InputStreamResource inputStreamResource = null;
    InputStream inputStream = null;
    byte[] byteArray = new byte[0];
    HttpHeaders httpHeaders = new HttpHeaders();

    try
    {
        inputStreamResource = cacheResultHandler.exportCacheResults( request );
        httpHeaders.set( HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=" + "test.csv" );

        //convert inputStream to bytes
        inputStream = inputStreamResource.getInputStream();
        ByteArrayOutputStream buffer = new ByteArrayOutputStream();
        int nRead;
        byte[] data = new byte[1024];
        while ((nRead = inputStream.read(data, 0, data.length)) != -1) {
            buffer.write(data, 0, nRead);
        }

        buffer.flush();
        byteArray = buffer.toByteArray();

        httpHeaders.setContentLength(byteArray.length);
    }
    catch ( IOException e )
    {
        e.printStackTrace();
    }

    return new ResponseEntity( byteArray, httpHeaders, HttpStatus.OK );

}
建议:用于将InputStream转换为字节。需要添加库依赖项,这可以使代码简短

byte[] byteArray = IOUtils.toByteArray(inputStream);

解释:

您首先获得inputStream:

contentLengthOfStream=inputStreamResource.contentLength()

然后Spring的ReturnValueHandler再次获得inputStream:

新响应属性(inputStreamResource、httpHeaders、HttpStatus.OK)

但是由inputStreamResource包装的inputStream只能使用一次:

/**
 * This implementation throws IllegalStateException if attempting to
 * read the underlying stream multiple times.
 */
public InputStream getInputStream() throws IOException, IllegalStateException {
    if (this.read) {
        throw new IllegalStateException("InputStream has already been read - " +
                "do not use InputStreamResource if a stream needs to be read multiple times");
    }
    this.read = true;
    return this.inputStream;
}
解决方案:您可以从inputStream获取字节,并返回带有字节的响应

@ApiOperation(value = "export",
        notes = "Export Cache details for a given criteria")
@ApiImplicitParams({

})
@ApiResponses(value = {
        @ApiResponse(code = 400, message = "Bad Request"),
        @ApiResponse(code = 404, message = "Not Found"),
        @ApiResponse(code = 500, message = "Internal Server Error") })
@RequestMapping(method = RequestMethod.GET, value = "/export")
public ResponseEntity export( HttpServletRequest request )
{
    CacheDataManager cacheResultHandler = new CacheDataManager();
    InputStreamResource inputStreamResource = null;
    InputStream inputStream = null;
    byte[] byteArray = new byte[0];
    HttpHeaders httpHeaders = new HttpHeaders();

    try
    {
        inputStreamResource = cacheResultHandler.exportCacheResults( request );
        httpHeaders.set( HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=" + "test.csv" );

        //convert inputStream to bytes
        inputStream = inputStreamResource.getInputStream();
        ByteArrayOutputStream buffer = new ByteArrayOutputStream();
        int nRead;
        byte[] data = new byte[1024];
        while ((nRead = inputStream.read(data, 0, data.length)) != -1) {
            buffer.write(data, 0, nRead);
        }

        buffer.flush();
        byteArray = buffer.toByteArray();

        httpHeaders.setContentLength(byteArray.length);
    }
    catch ( IOException e )
    {
        e.printStackTrace();
    }

    return new ResponseEntity( byteArray, httpHeaders, HttpStatus.OK );

}
建议:用于将InputStream转换为字节。需要添加库依赖项,这可以使代码简短

byte[] byteArray = IOUtils.toByteArray(inputStream);

我更改了这些InputStream InputStream=新文件InputStream(文件);返回新的InputStreamResource(inputStream);两行到你的分段。但错误与以前相同。@Rose18应创建新文件对象实例:
InputStream InputStream=new FileInputStream(新文件(文件名))
而不是重复使用旧文件OJECT对不起,我不明白你说的。我需要更改哪个文件?@Rose18你可以看到我的答案,这将帮助你找到答案<代码>pw.close()行将关闭您的
文件
对象。我的意思是“文件=新文件(文件名);”无法设置为新对象:`InputStream InputStream=新文件InputStream(文件);`因此,请再次创建
file
对象的实例:
file=newfile(fileName);InputStream InputStream=新文件InputStream(文件);返回新的InputStreamResource(inputStream)我更改了这些InputStream InputStream=新文件InputStream(文件);返回新的InputStreamResource(inputStream);两行到你的分段。但错误与以前相同。@Rose18应创建新文件对象实例:
InputStream InputStream=new FileInputStream(新文件(文件名))
而不是重复使用旧文件OJECT对不起,我不明白你说的。我需要更改哪个文件?@Rose18你可以看到我的答案,这将帮助你找到答案<代码>pw.close()行将关闭您的
文件
对象。我的意思是“文件=新文件(文件名);”无法设置为新对象:`InputStream InputStream=新文件InputStream(文件);`因此,请再次创建
file
对象的实例:
file=newfile(fileName);InputStream InputStream=新文件InputStream(文件);返回新的InputStreamResource(inputStream)此工作方式ans响应正文包含响应正文下载exportCacheResults?pr=HTL&index=0&size=100。单击此url后,它将下载应用程序八位字节流exportCacheResults pr=HTL&index=0&size=100 blob http---localhost-8080-d541c19c-6da3-478e-b8ee-0448aa5bf598的文件名。这是一个文件类型为的文件。如何下载.csv文件我看不到上面与您的url“exportCacheResults?pr=HTL&index=0&size=100”相关的任何代码。添加
httpHeaders.set(“内容处置”、“附件;文件名=“+”test.csv”)
时,您可以直接下载.csv文件!这项工作ans响应正文包含响应正文下载exportCacheResults?pr=HTL&index=0&size=100。单击此url后,它将下载应用程序八位字节流exportCacheResults pr=HTL&index=0&size=100 blob http---localhost-8080-d541c19c-6da3-478e-b8ee-0448aa5bf598的文件名。这是一个文件类型为的文件。如何下载.csv文件我看不到上面与您的url“exportCacheResults?pr=HTL&index=0&size=100”相关的任何代码。添加
httpHeaders.set(“内容处置”、“附件;文件名=“+”test.csv”)
时,您可以直接下载.csv文件!