upload and view image in spring mvc - java

i'm trying to upload an image in the database and then show it on a jsp, in a web application developed with spring MVC.
I've read all the questions concerning to this problem but i didn't get it.
I was thinking about saving the image in a blob field, instead of a clob one. Is it a good idea?
I've created a multipart form with a file input.
<form:form method="POST" action="monorigineEdit" modelAttribute="formMonorigineEdit" enctype="multipart/form-data">
...
<input type="file" name="image">
...
</form:form>
In the controller i get correctly the Multipartfile in this way
public String monorigineEdit(#RequestParam("image") MultipartFile file, HttpServletRequest request, ModelMap model,
#ModelAttribute(value = "formMonorigineEdit") #Valid MonorigineDTO monorigineDTO, BindingResult result, RedirectAttributes redirectAttrs) throws FacadeException
I would like, for testing purpose, just to forward the image to a jsp in base64 and show it, in this way in the controller
...
File auxFile = multipartToFile(file);
FileInputStream fi = new FileInputStream(auxFile);
byte[] byteArrayImage = Base64.encodeBase64(IOUtils.toByteArray(fi));
model.put("myImage", byteArrayImage);
return new String("monorigineEditTemplate");
and with this tag in the jsp
<img id="myImg" name="myImg" src="data:image/jpeg;base64,<c:out value='${myImage}'/>" >
The method multipartToFile is this one:
public File multipartToFile(MultipartFile multipart) throws IllegalStateException, IOException
{
File convFile = new File(multipart.getOriginalFilename());
multipart.transferTo(convFile);
return convFile;
}
The problem is that the browser doesn't show the image, but i can't get where i'm wrong.
Can you help me? :)
Thanks a lot.

Here is how you convert image to String and display it :
import org.apache.commons.codec.binary.Base64;
public String convertByteArrayImagetoString(){
BASE64Encoder base64Encoder = new BASE64Encoder();
File imagePath = new File(defaultPersonImagePath);
try {
BufferedImage bufferedImage = ImageIO.read(imagePath);
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
ImageIO.write(bufferedImage, "png", byteArrayOutputStream);
photoString = "data:image/png;base64," + base64Encoder.encode(byteArrayOutputStream.toByteArray());
} catch (IOException e) {
e.printStackTrace();
return "";
}
}
if you have doubts, let me know.

Related

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

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.

Should I use a session for a non authenticated user?

I have a requirement, have non authenticated users fill out a form that includes a back end generated captcha in order to submit approvals, I'm using Spring MVC and Cage to generate the captcha
#Controller
#Slf4j
public class ContactController {
#RequestMapping("/contact")
public String contact(Map<String, Object> model, HttpSession session, HttpServletRequest request) {
log.info("In contact");
try {
final String captchaCode = RandomStringUtils.randomAlphanumeric(5);
generate(new GCage(), 10, "cg1", ".jpg", captchaCode);
final File file = Paths.get("./cg13.jpg").toFile();
FileInputStream fileInputStreamReader = new FileInputStream(file);
byte[] bytes = new byte[(int)file.length()];
fileInputStreamReader.read(bytes);
String base64String = new String(Base64.encodeBase64(bytes), "UTF-8");;
model.put("image", "data:image/jpeg;base64," + base64String);
model.put("captcha", captchaCode);
session.setAttribute("captcha", captchaCode);
} catch (IOException e) {
log.error(e.getMessage(), e);
}
return "contact";
}
#PostMapping("/check")
public String checkCaptcha(final Map<String, Object> model, HttpSession session) {
log.info("in check captcha");
final String captcha = (String) session.getAttribute("captcha");
return "contact";
}
In Thymeleaf I'm using
<img th:src="#{${image}}" />
<form th:action="#{/check}" th:object="${captcha}" method="post">
<input type="submit" />
</form>
is it a bad practice to create a session for a non authenticated user like this? How else can this be handled then?
It's fine, but beware of session fixation. Spring's session handling is generally pretty good. Its default configuration will cause a change of session ID for when the user eventually authenticates.

Convert byte[] to image and display on jsp

I'm trying to display an uploaded picture (which is now a byte array) on a jsp page. Now, the byte[] column exists in the database and has to be converted to an image.
This is what I've been trying:
Part of the table on jsp page:
<c:forEach var="user" items="${userList}">
<tr>
<td>${user.fileName}</td>
<td>
<img src="data:image/jpg;base64,${user.imageFile}" alt="No image">
</td>
Part of the controller that takes an array of bytes from a MultipartFile object:
#RequestMapping(value = "/register", method = RequestMethod.POST)
public ModelAndView userRegister(#ModelAttribute("user") #Valid User user, BindingResult result, ModelMap model, #RequestParam("fileData") MultipartFile fileData) throws Exception {
if (!fileData.isEmpty() && fileData != null) {
byte[] bytes = fileData.getBytes();
user.setFileName(fileData.getOriginalFilename());
user.setImageFile(bytes);
}
}
If any additional information is needed, please let me know. Thanks.
You can add a tranisent base64imageFile property to your User. It will hold the base64 encoded string of the image, which you can access in your jsp like
<img alt="img" src="data:image/jpeg;base64,${user.base64imageFile}"/>
And in your method you should do the encoding, somethig like
#RequestMapping(value = "/register", method = RequestMethod.POST)
public ModelAndView userRegister(#ModelAttribute("user") #Valid User user, BindingResult result, ModelMap model, #RequestParam("fileData") MultipartFile fileData) throws Exception {
if (!fileData.isEmpty() && fileData != null) {
byte[] bytes = fileData.getBytes();
user.setFileName(fileData.getOriginalFilename());
user.setImageFile(bytes);
byte[] encodeBase64 = Base64.encodeBase64(bytes);
String base64Encoded = new String(encodeBase64, "UTF-8");
user.setBase64image(base64encoded);
}
}
IOUtils and Base64 are a handy util classes from org.apache.commons, shouldn't have a problem finding

Return a PDF file with Spring MVC

Actually, I have that functionality, I got a frame where I set the URL (ip:port/birt/preview?__report=report.rptdesign&__format=pdf&parameters...) and that frame renders the PDF file.
But I want that URL hidden...
I need return a PDF file with Spring MVC but that PDF is generated by another application.
This means I got another app (Eclipse Birt Engine) that I pass the parameters through of an URL (ip:port/birt/preview?__report=report.rptdesign&__format=pdf&parameters...) and it generates a PDF file, I need from my controller get that PDF and return it with Spring MVC. Could somebody help?
That would be like the below:
#Controller
#RequestMapping("/generateReport.do")
public class ReportController
#RequestMapping(method = RequestMethod.POST)
public void generateReport(HttpServletResponse response) throws Exception {
byte[] data = //read PDF as byte stream
streamReport(response, data, "my_report.pdf"));
}
protected void streamReport(HttpServletResponse response, byte[] data, String name)
throws IOException {
response.setContentType("application/pdf");
response.setHeader("Content-disposition", "attachment; filename=" + name);
response.setContentLength(data.length);
response.getOutputStream().write(data);
response.getOutputStream().flush();
}
}
PDF content is just bytes so you can just write the PDF content bytes to the HttpResponse output stream.

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