I use angularjs 1.3.14
I have a java REST services produce a xml file with this header: "Content-Disposition", "attachment; filename=yourFileName";
I need take the file with the name of my file on AngularJS.
I have this code:
$http.get('/someUrl').success(function(data, status, headers){
var myHeaders = headers();
...
});
but in myHeaders have only {content-type="application/xml"}. I need find "Content-Disposition", "attachment; filename=yourFileName"
Java Services:
#GET
#Path(EXPORT_URL)
#Produces(MediaType.APPLICATION_XML)
public Response export(#Context HttpServletRequest request) {
String userName = request.getRemoteUser();
if (userName != null) {
...
ResponseBuilder response = Response.ok(myObject);
response.header("Content-Disposition", "attachment; filename=myFile.xml");
return response.build();
} else {
return Response.status(Status.FORBIDDEN).build();
}
}
2 years after, I find a solution:
#RequestMapping(value = "/export", method = RequestMethod.GET, produces = MediaType.APPLICATION_XML)
public ResponseEntity<String> export(...
HttpHeaders headers = new HttpHeaders();
headers.setAccessControlExposeHeaders(Collections.singletonList("Content-Disposition"));
headers.set("Content-Disposition", "attachment; filename=" + filename);
return new ResponseEntity<>(exportedContent, headers, HttpStatus.OK);
This is a server side CORS issue. You need to enable this:
"Access-Control-Expose-Headers", "Content-Disposition"
Related
#RequestMapping( value= "/get/{imageName}",produces = MediaType.APPLICATION_OCTET_STREAM_VALUE ,method = RequestMethod.GET)
public ResponseEntity<byte[]> getImage1(#PathVariable("imageName") String imageName) throws IOException {
final Optional<ImageModel> retrievedImage = imageModelRepository.findByName(imageName);
ImageModel img = new ImageModel(retrievedImage.get().getName(), retrievedImage.get().getType(),retrievedImage.get().getPicByte());
byte[] imageArray= retrievedImage.get().getPicByte();
return ResponseEntity.ok().body(imageArray);
}
Content-Type of application/octet-stream forces it to always download.
You can try something like follows:
...
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.parseMediaType("image/jpeg"));
...
headers.add("Content-Disposition", "inline; filename=" + fileName);
...
ResponseEntity<byte[]> returnValue = new ResponseEntity<>(imageArray, headers, HttpStatus.OK);
return returnValue;
I am writing a rest service which will download the pdf when user access this service on users machine. below is the code of my controller class.
When I tried to access below url in browser, it is downloading .JSON file and not PDF file.
URL:- http://localhost:8080/test-service/downloadPDF?userId=abcd&requestingLocation=6&orderId=06006030
I have tried to use same code which was mentioned in below sites. It seems the straight forward code but not sure why it is not working.
http://www.java2novice.com/restful-web-services/jax-rs-download-file/
https://www.javatpoint.com/jax-rs-file-download-example
Below is method in controller.
#GET
#RequestMapping(value = "/downloadPDF")
#Produces("application/pdf")
public #ResponseBody Response downloadDocument(#RequestParam("userId") String userId,#RequestParam("requestingLocation") String requestinglocation,#RequestParam("orderId") String orderId) {
String path = "C:\\opt\\autobol\\logs\\autobol\\test2.pdf";
File file = new File(path);
ResponseBuilder response = Response.ok((Object) file);
response.header("Content-Disposition","attachment; filename=\"javatpoint_pdf.pdf\"");
return response.build();
}
It should download pdf file
below is the content of downloaded file (file name downloadPDF.json):
{
"entity":"C:\\opt\\autobol\\logs\\autobol\\test2.pdf",
"status":200,
"metadata":{
"Content-Disposition":[
"attachment; filename=\"javatpoint_pdf.pdf\""
]
},
"annotations":null,
"entityClass":"java.io.File",
"genericType":null,
"length":-1,
"language":null,
"location":null,
"lastModified":null,
"date":null,
"closed":false,
"cookies":{
},
"statusInfo":"OK",
"stringHeaders":{
"Content-Disposition":[
"attachment; filename=\"javatpoint_pdf.pdf\""
]
},
"links":[
],
"entityTag":null,
"allowedMethods":[
],
"mediaType":null,
"headers":{
"Content-Disposition":[
"attachment; filename=\"javatpoint_pdf.pdf\""
]
}
}
in downloadPDF.json file
Try this
HttpResponse response = HttpContext.Current.Response;
response.ClearContent();
response.Clear();
Response.ContentType = "application/pdf";
Response.AppendHeader("Content-Disposition", "attachment; filename=" + Path.GetFileName(strPath));
response.TransmitFile(strPath); //File
response.Flush();
response.End();
Response.ContentType = ContentType;
Response.AppendHeader("Content-Disposition", "attachment; filename=" + Path.GetFileName(strPath));
Response.WriteFile(strPath);
Response.End();
Here is a spring boot example.
you can refer this example https://docs.spring.io/spring-boot/docs/current/reference/html/getting-started-first-application.html and attach the below class in the project
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.*;
import org.springframework.http.*;
import java.io.File;
import java.nio.file.Files;
#Controller
public class DemoController {
#RequestMapping(value="/getpdf", method=RequestMethod.GET)
public ResponseEntity<byte[]> getPDF() {
File file = new File("sample.pdf"); // change to relative path
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_PDF);
String filename = "output.pdf";
headers.setContentDispositionFormData(filename, filename);
headers.setCacheControl("must-revalidate, post-check=0, pre-check=0");
ResponseEntity<byte[]> response = null;
try {
response = new org.springframework.http.ResponseEntity<>(Files.readAllBytes(file.toPath()), headers, org.springframework.http.HttpStatus.OK);
} catch (java.io.IOException e) {
e.printStackTrace();
}
return response;
}
}
Try this using Spring RestController
#PostMapping(value = "/slip", headers = "Accept=application/json",
produces = "application/pdf")
public ResponseEntity<Resource> generateSalarySlip(HttpServletRequest request,
#RequestBody Locale locale) {
...
...
File file = new File(fileName);
HttpHeaders header = new HttpHeaders();
header.setContentType(MediaType.parseMediaType("application/pdf"));
header.add(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=salaryslip.pdf");
header.add("Cache-Control", "no-cache, no-store, must-revalidate");
header.add("Pragma", "no-cache");
header.add("Expires", "0");
InputStream targetStream = new FileInputStream(file);
Resource resource = new InputStreamResource(targetStream)
return ResponseEntity.ok()
.headers(header)
.contentLength(file.length())
.contentType(MediaType.parseMediaType("application/pdf"))
.body(resource);
}
I'm developing a Rest API, will be responsible to return a csv file as response.
This is my Api interface:
#Api(value = Constantes.REPORTS)
public interface ExtractFileApi {
#RequestMapping(value = Constantes.REPORTS_URL, produces = "application/csv", method = RequestMethod.GET)
public ResponseEntity<InputStreamResource> getExtractFile() throws IOException;
}
And this is my interface implementation:
#RestController
public class ExtractFileApiController implements ExtractFileApi {
#Override
public ResponseEntity<InputStreamResource> getExtractFile() throws IOException {
ClassPathResource pdfFile = new ClassPathResource("pdf-sample.csv");
HttpHeaders headers = new HttpHeaders();
headers.add("Cache-Control", "no-cache, no-store, must-revalidate");
headers.add("Pragma", "no-cache");
headers.add("Expires", "0");
return ResponseEntity.ok().headers(headers).contentLength(pdfFile.contentLength())
.contentType(MediaType.parseMediaType("application/octet-stream"))
.body(new InputStreamResource(pdfFile.getInputStream()));
}
For now, my API return a link to download the file, but I don't know how to force the response to be exactly a CSV file (file.csv).
Can any one help me ?
You need to change return type to void and then use following code at end
Path path = Paths.get(pdfFile.getPath());
response.setHeader("content-disposition", "attachment; filename="
+ path.getFileName().toString().replace(" ", "_"));
try {
response.setContentType(Files.probeContentType(path));
response.setContentLength((int) Files.size(path));
// Copy bytes from source to destination, closes both streams.
FileCopyUtils.copy(Files.newInputStream(path),
response.getOutputStream());
} catch (IOException e) {
LOGGER.error("fetching file failed", e);
response.setStatus(500);
}
Try changing the production output MIME type to text/csv instead.
I followed this tutorial to implement rest API with Spring Boot for downloading files (xml format).
My controller class is as follows:
#RestController
public class RistoreController {
#Autowired
private RistoreService ristoreService;
#RequestMapping(
value = "/ristore/foundation/{trf}",
method = RequestMethod.GET,
produces = "application/xml")
public ResponseEntity<InputStream> getXMLById(#PathVariable("trf") String trf) throws IOException {
InputStream inputStream = ristoreService.findByTRF(trf);
return ResponseEntity
.ok()
.contentType(MediaType.parseMediaType("application/octet-stream"))
.body(inputStream);
}
}
I have service interface RistoreService autowired in the controller and Bean class for that service looks like this:
#Service
public class RistoreServiceBean implements RistoreService {
public InputStream findByTRF(String trf) throws IOException {
String filePath = "/Users/djiao/Box Sync/Work/Projects/RIStore/foundation/foundation_new/" + trf + ".xml";
File file = new File(filePath);
return new FileInputStream(file);
}
}
I tested the application using the following curl command:
curl -i -H "Accept: application/xml" http://localhost:8080/ristore/foundation/TRF133672_1455294493597
However, I got 406 error, "Not Acceptable". Something wrong with the file format?
Try to change the definition of the controller that way
#RequestMapping(value = "/ristore/foundation/{trf}", method = RequestMethod.GET, produces = "application/xml")
public ResponseEntity<InputStreamResource> downloadXMLFile(#PathVariable("trf") String trf)
throws IOException {
// Optinal headers configuration
HttpHeaders headers = new HttpHeaders();
headers.add("Cache-Control", "no-cache, no-store, must-revalidate");
headers.add("Pragma", "no-cache");
headers.add("Expires", "0");
// get the inputStream
InputStream xmlFileInputStream = ristoreService.findByTRF(trf);
return ResponseEntity
.ok()
.headers(headers)
.contentType(MediaType.parseMediaType("application/octet-stream"))
.body(new InputStreamResource(xmlFileInputStream));
}
Then your service class would be :
#Service
public class RistoreServiceBean implements RistoreService {
public InputStream findByTRF(String trf) throws IOException {
String filePath = "/Users/djiao/Box Sync/Work/Projects/RIStore/foundation/foundation_new/" + trf + ".xml";
File file = new File(filePath);
return new FileInputStream(file);
}
}
406 Not Acceptable
The resource identified by the request is only capable of generating response entities which have content characteristics not acceptable according to the accept headers sent in the request.
That means that the inputstream you return must be considered as a resource as soon as you have a REST controller.
The following two lines in your code contradict each other:
.contentType(MediaType.parseMediaType("application/octet-stream"))
and
produces = "application/xml")
I have my REST response set up like so:
#MethodMapping(value = "/download", httpMethod = HttpMethod.GET)
public Response getLogFile() {
File log = new File("path");
if (log.exists())
{
return Response.ok(log, MediaType.APPLICATION_OCTET_STREAM)
.header("Content-Disposition", "attachment; filename=\"" + log.getName() + "\"" ) //optional
.build();
}
}
But the link just gives me a text response rather than a download:
{"status":200,"entity":{"path":"path"},"metadata":{"Content-Type":["application/octet-stream"],"Content-Disposition":["attachment; filename\u003d\"proteus.log\""]},"entityClosed":false,"entityBufferred":false}
The two packages I'm using are javax.ws.rs.core.Response and javax.ws.rs.core.MediaType.
Am I understanding the functionality wrong? Thanks!