HTTP 204 error when sending File in response REST - file

This is my write to excel method which returns javax.ws.rs.core.Response
public Response writeToExcel(UserDeatilsVOWrapper listBook) {
XSSFWorkbook workbook = new XSSFWorkbook();
XSSFSheet spreadsheet = workbook.createSheet("Resource Information");
int rowCount = 0;
createHeaderRow(spreadsheet);
for (UserDetailsVO detailsVO : listBook.getUserDetailsList()) {
Row row = spreadsheet.createRow(++rowCount);
writeBook(detailsVO, row);
}
Response response = null;
try (FileOutputStream outputStream = new FileOutputStream(new File("ResourceInformation.xlsx"))) {
workbook.write(outputStream);
// header required to enable download pop-up and set file name
Response.ok().header("Content-Disposition", "attachment; filename=" + "ResourceInformation.xlsx").build();
}
catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return response;
}
This is my web service:
#POST
#Path(WebServiceConstants.DOWNLOAD_EXCEL)
#Consumes(MediaType.APPLICATION_JSON)
public Response getFile(UserDeatilsVOWrapper wrapper) {
Response respose=new ExportToExcel().writeToExcel(wrapper);
return respose;}
I get a HTTP204 error. I'm using postman. I know, I'm doing a big mistake in write to excel method and when trying to send file along with response.
Also is there any possible way to write a file object on REST response without saving file on server? I'm doing terrible in here. any help is appreciated.

I do not see where you set your file to the response. Normally you would do something like this
File file = new File("ResourceInformation.xlsx"))
// Do your excel-writing here...
ResponseBuilder response = Response.ok((Object) file);
response.header("Content-Disposition", "attachment; filename=" + "ResourceInformation.xlsx");
return response.build();

Related

Send document to client server from .net server

I have an API that offers a file translation service. I have been able to generate a new the new translated file but I have not been able to get it to the client correctly, because the document downloaded it is not readable.
This is my controller code:
[HttpPost]
[Route("TranslateDocument/{inputLanguage}/{outputLanguage}")]
[ProducesResponseType(typeof(FileContentResult), StatusCodes.Status200OK)]
public async Task<ActionResult<FileInfo>> TranslateDocument(string inputLanguage, string outputLanguage, [FromForm] IFormFile file)
{
try
{
FileContentResult result = await _deeplService.TranslateFile(inputLanguage, outputLanguage, file);
return Ok(result);
}
catch (Exception ex)
{
return ManageExceptions(ex);
}
}
In my service I have the following function:
public async Task<FileContentResult> TranslateFile(string inputLang, string outputLang, IFormFile file){
//Code to translate the file into outputLang
...
//Get bytes from Document generated
byte[] bytes = System.IO.File.ReadAllBytes("localpath from doc");
//Send the File to Download.
return new FileContentResult(bytes, "application/vnd.openxmlformats-officedocument.wordprocessingml.document");
}
And this is the response I am getting on the client site:
{
"fileContents": "UEsDBBQAAA...AAyCUAAAAA",
"contentType": "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
"fileDownloadName": "",
"lastModified": null,
"entityTag": null,
"enableRangeProcessing": false
}
And when I do the const url = window.URL.createObjectURL(new Blob([response.fileContents], {type: "application/vnd.openxmlformats-officedocument.wordprocessingml.document"}));, the file downloaded is not readable in word

Cannot open downloaded zip file from rest endpoint using file-saver

Here is the backend code for the download endpoint:
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
ZipOutputStream zipOut = new ZipOutputStream(byteArrayOutputStream);
for (Long id : ids) {
// Get the "generated" file using the id
zipOut.putNextEntry(new ZipEntry(generated.getName() + ".doc"));
InputStream inputStream = new ByteArrayInputStream(generated.getFile().getBytes(1, (int)generated.getFile().length()));
IOUtils.copy(inputStream, zipOut);
zipOut.closeEntry();
}
zipOut.close();
response.setContentType("application/zip");
response.setHeader("Content-Disposition", "attachment; filename=File.zip");
byte[] zipBytes = byteArrayOutputStream.toByteArray();
OutputStream outputStream = response.getOutputStream();
outputStream.write(zipBytes);
outputStream.close();
response.flushBuffer();
And for the frontend, I am using axios and file-saver
import { saveAs } from "file-saver";
request.then((response: any) => {
const blob = new Blob([response.data], { type: "application/zip" });
saveAs(blob, "Report.zip");
});
I can download the zip file, but when I tried to open, I got the follwing error:
"An attempt was made to move the file pointer before the beginning of the file"
NOTE: There is no error on the backend. The zip file is downloaded successfully. But upon opening the zip file, the error pops up.
Please, try to rewrite it like that:
response.setContentType("application/zip");
response.setHeader("Content-Disposition", "attachment; filename=File.zip");
ZipOutputStream zipOut = new ZipOutputStream(response.getOutputStream());
for (Long id : ids) {
// Get the "generated" file using the id
zipOut.putNextEntry(new ZipEntry(generated.getName() + ".doc"));
InputStream inputStream = new ByteArrayInputStream(generated.getFile().getBytes(1, (int)generated.getFile().length()));
IOUtils.copy(inputStream, zipOut);
zipOut.closeEntry();
}
zipOut.close();
response.flushBuffer();

How to upload file along with json meta data using rest api

I have requirement to upload xlsx file on server along with some json data(both has to be done in one request). I was able to upload just file using multipart/form-data, but when I tried add JSON data to the same request, request is failing with org.apache.commons.fileupload.FileUploadBase$InvalidContentTypeException: the request doesn't contain a multipart/form-data or multipart/mixed stream
exception. Below is my code.
Client side code
var method = 'POST';
$.ajax({
type: method,
url : "rest/file/upload",
transformRequest: function () {
var formData = new FormData();
formData.append("model", JSON.stringify(jsonData));
formData.append("file",document.getElementById("fileForm"));
return formData;
},
enctype : 'multipart/form-data',
processData : false,
contentType : false,
success: function (data) {},
error: function (data) {}
});
model is the JSON data & file is xlsx file which is to be uploaded.
Server Side Code
#POST
#Path("/upload")
#Consumes(MediaType.MULTIPART_FORM_DATA)
#Produces(MediaType.TEXT_PLAIN)
public Response uploadResumableISOFile(#Context HttpServletRequest request, #Context UriInfo uri,
#Context HttpHeaders headers, #Context HttpServletResponse response) throws IOException {
ServletFileUpload uploader = null;
try {
DiskFileItemFactory fileFactory = new DiskFileItemFactory();
uploader = new ServletFileUpload(fileFactory);
List<FileItem> fileItemsList = uploader.parseRequest(request);
Iterator<FileItem> fileItemsIterator = fileItemsList.iterator();
while (fileItemsIterator.hasNext()) {
FileItem fileItem = fileItemsIterator.next();
File file = File.createTempFile("TEMP_", ".xlsx");
fileItem.write(file);
System.out.print("File " + fileItem.getName() + " uploaded successfully.");
}
System.out.println("File uploaded to successfully...");
return Response.status(Response.Status.OK).build();
} catch (Exception e) {
System.out.println(e);
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity("Failed to upload file.").build();
}
}
Please let me know if something is missing.

How to open Rest API Post response in New window using Angular Js

I am making a rest API call using Angular. My Rest API look like as below:
#RequestMapping(value = "/getPDF/{projectId}", method = RequestMethod.POST)
public ResponseEntity<byte[]> generateReport(#PathVariable("projectId") long projectId, #RequestBody Object vo, final HttpServletRequest request) {
vo.setProjectId(projectId);
byte[] pdf = blueprintService.generateBluePrint(vo);
LOG.debug(new StringBuilder("Generating Blueprint for VO: ").append(vo).toString());
String fileName = null;
try {
ProjectDetailsVO pdvo = projectSetupService.getProjectDetails(vo.getProjectId());
fileName = new StringBuilder(pdvo.getClientName()).append("_")
.append(pdvo.getProjectName()).append("_")
.append(System.currentTimeMillis()).append(".pdf")
.toString();
} catch (Exception e) {
}
if (fileName == null || fileName.trim().isEmpty())
fileName = new StringBuilder("Project_")
.append(vo.getProjectId()).append("_")
.append(System.currentTimeMillis())
.append(".pdf").toString();
HttpHeaders headers = new HttpHeaders();
headers.add("Content-Type", "application/pdf");
String userAgent = request.getHeader("User-Agent");
if (userAgent != null && !(userAgent.contains("Firefox") && userAgent.contains("Mac"))) {
LOG.debug("Inline BP Content");
headers.add("Content-Disposition", new StringBuilder("inline; filename=\"").append(fileName).append("\"").toString());
} else {
LOG.debug("Attached BP Content");
headers.add("Content-Disposition", new StringBuilder("attachment; filename=\"").append(fileName).append("\"").toString());
}
if (pdf != null)
headers.setContentLength(pdf.length);
return new ResponseEntity<byte[]>(pdf, headers, HttpStatus.OK);
}
}
So server is setting file name for the PDF which I want to be the name of the generated PDF.
I tried below angular code:
success: function (data, status, headers, config) {
$modalInstance.close();
var file = new Blob([data], {type: 'application/pdf'});
var fileURL = URL.createObjectURL(file);
window.open(fileURL);
}
It works fine but it open the pdf of it's own name. Which I think, since Angular is converting the response into PDF. Hence Headers are getting excluded.
Is there any way to make a post request so it will open a PDF in new browser tab some code like as below:
$http.post{
url: myRestURL,
data: postbodyData,
taget: _blank
}
which will open my rest URL in new tab and show the PDF in browser.
Thank you.

How can I send a file from the server to client using REST (JAX-RS Jersey)?

I want to send a file from my server side (EJB) using REST Jersey (JAX-RS).
I am trying with the following code,
Public Response getFiles() {
File file = new File(fileName);
FileOutputStream dest = new FileOutputStream(file);
ZipOutputStream out = new ZipOutputStream(new BufferedOutputStream(dest));
out.putNextEntry(new ZipEntry(fileName));
final ResponseBuilder response = Response.ok(out);
response.header("Content-Type", "*/*");
response.header("Content-Disposition", "attachment; filename=" + file.getName() + ".zip");
return response.build();
}
But I am getting the exception message
type class java.util.zip.ZipOutputStream, and MIME media type */* was not found
SEVERE: The registered message body writers compatible with the MIME media type are:
Also tried with "Content-Type" , "application/octet-stream", "application/x-www-form-urlencoded" and multipart/form-data
But none of them is working.
Use application/zip.
#GET
#Produces("application/zip")
public Response getZip() {
final File f = new File("/tmp/foo.zip");
ResponseBuilder response = Response.ok((Object) f);
response.header("Content-Disposition", "attachment; filename=" + f.getName());
return response.build();
}
application/octet-stream + gzip
#GET
#Path("/getFiles")
#Produces(MediaType.APPLICATION_OCTET_STREAM)
public Response getFiles() {
StreamingOutput stream = new StreamingOutput() {
#Override
public void write(OutputStream output) throws IOException, WebApplicationException {
String filePath = "/yourFile.pdf";
java.nio.file.Path path = Paths.get(filePath);
byte[] data = Files.readAllBytes(path);
output.write(data);
output.flush();
}
};
return Response.ok(stream).build();
}
and a jersey filter added to web.xml
<init-param>
<param-name>com.sun.jersey.spi.container.ContainerResponseFilters</param-name>
<param-value>com.sun.jersey.api.container.filter.GZIPContentEncodingFilter</param-value>
</init-param>
when making the request:
send a header of "Accept" with value of "application/octet-stream"
and a header of "Accept-Encoding" with value of "gzip"

Resources