I have write a simple Spring + Angular application just for learn more about it.
I have a spring controller which is mapped to a URL and when an request comes it returns an image.
I have written all the codes and the spring controller returns me the image but when i set it in the HTML it is not displayed correctly
here is my spring controller
#RequestMapping(value = "image/", method = RequestMethod.GET)
public ResponseEntity<byte[]> getChequeImage(HttpSessionsession,#PathVariable("itemId") Integer itemId,
HttpServletResponse response) {
try{
InputStream in = new FileInputStream(new File("path_to_image.jpg"));
final HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.IMAGE_JPEG);
return new ResponseEntity<byte[]>(IOUtils.toByteArray(in), headers, HttpStatus.OK);
}catch (IOException e){
LOGGER.error(e);
e.getMessage(), response);
return null;
}
}
here is my HTML code
<img src="{{image}}"/>
image is an Angular variable. Angular service is sending the request and binding the data to the image variable
here is the angular code
#scope.image = "data:image/jpg," + data_from_the_api;
You can't use raw image bytes directly on the page, but you can do Base64 encoding, this would be the adaptations
#RequestMapping(value = "image/", method = RequestMethod.GET)
public ResponseEntity<String> getChequeImage(HttpSessionsession,#PathVariable("itemId") Integer itemId,
HttpServletResponse response) {
try{
InputStream in = new FileInputStream(new File("path_to_image.jpg"));
final HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.IMAGE_JPEG);
byte[] binaryData = IOUtils.toByteArray(in)
byte[] encodeBase64 = Base64.encodeBase64(binaryData);
String base64Encoded = new String(encodeBase64, "UTF-8");
return new ResponseEntity<String>(base64Encoded , headers, HttpStatus.OK);
}catch (IOException e){
LOGGER.error(e);
e.getMessage(), response);
return null;
}
}
and as TechMa9iac said in the comment you should set #scope.image = "data:image/jpg;base64," + data_from_the_api;
Related
I want to implement CloudHealth API in my Spring Boot application. I want to fetch report of particular client. I have a dropdown where logged in user select reports and that report will be directly fetched from CloudHealth platform. I want to do that thing in my application. I want to generate JSON response of custom report. I followed API documentation available at https://apidocs.cloudhealthtech.com/#reporting_data-for-custom-report
but I am getting 404 Not Found: "{"error":"Record with id not found."}"
This is the code written in my service class:
public String getCustomReportData(String reportId) {
ResponseEntity<String> responseEntity = null;
String response = null;
try {
final String uri = "https://chapi.cloudhealthtech.com/olap_reports/custom/"+reportId;
RestTemplate restTemplate = new RestTemplate();
HttpHeaders header = new HttpHeaders();
header.set(HttpHeaders.AUTHORIZATION, "Bearer my-api-key");
header.set(HttpHeaders.ACCEPT,"application/json");
HttpEntity<String> requestEntity = new HttpEntity<String>("body",header);
responseEntity = restTemplate.exchange(uri, HttpMethod.GET, requestEntity, String.class);
response = responseEntity.getBody();
} catch (Exception e) {
System.out.println(e.getMessage());
e.printStackTrace();
}
return response;
}
This is main endpoint in my restcontoller:
#RequestMapping(value = {"/custom_report/{report_id}"}, method = {RequestMethod.GET, RequestMethod.POST}, produces = {MediaType.APPLICATION_JSON_VALUE})
public ResponseEntity<Object> getCustomCloudHealthReports(HttpServletRequest request,#PathVariable("report_id") String reportId){
try {
String response = standardReportService.getCustomReportData(reportId);
return new ResponseEntity<Object>(response, HttpStatus.OK);
} catch (Exception e) {
System.out.println(e.getMessage());
e.printStackTrace();
return new ResponseEntity<Object>("Please try again later", HttpStatus.INTERNAL_SERVER_ERROR);
}
}
I have a controller and an Exporter class to create pdf of one class data in Spring boot. It works at localhost. And I can send emails with attachments which are in the resources/static/ directory from this link:
https://asbnotebook.com/2020/01/26/send-email-with-attachment-spring-boot/
I want to email the pdf file created at fly. I tried to combine them but it didnt work.
public String sendMail(EmailRequestDto request, Map<String, String> model) {
String response;
MimeMessage message = mailSender.createMimeMessage();
try {
MimeMessageHelper helper = new MimeMessageHelper(message, MimeMessageHelper.MULTIPART_MODE_MIXED_RELATED,
StandardCharsets.UTF_8.name());
Template template = configuration.getTemplate("email.ftl");
String html = FreeMarkerTemplateUtils.processTemplateIntoString(template, model);
helper.setTo(request.getTo());
helper.setFrom(request.getFrom());
helper.setSubject(request.getSubject());
helper.setText(html, true);
List<PurchaseDetail> cities = (List<PurchaseDetail>)basketService.getPurchases();
ByteArrayInputStream bis = InvoicePdfExporter.citiesReport(cities);
HttpHeaders headers = new HttpHeaders(); headers.add("ContentDisposition",
"inline; filename=citiesreport.pdf");
InputStreamResource rs= (new InputStreamResource(bis)) ;
//this gives error because rs is a inputStreamResource but not InputStream
helper.addAttachment("citiesreport.pdf",newByteArrayResource(IOUtils.toByteArray(rs)));
mailSender.send(message);
response = "Email has been sent to :" + request.getTo();
} catch (MessagingException | IOException | TemplateException e) {
response = "Email send failure to :" + request.getTo();
}
return response;
}
And my working controller class which creates pdf. InvoicePdfExporter class adds datatable to document and returns as return new ByteArrayInputStream(out.toByteArray());:
#RequestMapping(value = "/pdfreport", method = RequestMethod.GET,
produces = MediaType.APPLICATION_PDF_VALUE)
public ResponseEntity<InputStreamResource> citiesReport() throws IOException
{
List<PurchaseDetail> purchases = (List<PurchaseDetail>)
basketService.getPurchases();
ByteArrayInputStream bis = InvoicePdfExporter.citiesReport(purchases);
HttpHeaders headers = new HttpHeaders(); headers.add("Content-Disposition",
"inline; filename=citiesreport.pdf");
return
ResponseEntity.ok().headers(headers).contentType(MediaType.APPLICATION_PDF)
.body(new InputStreamResource(bis)) ; }
}
I really need help I really dont understand from IOStreams, I tried many things but none of them solved my problem. Thanks!!
Edit:
I solved this problem by changing the return type of my InvoicePdfExporter to InputStreamSource and changed to this:
List<PurchaseDetail> cities = (List<PurchaseDetail>)basketService.getPurchases();
InputStreamSource bis =InvoicePdfExporter.citiesReport(cities);
HttpHeaders headers = new HttpHeaders(); headers.add("Content-Disposition",
"inline; filename=citiesreport.pdf");
helper.addAttachment("citiesreport.pdf",bis, "application/pdf" );
I'm trying to implement an ajax download. This is my code for the ajax request:
$('#download').click(function(){
$.ajax({
url: '${downloadPath}',
type: 'GET',
data: {${_csrf.parameterName}:'${_csrf.token}'},
success: function (res) {
}
});
});
And this is my controller's method:
#Secured("IS_AUTHENTICATED")
#RequestMapping(value="download/{id}", method=RequestMethod.GET, produces="application/pdf")
#ResponseBody
public void download(#PathVariable(value="id") final Long id, HttpServletResponse response) throws IOException {
CheckList checkList = checkListService.findById(id);
// byte[] byteItem = checkListService.getFileByIdDocument(id);
File f = new File(VariabiliGlobali.PATH_CHECKLIST+checkList.getPratica().getId()+"/"+id);
ServletOutputStream out = response.getOutputStream();
response.setContentType("application/pdf");
response.setContentLength((int)f.length());
response.setHeader("Content-Disposition", "attachment; filename=\"" + f.getName() + "\"");
FileInputStream in = new FileInputStream(f);
byte[] buffer = new byte[4096];
int length;
while( (length = in.read(buffer) ) > 0) {
out.write(buffer, 0, length);
}
in.close();
out.flush();
}
I can see the pdf inside the response:
But my browser (Chrome) doens't do anything.
Where am I wrong? How can I dowload it?
You don't need ajax and you are using as content type application/octet-stream as we can see in your code here:
response.setContentType("application/octet-stream");
If you want to display the pdf inside the browser (if the browser has the proper plugin to read pdf) you should use:
the right pdf content type
set the proper header
In my code i did the following:
response.setContentType("application/pdf");
response.setHeader("Content-Disposition", "inline; filename=pdfFileName.pdf;");
In any case I'd suggest to yuo to use the "spring" way like this:
#Secured("IS_AUTHENTICATED")
#RequestMapping(value="download/{id}", method=RequestMethod.GET)
public ResponseEntity<InputStreamResource> download(#PathVariable(value="id") final Long id) throws IOException {
HttpHeaders respHeaders = new HttpHeaders();
MediaType mediaType = new MediaType("application","pdf");
respHeaders.setContentType(mediaType);
respHeaders.setContentDispositionFormData("inline", "pdfFileName.pdf");
//Here you have to take the InputStream of the file you want to download
InputStreamResource isr = new InputStreamResource(new FileInputStream(file));
return new ResponseEntity<InputStreamResource>(isr, respHeaders, HttpStatus.OK);
}
I hope it's useful
Angelo
Set your content type in header. So browsers handles the pdf.
headers.setContentType(MediaType.parseMediaType("application/pdf"));
Below is the sample code.
#Secured("IS_AUTHENTICATED")
#RequestMapping(value="download/{id}", method=RequestMethod.GET, produces="application/pdf")
public ResponseEntity<?> download(#PathVariable(value="id") final Long id, HttpServletResponse response) throws IOException {
List<SampleDto> reportData = new ArrayList<SampleDto>();
HttpHeaders headers = new HttpHeaders();
if (null == reportData || reportData.size() == 0) {
return new ResponseEntity<byte[]>(null, headers, HttpStatus.NO_CONTENT);
}
byte[] contents = writePdfContentToBytes();//Here you should your code to get content in bytes.
headers.setContentType(MediaType.parseMediaType("application/pdf"));
headers.setContentDispositionFormData("inline", "Report.pdf");
return new ResponseEntity<byte[]>(contents, headers, HttpStatus.OK);
}
Currently, this is my code in the controller to return a XLS file for download:
#RequestMapping(value = "/export-data/", method = RequestMethod.GET)
public ResponseEntity exportAllData() {
ResponseEntity respEntity = null;
SheetDownload sheetDownload = new SheetDownload();
try {
ByteArrayOutputStream result = sheetDownload.createMentoringSheet();
HttpHeaders responseHeaders = new HttpHeaders();
byte[] out = result.toByteArray();
responseHeaders.add("content-disposition", "attachment; filename=export-data.xlsx");
responseHeaders.add("Content-Type", "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
respEntity = new ResponseEntity(out, responseHeaders,HttpStatus.OK);
}catch(Exception e){
respEntity = new ResponseEntity ("File Not Found", HttpStatus.OK);
}
return respEntity;
}
When I go to the "network" in Chrome, all I see in the response is:
So, there's no trigger to browser download, for example. The goal is to return the file to be downloaded in the proper format (XLSX).
Can someone help me?
Thank you in advance.
I am getting this error:
the request was rejected because no multipart boundary was found
when I upload an image through postman like this: I have saveImage as url, in header I have content/type and multipart/form-data and choossed raw and uploaded an image.
This is my controller:
#RequestMapping(value = "/saveImage",
method = RequestMethod.POST,
consumes = "application/json", produces = "application/json;charset=UTF-8")
public #ResponseBody ResponseEntity<GenericResponseVO<? extends IServiceVO>> getImage(
#RequestBody(required = false) GenericRequestVO<ImageCriteriaVO> imageCriteriaVO,HttpServletRequest request, HttpServletResponse response ) {
return requestHandlerInvoker.callHandler(
HandlerName.SAVE_IMAGE_HANDLER,request,response,imageCriteriaVO);
}
This my handler:
public GenericResponseVO<? extends IServiceVO> handleRequest(
UserContext userCtx, HttpServletRequest httpRequest,
HttpServletResponse httpResponse,
GenericRequestVO<? extends IServiceVO> requestVO)
throws O2Exception {
GenericResponseVO<ImageResultVO> imageVO = new GenericResponseVO<ImageResultVO>();
ImageResultVO imageResultVO = (ImageResultVO) serviceInvoker
.callService(ServiceName.IMAGE_SERVICE, userCtx,requestVO.getBody());
imageVO.setBody(imageResultVO);
imageVO.getHeader().setStatus(new Status(Status.SUCCESS, "Token"));
return imageVO;
This my service:
public IServiceVO service(UserContext userCtx, IServiceVO inputVO)
throws O2Exception {
LOG.info(LoggingEvent.Image_INPROGRESS,"Inside get list of treasure hunt for corporate service");
ImageCriteriaVO imageCriteriaVO = (ImageCriteriaVO) inputVO;
System.out.println(imageCriteriaVO.getFile());
ImageResultVO imageResultVO = new ImageResultVO();
CommonsMultipartFile file = null;
String fileName = null;
if (!file.isEmpty()) {
try {
fileName = file.getOriginalFilename();
byte[] bytes = file.getBytes();
BufferedOutputStream buffStream =
new BufferedOutputStream(new FileOutputStream(new File("F:/" + fileName)));
buffStream.write(bytes);
buffStream.close();
}catch (Exception e) {
}
}
return imageResultVO;
}
This my criteria class:
public class ImageCriteriaVO implements IServiceVO{
private byte[] file;
public byte[] getFile() {
return file;
}
public void setFile(byte[] file) {
this.file = file;
}
}
I hope this answer may help
Remove Content-Type from header when you are trying to upload, Postman will do it automatically.
if you set Content-Type: undefined, Postman will automatically sets Content-Type to multipart/form-data and depending upon the media it will set boundary.
Mail user agents ignore content-disposition headers in the messages.
File name should be mentioned in filename parameter. Otherwise should be mentioned in both filename and the name parameters5
multipart/form-data with Angular JS