Some problem Logic with response POST in spring boot - java

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

Related

Save pdf on disk using JasperReportsViewResolver with Spring 4.x

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

What is the correct way to upload large Base64 encoded files with retrofit?

So I'm working with retrofit 2 which uses okhttp underneath. The below code snippet works but I get OOM errors for large files.
I believe this is because I am reading the file to a byte array.
What is the recommended way to work with this?
private void appendFileContentsToBody(Attachment attachment, MultipartBody.Builder requestBodyBuilder) throws IOException {
File file = new File(attachment.getAbsolutePath());
if(file.exists()){
RequestBody attachmentPart = RequestBody.create(null, Base64.getEncoder().encode(FileUtils.readFileToByteArray(file)));
requestBodyBuilder.addPart(Headers.of("X-Filename", attachment.getFilename()), attachmentPart);
}
}
You should not encode a file into Base64 before sending it, this should be done using stream, which will be done by Retrofit for you. So your code should look like
private void appendFileContentsToBody(Attachment attachment, MultipartBody.Builder requestBodyBuilder) throws IOException {
File file = new File(attachment.getAbsolutePath());
if(file.exists()){
RequestBody attachmentPart = RequestBody.create(MediaType.parse("application/pdf"), file);
requestBodyBuilder.addPart(Headers.of("X-Filename", attachment.getFilename()), attachmentPart);
}
}
where "application/pdf" - is MIME type of the particular file.
That way you will not suffer of OOM ever. However this approach might be implemented on a backend first cuz seems like now your backend implementation made applicable for web-apps only cuz it expects encoded file in a request body.

CXF JAX-RS downloading resource from URL

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.

How to get file contents from a MultipartHttpServletRequest object?

I would like to upload a file from the web page using this strategy. i.e. Ajax file upload tutorial . It is going all fine, but the issue is on the server side, where I want to open this file and read its contents.
I am using the following signature for the method which is called on the submit of the form.
i.e.
public #ResponseBody String getFile(MultipartHttpServletRequest request)
Can any body please let me know that how can I extract the contents of the file?
MultipartHttpServletRequest extends MultipartRequest, which has methods for accessing the files.
You can do this:
MultipartFile file = request.getFile(paramName);
See http://docs.spring.io/spring-framework/docs/3.2.0.M1/api/org/springframework/web/multipart/MultipartRequest.html

How To Download PDF file using Jersey?

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

Categories

Resources