I'm using Spring Boot, Spring Data REST, Jasper Report (6.x).
I created a REST controller that should export a PDF report on disk and return a "ok" string to the client. So, it's a bit different from the usual use case in which the user what the PDF is sent back to the client.
According to best practice, I'm using the solution 4 of this reply: https://stackoverflow.com/a/27532493/2012635 for the "normal" use case in which the PDF is returned to the client:
#RequestMapping(value = "/refunds/{id}/export", method = RequestMethod.GET)
public ModelAndView exportPdf(#PathVariable("id") Long id, HttpServletRequest request, Locale locale) throws Exception {
Refund refund = refundRepository.findOne(id);
if (refund != null) {
ModelMap model = new ModelMap();
model.addAttribute("datasource", new JREmptyDataSource(1));
model.addAttribute("model", refund);
return new ModelAndView("RefundPdfView-IT", model);
} else {
throw new ResourceNotFoundException();
}
}
This approach is very clean, I've my mapping in the property file:
#REFUND
RefundPdfView-IT.(class)=org.springframework.web.servlet.view.jasperreports.JasperReportsPdfView
RefundPdfView-IT.url=classpath:/reports/accounting/refunds/Refund-IT.jrxml
I'm wondering if I can reuse this approach to save the PDF on the disk in the server rather than send it back to the client.
I would like to reuse the mapping defined without hardcoding the position and names of reports.
Some advice would be appreciated.
First thing I would like to point out is you will need JasperExportManager.
exportReportToPdfFile(JasperPrint jasperPrint, java.lang.String destFileName)
to save a file locally in the server.
From your use case it is not clear why you want to save the file in server, I feel instead of saving the file you should save the search parameters. so that when you click on the parameters you will get/generate the pdf file again.
or alternatively you should use curl in the server and call the required url with parameters
Related
I will have to do some development and I will need your logic please,
I'll try to be as clear as possible
I have a JSON file that will be sent to a Web Service to process it.
When the file arrives on this Web Service, I have to parse it.
First question :
Is it a #PostMapping to recover this file?
Since it's a file, I get it as a file like this:
#PostMapping( value="/getFile",
consumes = {"multipart/form-data"})
public void postFile(#RequestParam() MultipartFile file) throws IOException
I recover the file well, but the concern is that the #RequestParam parameter expects a file name, except that when the file is sent to the web service, I do not know its name yet,
Second Question :
So how do you parse this file into a string?
Thank you in advance for your precious help
For the first question:
Yep, #PostMapping is the right way to go. Regarding the file name bit, #RequestParam() does not expect the file name to be passed, it expects the "key" of the key-value pair where the value is the file being uploaded.
For example, when sending a file via a RestTemplate call, the file would be included in the POST call as somewhat like this:
MultiValueMap<String, Object> body = new LinkedMultiValueMap<>();
body.add("uploadFile", getFileToUpload());
Here the key is "uploadFile", so your controller will look like this :
#PostMapping( value="/getFile",
consumes = {"multipart/form-data"})
public void postFile(#RequestParam("uploadFile") MultipartFile file) throws IOException
Checkout this tutorial : https://spring.io/guides/gs/uploading-files/
For the second question:
ByteArrayInputStream stream = new ByteArrayInputStream(file.getBytes());
String myFileString = IOUtils.toString(stream, StandardCharsets.UTF_8);
This should do. Cheers
I have been learning spring and to get the things together I am making an e-commerce application. I have used rest api to connect client and server. Now i need to send images to the client. My images are already stored in src/resources folder. What i need to know is that how do i send those images through rest api. so that i can use it in my client
I am very noob at this. I tried google and all i can find is examples of image files uploading to the server. I can't find a example of sending file from server to client through rest api. i've been stuck in this for past three day
Here is my rest controller:
now i need to know what should i do next so that i can send images
#RestController
#RequestMapping("/api")
public class CategoriesRestController {
// autowire customer service
#Autowired
private CategoriesService service;
//add mapping for GET all customer
#GetMapping("/categories")
public List<Categories> getCategories() {
return service.getCategories();
}
// adding mapping for GET only one customer
#GetMapping("/categories/{categoryId}")
public Categories getCategory(#PathVariable int categoryId) {
Categories categories = service.getCategory(categoryId);
if(categories == null) {
throw new CustomerNotFoundException("Customer id not found- "+ categoryId);
}else {
return categories;
}
}
// adding mapping for POST/customer i.e. insert a customer
#PostMapping("/categories")
public Categories addCategories(#RequestBody Categories theCategories) { //#RequestBody will convert JSON to JAVA object
// just to make things clear... always set id to 0 when inserting new object
// so that it will be created instead of update
theCategories.setId(0);
service.saveCategories(theCategories);
return theCategories;
}
You might be thinking about the problem the wrong way. Instead of sending the image itself through the rest API, the HTML only needs the path to the image. You store the image in a directory, and you can pass the path to the image to your HTML. You could add a variable "imagePath" to Categories and the HTML could reference it in the tag
You can convert your images to base64:
byte[] fileContent = FileUtils.readFileToByteArray(new File(filePath));
String encodedString = Base64.getEncoder().encodeToString(fileContent);
and then send this property through your API. then in your client side you can use it like this:
<img src=json.encodedString />
Here json is an object which has been sent over API.
Before sending the encodedString you may appned at its beginning some things like below, to make it easier to display in front-end:
"data:image/png;base64,"
To display a base64 image in front-end you should use some thing like this:
<img src="data:image/png;base64, iVBORw0KGgoAAAANSUhEUgAAAAUA
AAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO
9TXL0Y4OHwAAAABJRU5ErkJggg==" alt="Red dot" />
Read more:
https://www.baeldung.com/java-base64-image-string
How to display Base64 images in HTML?
I have a JSON that looks more or less like this:
{"id":"id","date":"date","csvdata":"csvdata".....}
where csvdata property is a big amount of data in JSON format too.
I was trying to POST this JSON using AJAX in Play! Framework 1.4.x so I sended just like that, but when I receive the data in the server side, the csvdata looks like [object Object] and stores it in my db.
My first thought to solve this was to send the csvdata json in string format to store it like a longtext, but when I try to do this, my request fails with the following error:
413 (Request Entity Too Large)
And Play's console show me this message:
Number of request parameters 3623 is higher than maximum of 1000, aborting. Can be configured using 'http.maxParams'
I also tried to add http.maxParams=5000 in application.conf but the only result is that Play's console says nothing and in my database this field is stored as null.
Can anyone help me, or maybe suggest another solution to my problem?
Thanks you so much in advance.
Is it possible that you sent "csvdata" as an array, not a string? Each element in the array would be a separate parameter. I have sent 100KB strings using AJAX and not run into the http.maxParams limit. You can check the contents of the request body using your browser's developer tools.
If your csvdata originates as a file on the client's machine, then the easiest way to send it is as a File. Your controller action would look like:
public static void upload(String id, Date date, File csv) {
...
}
When Play! binds a parameter to the File type, it writes the contents of the parameter to a temporary file which you can read in. (This avoids running out of memory if a large file is uploaded.) The File parameter type was designed for a normal form submit, but I have used it in AJAX when the browser supported some HTML5 features (File API and Form Data).
I want to send across resource(say a image) from some URL to front-end.
The typical way of doing this is to create a File and build the response. Is there any way in which I don't have to create the File in java code and still send the resource to front-end.
Front-end cannot access the URL due to some constraints.
Currently the Pseudo code looks like this.
File file = new File(fullPath);
FileUtils.copyURLToFile(url, file);
ResponseBuilder response = Response.ok(modulePDF);
I want to send content of URL to front-end without creating file. Is there any way?
What way did have in mind to actually obtain the file without creating a File object?
Not sure I fully understand the complete requirement, but you don't have to create a File object. You can send out a byte[], or simply write it to the response output stream by returning StreamingOutput.
#GET
public StreamingOutput getString() {
return new StreamingOutput(){
#Override
public void write(OutputStream out)
throws IOException, WebApplicationException {
// write to the `out` stream
}
};
}
For anything more than that, you will have to greatly elaborate on your requirement. The information you've provided, (especially the highlighted line) doesn't quite paint a clear enough problem as to what actual problem is you are facing.
I need to download pdf file using Jersey Web Services
i already do the following but the file size received is always 0 (zero).
#Produces({"application/pdf"})
#GET
#Path("/pdfsample")
public Response getPDF() {
File f = new File("D:/Reports/Output/Testing.pdf");
return Response.ok(f, "application/pdf").build();
}
Please help to do the correct way, thanks !!
Mkyong always delivers. Looks like the only thing you are missing is the correct response header.
http://www.mkyong.com/webservices/jax-rs/download-excel-file-from-jax-rs/
#GET
#Path("/get")
#Produces("application/pdf")
public Response getFile() {
File file = new File(FILE_PATH);
ResponseBuilder response = Response.ok((Object) file);
response.header("Content-Disposition","attachment; filename=test.pdf");
return response.build();
}
You can't just give a File as the entity, it doesn't work like that.
You need to read the file yourself and give the data (as a byte[]) as the entity.
Edit:
You might also want to look at streaming the output. This has two advantages; 1) it allows you to use serve files without the memory overhead of having to read the whole file and 2) it starts sending data to the client straight away without you having to read the whole file first. See https://stackoverflow.com/a/3503704/443515 for an example of streaming.
For future visitors,
This will find the blob located at the passed ID and return it as a PDF document in the browser(assuming it's a pdf stored in the database):
#Path("Download/{id}")
#GET
#Produces("application/pdf")
public Response getPDF(#PathParam("id") Long id) throws Exception {
Entity entity = em.find(ClientCase.class, id);
return Response
.ok()
.type("application/pdf")
.entity(entity.getDocument())
.build();
}