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

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

Related

The system cannot find the path specified in my Java JAR file

I am running a jar file .spring code for backend and react js for frontend. The code below works perfect for frontend and backend apart but what do you do if it is a jar . Only recieving "cant find file"
#RequestMapping(value = "/getPdf/{userType}/{userRoll}/{trainingFileName}", method = RequestMethod.GET)
public ResponseEntity<InputStreamResource> getPdf(#PathVariable("userType") String userType,
#PathVariable("userRoll") String userRoll,
#PathVariable("trainingFileName") String trainingFileName) throws IOException {
String fileName =trainingFileName + ".pdf";
String filePath = "TrainingDocuments/" +userType+"/"+userRoll+"/"+ trainingFileName+ "/"+ fileName;
File file = new File(filePath);
HttpHeaders headers = new HttpHeaders();
headers.add("content-disposition", "inline;filename=" +fileName);
InputStreamResource resource = new InputStreamResource(new FileInputStream(file));
return ResponseEntity.ok()
.headers(headers)
.contentLength(file.length())
.contentType(MediaType.parseMediaType("application/pdf"))
.body(resource);
}

Angularjs : call to REST API to get a docx document from server

I am trying to call a service from angularjs that produces a docx document.
Angularjs is supposed to display the save prompt of the web browser, and then save the document.
When I open the saved document, what I get in the docx file is :
Undefined
Api rest :
#RequestMapping(value = "/create-avenant",
method = RequestMethod.POST,
produces = MediaType.APPLICATION_JSON_VALUE)
#Timed
public void getAvenant(#RequestBody AvenantDTO avenant, HttpServletResponse response) {
contratService.createAvenant(response, avenant);
}
service produces a XWPFDocument and send to browser :
private void sendDocToBrowser(HttpServletResponse response, XWPFDocument doc) throws IOException {
try
{
byte[] buffer = new byte[8192];
ByteArrayOutputStream baos = new ByteArrayOutputStream();
doc.write(baos);
response.setHeader("Content-Disposition", "attachment;filename=myDoc.docx");
response.setContentType("application/docx");
ServletOutputStream outputStream = response.getOutputStream();
baos.writeTo(outputStream);
outputStream.flush();
}
finally
{
outputStream.close();
}
}
Angularjs :
Avenant.create(avenant,function(result){
var blob = new Blob([result.body], { type: 'application/docx' });
var link = document.createElement('a');
link.href = window.URL.createObjectURL(blob);
link.download = 'file.docx';
link.click();
})

Hack to upload a file from Java backend to a remote server over HTTP using Rest API.

My file resides on some location on my machine say C://users//abc.txt and i want to write a java program to transfer this file using REST API over HTTP. I used MockHttpServelet Request to create the request, but somehow i am unable to transfer the file
Use HttpClient:
String url = "http://localhost:8080/upload"; // Replace with your target 'REST API' url
String filePath = "C://users//abc.txt";
CloseableHttpClient httpClient = HttpClients.createDefault();
try {
HttpPost httpPost = new HttpPost(url);
FileEntity entity = new FileEntity(new File(filePath), ContentType.TEXT_PLAIN);
httpPost.setEntity(entity);
HttpResponse httpResponse = httpClient.execute(httpPost);
System.out.println(httpResponse.getStatusLine().getStatusCode()); // Check HTTP code
} finally {
httpClient.close();
}
With Authentication:
String url = "http://localhost:8080/upload"; // Replace with your target 'REST API' url
String filePath = "C://users//abc.txt";
String username = "username"; // Replace with your username
String password = "password"; // Replace with your password
RequestConfig requestConfig =
RequestConfig.custom().
setAuthenticationEnable(true).
build();
CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
credentialsProvider.setCredentials(
AuthScope.ANY,
new UsernamePasswordCredential(username, password));
CloseableHttpClient httpClient =
HttpClients.custom().
setDefaultRequestConfig(requestConfig).
setDefaultCredentialsProvider(credentialsProvider).
build();
try {
HttpPost httpPost = new HttpPost(url);
FileEntity entity = new FileEntity(new File(filePath), ContentType.TEXT_PLAIN);
httpPost.setEntity(entity);
HttpResponse httpResponse = httpClient.execute(httpPost);
System.out.println(httpResponse.getStatusLine().getStatusCode()); // Check HTTP code
} finally {
httpClient.close();
}
String location="C:\\Usersabc.img";
Path path = Paths.get(location);
String name=location.substring(location.lastIndexOf("\\")+1);
MultipartEntity multipart= new MultipartEntity(HttpMultipartMode.BROWSER_COMPATIBLE);
try {
multipart.addPart("image", new ByteArrayBody(Files.readAllBytes(path), ContentType.APPLICATION_OCTET_STREAM.getMimeType(),name));
}
catch (IOException ex) {
// TODO Auto-generated catch block
ex.printStackTrace();
}

HTTP 204 error when sending File in response REST

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

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.

Resources