Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to display byte array from a model in Thymeleaf

I want to display all my products info, but I have problem with showing a product image. I get my products from DB and then I add them to Model, but don't know why only image don't display. In HTML it looks like this:

<div class="row">
    <div class="col-sm-3 my-2 d-flex align-content-stretch flex-wrap" th:each="product : ${products}">
        <div class="card">
            <img class="card-img-top" th:src="${product.image}">
            <div class="card-body">
                <h5 class="card-title" th:text="${product.name}">Product name</h5>
                <p class="card-text" th:text="${product.description}">Product summary</p>
                <p class="card-text" th:text="${product.cost}">Product summary</p>
            </div>
        </div>
    </div>
</div>

In controller I add all the products like this:

@GetMapping("/")
public String getHomePage(Model model) {
    model.addAttribute("products", productRepository.findAll());
    return "home";
}

And the product model is as shown:

@Entity
@Getter
public class Product extends BaseEntity {

    private String name;

    private String description;

    @OneToOne
    private Category category;

    private double cost;

    @Lob
    private byte[] image;

    public Product() {
        super();
    }

    public Product(String name, String description, Category category, double cost, byte[] image) {
        this();
        this.name = name;
        this.description = description;
        this.category = category;
        this.cost = cost;
        this.image = image;
    }
}

My problem is that I want to display multiple images at one time. BTW, I know that the findAll method is not a good choose, but It is only for testing proposes. Later I want to implement pagination, but first how to display, a byte array image?

like image 364
slovvic Avatar asked Jan 12 '18 23:01

slovvic


People also ask

How do I use the Thymeleaf th object?

Handling User Input We use th:action to provide the form action URL and th:object to specify an object to which the submitted form data will be bound. Individual fields are mapped using the th:field=”*{name}” attribute, where the name is the matching property of the object.

How do I get a request attribute in Thymeleaf?

Request parameters can be easily accessed in Thymeleaf views. Request parameters are passed from the client to server like: https://example.com/query?q=Thymeleaf+Is+Great! In the above example if parameter q is not present, empty string will be displayed in the above paragraph otherwise the value of q will be shown.


1 Answers

I'm answering this old question, in the hope of helping someone with the same need.

In order to show image using bytes, you have to create a controller action with the role of showing the image:

@GetMapping("/product/image/{id}")
public void showProductImage(@PathVariable String id
                               HttpServletResponse response) throws IOException {
response.setContentType("image/jpeg"); // Or whatever format you wanna use

Product product = productRepository.findById(id);

InputStream is = new ByteArrayInputStream(product.getImage());
IOUtils.copy(is, response.getOutputStream());
}

Thus, you can simply show your image with:

<div class="row">
    <div class="col-sm-3 my-2 d-flex align-content-stretch flex-wrap" th:each="product : ${products}">
        <div class="card">
            <img class="card-img-top" th:src="@{'product/image/' + @{product.image}}">
            <div class="card-body">
                <h5 class="card-title" th:text="${product.name}">Product name</h5>
                <p class="card-text" th:text="${product.description}">Product summary</p>
                <p class="card-text" th:text="${product.cost}">Product summary</p>
            </div>
        </div>
    </div> 

PS: you better use the wrapper Byte in spite of byte for your image attribute. This will let you manage cases of no image (null)

Edit: The last line of showProductImage method is copying InputStream to OutputStream (check IOUtils doc for more details)

like image 190
elkolotfi Avatar answered Sep 26 '22 23:09

elkolotfi