Spring doesnt display images when there is a path variable on URI - java

I have a method in my controller that directs to the page with comments.
All comments are related to a specific message. I use pathvariable to send messageID that I later use to get comments from my database.
#GetMapping("/showComments/{messageId}")
public String displayComments(#PathVariable Long messageId, #AuthenticationPrincipal User user, Model model) {
List<Comment> comments = commentService.showComments(messageId);
Message messageGotById = messageService.getMessageById(messageId);
model.addAttribute("comments", comments);
model.addAttribute("messageGot",messageGotById);
model.addAttribute("userId",user.getId());
return "listComments";
}
And then I have a method for fetching images from database
#GetMapping("/getImageComment/{id}")
public void showCommentImage(#PathVariable Long id, HttpServletResponse response) throws IOException {
response.setContentType("image/jpeg");
Message messageImage = messageService.getMessageById(id);
ImageInfo imageInfo = messageImage.getUsr().getImageInfo();
byte[] imageData = imageInfo.getImageData();
String encode = Base64.getEncoder().encodeToString(imageData);
InputStream is = new ByteArrayInputStream(imageData);
IOUtils.copy(is, response.getOutputStream());
}
listComments.html
<img th:src="#{'getImageComment/' + ${userId}}" height="55"
width="55">
Added the link I use to go to listComments.html
<a th:href="#{/showComments/{id}(id=${message.id})}">comment</a>
The issue here is that when there is a variable on URI in displayComments method, images are not displayed.
But without pathvariable everything works just fine.I cant understand what is the problem.

Followed dsp_user advice and used Server-relative URLs. Changed
<img th:src="#{'getImageComment/' + ${userId}}" height="55"
width="55">
to
<img class="rounded" th:src="#{'~/getImageComment/' + ${userId}}" height="55"
width="55">
And It finally worked for me.

Related

How get multiple images with springboot?

Goodmorning everyone,
I am creating a web application for my degree and I have been running into a problem for several days related to the loading and retrive of images from the database.
I can upload the photos without major problems, I still leave the controller code:
#PostMapping()
public AckDto handleImagePost(#RequestParam ("file") MultipartFile file, #RequestParam Long userId, #RequestParam Long contestId) throws ServiceException, IOException {
PhotoDto photoDto = new PhotoDto();
photoDto.setTitle("Test Image");
photoDto.setDescription("Test description");
photoDto.setImage(file.getBytes());
return photoService.saveImagineFile(photoDto, userId, contestId);
}
While for the get of the photos I can only take one photo with the following method:
#GetMapping(value = "/image", produces = MediaType.IMAGE_PNG_VALUE)
public Resource downloadImage(#RequestParam Long contestId) throws ServiceException, IOException {
Photo photo = photoService.findByContest_Id(contestId);
byte[] image = photoService.findByContest_Id(contestId).getImage();;
return new ByteArrayResource(image);
}
while if I try to take more photos with the following code obviously changing the Service and Repository:
#GetMapping(value = "/image", produces = MediaType.IMAGE_PNG_VALUE)
public List<Resource> downloadImage(#RequestParam Long contestId) throws ServiceException, IOException {
List<Photo> photo = photoService.findByContest_Id(contestId);
List<Resource> results = new ArrayList<>();
for(Photo p : photo){
results.add(new ByteArrayResource(p.getImage()));
}
return results;
}
it returns me the following errors:
org.springframework.http.converter.HttpMessageNotWritableException: No converter for [class java.util.ArrayList] with preset Content-Type 'null'
I also tried to return a PhotoDto list but it doesn't change anything,
Some idea?
If you need any other class, ask and it will be given to you.
Thanks to everyone, I solved the problem was that I had accidentally left some old notes that I assume were in conflict with others.
Not sure if the following works for you, but you can zip all images and then retrieve them in a unique file.
The code example (taken from the reference below):
#GetMapping(value = "/zip-download", produces="application/zip")
public void zipDownload(#RequestParam List<String> name, HttpServletResponse response) throws IOException {
ZipOutputStream zipOut = new ZipOutputStream(response.getOutputStream());
for (String fileName : name) {
FileSystemResource resource = new FileSystemResource(fileBasePath + fileName);
ZipEntry zipEntry = new ZipEntry(resource.getFilename());
zipEntry.setSize(resource.contentLength());
zipOut.putNextEntry(zipEntry);
StreamUtils.copy(resource.getInputStream(), zipOut);
zipOut.closeEntry();
}
zipOut.finish();
zipOut.close();
response.setStatus(HttpServletResponse.SC_OK);
response.addHeader(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + zipFileName + "\"");
}
Reference: https://www.devglan.com/spring-boot/spring-boot-file-upload-download
Rather than returning a List, return a ResponseEntity<List>.
It MIGHT work.
Problem is that whatever way you're going about it, it's unlikely the frontend will be able to pull out your images.
UUEncoding them manually and putting them in the HTTP headers is probably your best bet. That way the frontend can iterate over the headers containing the images and get them one by one in a format it should be able to decode.

How to return a webpage containing images using spring?

I am just getting started with spring and have used their spring initialiser to create a project. I then tweaked the java code to get it do what I wanted:
The above method maps a GET request to the location "/hello/{name" to the method I have written which returns a string: 'Hello {name}". I want an image to be returned next to this; how would I go about this?
This is not a common recommended approach. But since your question is to serve and HTML page with image via HTTP API, a very basic example is given below. Here the first API uses the second one internally to server the image. The image is served from resources folder and expecting that there is an image available with given name.
Note that you need to use proper MediaType for response Content-Type
#Controller
public class TestController {
#GetMapping(value = "/hello/{name}", produces = MediaType.TEXT_HTML_VALUE)
#ResponseBody
public String hello(#PathVariable("name") String name) {
return "<html>\n" + "<header><title>Hello "+name+"</title></header>\n" +
"<body>\n" + "Hello \n" +name+ "<img src='http://localhost:8080/image?name="+name+"'/></body>\n" + "</html>";
}
#GetMapping(
value = "/image",
produces = MediaType.IMAGE_PNG_VALUE
)
public ResponseEntity<InputStreamResource> getFile(#RequestParam(value = "name") final String name) throws IOException {
//Get Image using name
var image= new ClassPathResource(name+".png");
return ResponseEntity.ok().contentType(MediaType.IMAGE_PNG).body(new InputStreamResource(image.getInputStream()));
}
}
Now you can access this even via browser pointing to http://<host:port/hello/{name}. This will display the HTML page with the image.
If you want to get image via API, then you need to get the resource and return MediaType IMAGE_PNG_VALUE (If the image is PNG file).
Example:
#GetMapping(
value = "/image",
produces = MediaType.IMAGE_PNG_VALUE
)
public ResponseEntity<InputStreamResource> getFile(#RequestParam(value = "name") final String name) throws IOException {
//Get Image using name
var image= new ClassPathResource(name+".png");
return ResponseEntity.ok().contentType(MediaType.IMAGE_PNG).body(new InputStreamResource(image.getInputStream()));
}

Render thumbnail in Angular4

I am trying to render an image which I got from a Java service as InputStream, re-send it through NodeJS Express server and finally render it in Angular4
Here's what I do:
Java Jersey service:
#GET
#Path("thumbnail")
#ApiOperation(
value = "Gets document preview",
notes = "Gets document preview"
)
#ApiResponses(value = {
#ApiResponse(code = 200, message = "Preview of the document")
})
#Consumes(MediaType.MULTIPART_FORM_DATA)
#Produces("image/png")
public Response getDocThumbnail(
#ApiParam(value = "Entity UUID", required = true) #FormDataParam("uuid") String uuid
) throws RepositoryException, UnknowException, WebserviceException, PathNotFoundException, DatabaseException, AutomationException, AccessDeniedException, ConversionException, IOException {
RawDocument rawDocument = docCtrl.getDocThumbnail(uuid);
return Response
.ok(rawDocument.getInputStream(), "image/png")
.header("Content-Disposition", "attachment; filename=\" " + rawDocument.getName() + "\"")
.build();
}
the controller looks like:
public RawDocument getDocThumbnail(String uuid) throws IOException, AccessDeniedException, PathNotFoundException, WebserviceException, RepositoryException, DatabaseException, ConversionException, AutomationException, UnknowException {
return new RawDocument(
okmWebSrv.getOkmService().getThumbnail(uuid, ThumbnailType.THUMBNAIL_LIGHTBOX),
"whatever"
);
}
Basically it's call to OpenKM SDK to retreive document's thumbnail
This Java endpoint is called from NodeJS Express 4.15 that is pre-processing some requests for this Java backend.
Here's what I do:
...compose request options...
const vedica_res = await rp(options);
let buffered = new Buffer(vedica_res, 'binary');
res.writeHead(200, {
'Content-Type': 'image/png',
'Content-disposition': 'attachment;filename=' + 'thumb.png',
'Content-Length': buffered.length
});
return res.end(buffered, 'binary');
Finally with Angular4 being the initiator of this roundtrip I am trying to render the image like so:
this.rest.send('http://localhost:4200/vedica/api/document/thumbnail', RequestMethod.Get,
{uuid: '19516ea1-657e-4b21-8564-0cb87f29b064'}, true).subscribe(img => {
// this.preview = img
var urlCreator = window.URL;
var url = urlCreator.createObjectURL(img);
this.thumb.nativeElement.src = url;
})
The 'img' received is a Blob {size: 81515, type: "image/png"}. Console shows no errors but renders no image in the <img #thumb/> tag. But I can see that it sets the src=blob:http%3A//localhost%3A3000/4cf847d5-5af3-4c5a-acbc-0201e60efdb7 for it. Image just has a broken image icon.
When I try to read a cached response in a new tab, its accessible but renders nothing again.
Can you point out what I'm doing wrong? Have tried a lot, but no luck.
I think the problem is not the stream is closed early, the problem I think will be in the way is downloaded, take a look here:
https://docs.openkm.com/kcenter/view/sdk4j-1.1/document-samples.html#getContent
From the server side ( inde middle between OpenKM and your user interface ) the problem usualy is:
//response.setContentLength(is.available()); // Cause a bug, because at this point InputStream still has not its real size.
And you should use
response.setContentLength(new Long(doc.getActualVersion().getSize()).intValue());
resolved this by replacing request-promise with bare request package for making this request to the java BE and piping reply right into the wrapping response of the angular FE:
let reply = request(options);
reply.pipe(res);

How to send Japanese text to backend Java code via http get?

I want send を伴う出力となって to backend java code via http get request.
My get call url is http://localhost:8080/test/getID?id=%E3%82%92%E4%BC%B4%E3%81%86%E5%87%BA%E5%8A%9B%E3%81%A8%E3%81%AA%E3%81%A3%E3%81%A6
Java code:
#RequestMapping(value = "/getCaseId")
public ModelAndView showCaseId(HttpServletRequest request, HttpServletResponse response) throws UnsupportedEncodingException {
String msg = request.getParameter("id");
System.out.println("URL:"+msg);
return new ModelAndView("showID", "idList", null);
}
Above piece of code prints URL:ãä¼´ãåºåã¨ãªã£ã¦.
So what's change i need to do get the exact Japanese text what i have passed from front end.
Try changing your msg line to:
String msg = new String(
request.getParameter("id").getBytes(StandardCharsets.ISO_8859_1),
StandardCharsets.UTF_8
);
If that will work it means that your application server (Tomcat? jetty?) is not configured correctly to handle UTF-8 in URLs.
If you use eclipse IDE, you need to check Text File encoding. Please check with the following figure.
The problem is that the submitted query string is getting mutilated on the way into your server-side script, because getParameter() uses ISO-8559-1 instead of UTF-8.
So i modified my code as below and now its working
#RequestMapping(value = "/getCaseId")
public ModelAndView showCaseId(HttpServletRequest request, HttpServletResponse response) throws UnsupportedEncodingException {
String msg = new String(request.getParameter("id").getBytes("iso-8859-1"), "UTF-8")
System.out.println("URL:"+msg);
return new ModelAndView("showID", "idList", null);
}
I found this solution in http://help-forums.adobe.com/content/adobeforums/en/experience-manager-forum/adobe-experience-manager.topic.html/forum__lxgr-hi_i_am_havi.html.

display image in JSP using Spring

I'm trying to display an image in jsp injected.
I upload and I store the image in the database, but do not know how retrieve and display in jsp.
My controller:
#RequestMapping(value = "/ver2", method = RequestMethod.GET)
public void ver2(HttpSession session, HttpServletResponse response) {
OutputStream oImage;
Item item10 = itemRepository.findOne(11);
try {
byte[] photo = item10.getImagen();
response.setContentType("image/jpeg, image/jpg, image/png, image/gif");
oImage = response.getOutputStream();
oImage.write(photo);
oImage.flush();
oImage.close();
} catch (Exception e) {
e.printStackTrace();
}
}
With this code, i show a full screen, and i need inject in jsp. Any idea?
Thanks
You need to return Base64 encoded image bytes in String to your JSP page and use:
<img src="data:image/png;base64,${yourBase64EncodedBytesString}"/>
to display your image.
Use Apache Commons Codec to do Base64 encodings.
So for e.g.:
String yourBase64EncodedBytesString = new String(Base64.encodeBase64(content));
Set it for e.g. as a request attribute:
request.setAttribute("yourBase64EncodedBytesString", yourBase64EncodedBytesString);
And retrieve in JSP page:
<img src="data:image/png;base64,${requestScope['yourBase64EncodedBytesString']}"/>

Categories

Resources