Spring:Writing image from GridFS to jsp view - spring

I am using GridFS to store images. Now I want to write stored image to spring view page directly I have tried a lot, but not succeded. I can write image to my local system by using
gfs.writeTo("my location of local directory");
but how can I write same image to JSP view in spring? Any help is appreciated.

This is worked for me
Serve method:
#Override
public void serveImage(String imageId , HttpServletResponse response ) {
InputStream is = null;
ApplicationContext ctx = new AnnotationConfigApplicationContext(MongoDBConfiguration.class);
GridFsOperations gridOperations = (GridFsOperations) ctx.getBean("yourBeanName");
List<GridFSDBFile> result = gridOperations.find(new Query().addCriteria(Criteria.where("_id").is(imageId)));
for (GridFSDBFile file : result) {
try {
response.setHeader("Content-Disposition", "inline; filename=image.jpg");
response.setContentType("image/jpg");
response.setContentLengthLong(file.getLength());
is = file.getInputStream();
IOUtils.copy(is, response.getOutputStream());
response.flushBuffer();
} catch (java.nio.file.NoSuchFileException e) {
response.setStatus(HttpStatus.NOT_FOUND.value());
} catch (Exception e) {
response.setStatus(HttpStatus.INTERNAL_SERVER_ERROR.value());
}
}
}
Html code:
<image>
<source th:src="#{/get/${imageId}}" type="image/jpg">
</image>
Controller class:
#RequestMapping(value = "/get/{imageId}", method = RequestMethod.GET)
public void handleFileDownload(#PathVariable String imageId, HttpServletResponse response) {
try {
vaskService.serveImage(imageId, response);
} catch (Exception e) {
response.setStatus(HttpStatus.INTERNAL_SERVER_ERROR.value());
}
}

Related

I want to upload file without using multipart in spring boot, would be great if I could get you valuable suggestions on this

Shall I remove this from application.properties
spring.http.multipart.enabled=true
What should be my approach towards this file upload without using multipart?
This way, I'm able to uploading file using where I'm using multipart.
#RequestMapping(value = "/dog/create/{name}", method = RequestMethod.POST)
public JsonNode dogCreation(HttpServletRequest httpRequest, #RequestParam(value = "picture", required = false) MultipartFile multipartFile,
#PathVariable("name") String name) throws IOException, InterruptedException {
JSONObject response = new JSONObject();
Dog dog = new Dog();
String DOG_IMAGES_BASE_LOCATION = "resource\\images\\dogImages";
try {
File file = new File(DOG_IMAGES_BASE_LOCATION);
if (!file.exists()) {
file.mkdirs();
}
} catch (Exception e) {
e.printStackTrace();
}
dog = dogService.getDogByName(name);
if (dog == null) {
if (!multipartFile.isEmpty()) {
String multipartFileName = multipartFile.getOriginalFilename();
String format = multipartFileName.substring(multipartFileName.lastIndexOf("."));
try {
Path path = Paths.get(DOG_IMAGES_BASE_LOCATION + "/" + name + format);
byte[] bytes = multipartFile.getBytes();
File file = new File(path.toString());
file.createNewFile();
Files.write(path, bytes);
if (file.length() == 0) {
response = utility.createResponse(500, Keyword.ERROR, "Image upload failed");
} else {
String dbPath = path.toString().replace('\\', '/');
dog = new Dog();
dog.setName(name);
dog.setPicture(dbPath);
dog = dogService.dogCreation(dog);
response = utility.createResponse(200, Keyword.SUCCESS, "Image upload successful");
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
return objectMapper.readTree(response.toString());
}
I want to do it without using multipart, what would you suggest?
This is what I've done till now to solve this
#RequestMapping(value = "/dog/create/{name}", method = RequestMethod.POST)
public JsonNode dogCreation(HttpServletRequest httpRequest, #RequestParam("picture") String picture,
#PathVariable("name") String name) throws IOException, InterruptedException {
JSONObject response = new JSONObject();
Dog dog = new Dog();
String DOG_IMAGES_BASE_LOCATION = "resource\\images\\dogImages";
try {
File file = new File(DOG_IMAGES_BASE_LOCATION);
if (!file.exists()) {
file.mkdirs();
}
} catch (Exception e) {
e.printStackTrace();
}
dog = dogService.getDogByName(name);
if (dog == null) {
if (!picture.isEmpty()) {
String dogPicture = picture;
byte[] encodedDogPicture = Base64.encodeBase64(dogPicture.getBytes());
String format = dogPicture.substring(picture.lastIndexOf("."));
try {
} catch (Exception e) {
e.printStackTrace();
}
}
}
return objectMapper.readTree(response.toString());
}
I just have to say that this should probably only be used as a workaround.
On your frontend, convert the file to base64 in js:
const reader = new FileReader();
reader.readAsDataURL(file);
reader.onload = function(evt) {
console.log(evt.target.result);
//do POST here - something like this:
$.ajax("/upload64", {
method: "POST",
contentType: "application/text"
data: evt.target.result
}
};
On the server with an example of a decoder - more decoding options here Decode Base64 data in Java
import sun.misc.BASE64Decoder;
#PostMapping("/upload64")
public String uploadBase64(#RequestBody String payload){
BASE64Decoder decoder = new BASE64Decoder();
byte[] decodedBytes = decoder.decodeBuffer(encodedBytes);
//use your bytes
}

download csv using spring boot and apache commons

I have this below code for downloading CSV as an ajax button click, But the file is not downloading. Only showing the black new tab on the browser.
#RequestMapping(value = "/batch/download", method = RequestMethod.POST, produces = "text/csv")
#ResponseBody
public void downloadNGIBatchSelected(HttpServletResponse response) throws IOException {
List<String> ids = Arrays.asList("1312321","312313");
generateNewCustomerCSV(response.getWriter(),ids);
}
private void generateNewCustomerCSV(PrintWriter writer, List<String> ids){
String NEW_LINE_SEPARATOR = "\n";
//CSV file header
Object[] FILE_HEADER = {"Token Number",
"Token Expiry Date",
};
CSVPrinter csvPrinter = null;
try {
csvPrinter = new CSVPrinter(new BufferedWriter(writer), CSVFormat.DEFAULT.withRecordSeparator(NEW_LINE_SEPARATOR));
//Create CSV file header
csvPrinter.printRecord(FILE_HEADER);
for (PolicyMap PolicyMap : policyMaps) {
List customerCSV = new ArrayList();
customerCSV.add(PolicyMap.getInsurancePolicy().getTokenNo());
try {
csvPrinter.printRecord(customerCSV);
} catch (IOException e) {
e.printStackTrace();
}
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
writer.flush();
writer.close();
csvPrinter.close();
} catch (IOException e) {
System.out.println("Error while flushing/closing fileWriter/csvPrinter !!!");
e.printStackTrace();
}
}
}
You have set the content type in #RequestMapping annotation. But it is not going to work in the case when response is being written using HttpServletResponse. In this case, instead of spring, HttpServletResponse is writing the response that's why you have to set the response type in the response before getting the writer.
response.setContentType ("application/csv");
response.setHeader ("Content-Disposition", "attachment; filename=\"nishith.csv\"");

Uploading, modifying and download the same file in memory

I have to create an application that allows the user upload a specific Excel file. Sumarizing, the system needs to receive the file, write something in a specific cell and return the same file modificated to the view, then, the user can download this new file.
I'm using Apache POI for modify the excel file, but I don't know how to return this file to the view.
Upload view:
<form method="POST" enctype="multipart/form-data" th:action="#{/pessoa/lote}">
<table>
<tr><td>File to upload:</td><td><input type="file" name="file" /></td></tr>
<tr><td></td><td><input type="submit" value="Upload" /></td></tr>
</table>
</form>
Controller: Here I don't know what I need to do, I call a method named "consultaLote" from a Service who is named "ConsultaPessoaService".
#RequestMapping(value = "/lote", method = RequestMethod.POST)
public String handleFileUpload(#RequestParam("file") MultipartFile file,
RedirectAttributes redirectAttributes) {
try {
cpService.consultaLote(file);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
redirectAttributes.addFlashAttribute("message",
"You successfully uploaded " + file.getOriginalFilename() + "!");
return "redirect:/";
}
In the service, I can read and edit the file, then its generated a FileOutputStream. At this time I don't know how to continue, I need to return the file to the view using the controller, but I don't know how:
#Service
public class ConsultaPessoaService {
public FileOutputStream consultaLote(MultipartFile file) throws IOException {
DataFormatter formatter = new DataFormatter();
File convFile = new File(file.getOriginalFilename());
convFile.createNewFile();
FileOutputStream fos = new FileOutputStream(convFile);
fos.write(file.getBytes());
fos.close();
FileInputStream inputStream = new FileInputStream(convFile);
Workbook workbook = new XSSFWorkbook(inputStream);
Sheet firstSheet = workbook.getSheetAt(0);
Iterator<Row> iterator = firstSheet.iterator();
while (iterator.hasNext()) {
Row nextRow = iterator.next();
System.out.println(formatter.formatCellValue(nextRow.getCell(3)));
nextRow.getCell(3).setCellValue("test");
}
FileOutputStream outputStream = new FileOutputStream("arquivot.xlsx");
workbook.write(outputStream);
workbook.close();
outputStream.flush();
outputStream.close();
return outputStream;
}
}
You should return a byte array from consultaLote method. Method return type will be byte[] because you need this byte array to write the httpservlet outputstream.
public byte[] consultaLote(MultipartFile file) throws IOException {
//whatever changes you want, do it here. I am going to converting part
ByteArrayOutputStream baos = new ByteArrayOutputStream();
workbook.write(baos);
// before returning you can close your your ByteArrayOutputStream
//baos.close();
return baos.toByteArray();
}
Now comes to your controller. We write the byte array to OutputStream from HttpservletResponse.
#RequestMapping(value = "/lote", method = RequestMethod.POST)
public String handleFileUpload(#RequestParam("file") MultipartFile file,
RedirectAttributes redirectAttributes,HttpServletResponse response) {
byte[] fileBytes = null;
String reportName="yourReportName";
try {
fileBytes = cpService.consultaLote(file);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
if(fileBytes !=null){
response.setHeader("Content-Disposition", "attachment; filename=" + reportName + ".xls");
response.setContentType("application/xls");
response.getOutputStream().write(fileBytes);
response.getOutputStream().flush();
}
redirectAttributes.addFlashAttribute("message",
"You successfully uploaded " + file.getOriginalFilename() + "!");
return "redirect:/";
}
Hope this will help.

Spring MVC Thymeleaf: Displaying Buffered Image to HTML file

Can't display the image in the html file. Where did I go wrong?
#RequestMapping(value = "/image/{usr.id}", headers = "Accept=image/jpeg, image/jpg, image/png, image/gif", method = RequestMethod.GET)
public #ResponseBody BufferedImage getImage(#PathVariable("usr.id") Long id) {
Attachment att = attSvc.getPicById(id);
try {
InputStream in = new ByteArrayInputStream(att.getAttachmentFile());
return ImageIO.read(in);
} catch (IOException e) {
System.out.println("ERROR:" + e);
throw new RuntimeException(e);
}
}
Please tell me if you need more references! Thank you so much.
This should solve your issue.
...
public #ResponseBody byte[] getImage(#PathVariable("usr.id") Long id) {
...
InputStream in = new ByteArrayInputStream(att.getAttachmentFile());
BufferedImage img = ImageIO.read(in);
ByteArrayOutputStream bao = new ByteArrayOutputStream();
ImageIO.write(img, "jpg", bao);
return bao.toByteArray();
...

Uploading file using Spring REST API

I have my controller like this, i am using POSTMAN REST client for upload pdf file. setting content-type: multipart/form-data;boundary=randomBoundaryNotInAnyOfParts
It is creating the file but not writing anything in it. Am i missing something here?
#RequestMapping(value = "/uploadfile", method = RequestMethod.POST)
public #ResponseBody String upload(HttpServletRequest request) {
InputStream is = null;
OutputStream out = null;
try {
is = request.getInputStream();
byte[] b = new byte[1024];
out = new FileOutputStream(new File("C:\\tmp\\upload.txt"));
out.write(b);
} catch (IOException e) {
e.printStackTrace();
} finally{
try{
if(out != null){
out.close();
}
if(is != null){
is.close();
}
}catch(IOException io){
io.printStackTrace();
}
}
return null;
}
Thanks,
Vinay
Your byte[] is empty hence it is writing nothing in the file. Get content of the request into the byte[] and then write it into file.
Or you can use BufferedWriter also it is more fast.
Thanks,
Brijesh

Resources