CSV API for Java
Apache Commons CSV
Check out Apache Common CSV.
This library reads and writes several variations of CSV, including the standard one RFC 4180. Also reads/writes Tab-delimited files.
- Excel
- InformixUnload
- InformixUnloadCsv
- MySQL
- Oracle
- PostgreSQLCsv
- PostgreSQLText
- RFC4180
- TDF
Import Response Data received from an API into CSV file
Solution:
- Step 1: Convert response to json in String format
- Step 2: Extract array
data
by Jackson, not Rest-Assured
String res = given()
.get("https://gorest.co.in/public-api/users")
.asString();
try {
JsonNode jsonTree = new ObjectMapper().readTree(res).get("data");
...
}
Design rule for responding to REST GET API with CSV output
My suggestions:
Keep the ResponseCSV immutable, no setters, provide constructor !
Change the CSVExportSvc.exportCSV signature to be easier, don't return boolean:
Try to set content type to csv/text.
The interface may be like this:
public interface CSVExportSvc {
public ResponseCSV exportCSV(String sectionTypeName);
}
Java: download CSV file with REST service
Explainations:
You got inputStream first:
contentLengthOfStream =inputStreamResource.contentLength();
Then Spring's returnValueHandlers got inputStream again:
new ResponseEntity( inputStreamResource, httpHeaders, HttpStatus.OK )
.
But the inputStream wrapped by inputStreamResource only can be used once:
/**
* 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;
}
Solution: You can get bytes from inputStream and return the ResponseEntity with bytes.
@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 );
}
Suggest: using Apache Commons IO to convert InputStream to bytes.Need to add a lib dependency,which can make your code brief
byte[] byteArray = IOUtils.toByteArray(inputStream);
Download CSV file via Rest
To force "save as", you need to set the content disposition HTTP header in the response. It should look like this:
Content-Disposition: attachment; filename="whatever.csv"
It looks like you're using JAX-RS. This question shows how to set the header. You can either write the CSV to the HTTP response stream and set the header there or return a Response
object like so:
return Response.ok(myCsvText).header("Content-Disposition", "attachment; filename=" + fileName).build();
You do not need to write to a File
object in the middle of this process so can avoid writing to disk.
Related Topics
What's the Difference Between @Component, @Repository & @Service Annotations in Spring
How to Run Unix Shell Script from Java Code
Do We Have Any Generic Function to Check If Page Has Completely Loaded in Selenium
Should I Always Use a Parallel Stream When Possible
"Invalid Signature File" When Attempting to Run a .Jar
How to Format a Number in Java
Including Jars in Classpath on Commandline (Javac or Apt)
Spring @Transactional Not Auto Rolling Back During Unchecked Exception
How to "Decompile" Java Class Files
Java Swing Revalidate() VS Repaint()
How to Implement Rest Token-Based Authentication With Jax-Rs and Jersey
Getting the Ip Address of the Current Machine Using Java
How to Convert Byte Array to String and Vice Versa
Different Ways of Loading a File as an Inputstream
Creating an Instance Using the Class Name and Calling Constructor