Search code examples
hibernatespring-mvcspring-bootspring-data-jpathymeleaf

Display an image with spring boot hibernate and JPA


When I try to add an image in Base64 from a Product Object, like next:

   <tbody>
      <tr th:each="product : ${products}">
        <td><img th:src="@{'data:image/png;base64,' + ${product.image}}" /></td>
        <td th:text="${product.name}"></td>
        <td th:text="${product.price}"></td>
        <td th:if="${product.state==true}" th:text="Activo" style="color:green;"></td>  
        <td th:if="${product.state==false}" th:text="Bloqueado" style="color:red;"></td>
        <td><a href="#" class="btn btn-info btn-xs" data-toggle="collapse" data-target="#collapse-form">Editar</a><a href="#" class="btn btn-danger btn-xs">Eliminar</a></td>
      </tr>
  </tbody>

the {$product.image} has the value [B@776a398 but if I put in a LOG.Info(); this show me the based64 string. How can I solve it?

This is my Controller:

@GetMapping("/admin/products") 
public ModelAndView index(){

    User user = (User)SecurityContextHolder.getContext().getAuthentication().getPrincipal();
    ModelAndView mvn = new ModelAndView();
    mvn.addObject("user",userServiceImpl.getOne(user.getUsername()));

    List<Product> products  = productServiceImpl.getAll();

    for(Product product : products)
    {
        byte[] encode = Base64.getEncoder().encode(product.getImage());
        product.setImage(encode);
        LOG.info(new String(encode));
    }

    mvn.addObject("products",products);
    mvn.setViewName(view);
    LOG.info("Se ha ingresado al controlador de productos");
    return mvn;

}

enter image description here


Solution

  • When you get the value of the product image:

     <img th:src="@{'data:image/png;base64,' + ${product.image}}" />
    

    Thymeleaf is just doing a toString() of your byte[], in java the default toString() gets some non readable values and that is what thymeleaf is adding to the src.

    From the official doc:

    The toString method for class Object returns a string consisting of the name of the class of which the object is an instance, the at-sign character `@', and the unsigned hexadecimal representation of the hash code of the object. In other words, this method returns a string equal to the value of:

    getClass().getName() + '@' + Integer.toHexString(hashCode())

    So if you need to get the same as is showing in your logger you could use a method which returns it as String:

    public class Product {
    
        //...
        public String getImageEncoded() {
             return new String(this.image);
        }
    
    }
    

    And then in thymeleaf use this method:

    <img th:src="@{'data:image/png;base64,' + ${product.getImageEncoded()}}" />