Crisncris0000
Crisncris0000

Reputation: 23

Duplicate - How can I display an image using Springboot-Thymeleaf

I've been trying to display an image using thymeleaf for awhile and having issues with it saving it as a byte array was no problem, however displaying it is extremely (for me at least) I followed a post with the question that was asked about it and had no results sadly, was hoping someone could help me with this problem

Controller trying to display the image

@GetMapping("/home")
public String index(Model model){
    model.addAttribute("clothingItems", itemService.findAll());
    return "index";
}

@GetMapping("/display/image/{id}")
public void displayItemImage(@PathVariable int id, HttpServletResponse response) throws IOException{

    response.setContentType("image/*");

    Item item = itemService.findItemById(id);

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

My Entity class

public class Item {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id")
    private int id;

    @Column(name = "post")
    private String text;

    @Lob
    @Column(name = "img")
    private byte[] image;

    @OneToOne(cascade = {CascadeType.DETACH,
                        CascadeType.MERGE,
                        CascadeType.PERSIST,
                        CascadeType.REFRESH})
    @JoinColumn(name = "category_id")
    private Category category;


    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getText() {
        return text;
    }

    public void setText(String text) {
        this.text = text;
    }

    public byte[] getImage() {
        return image;
    }

    public void setImage(byte[] image) {
        this.image = image;
    }

    public Category getCategory() {
        return category;
    }

    public void setCategory(Category category) {
        this.category = category;
    }

Trying to display it with thymeleaf

<div class="category-1">
    <h2>Headwear</h2>
    <div class="image-container" th:each="clothing : ${clothingItems}">
        <img th:src="@{'display/image/' + @{clothing.image}}">
    </div>

</div>

Result

I tried following this post How to display byte array from a model in Thymeleaf and ended up with an empty image

im also getting a NumberFormatException when I try to open the empty image in a new tab

Upvotes: 1

Views: 920

Answers (1)

Ryednap
Ryednap

Reputation: 312

In your thymeleaf template for the code

<img th:src="@{'display/image/' + @{clothing.image}}">

The src should point to @{'/display/image/'} you need to insert '/' that specifies you are referring to the root of your application also instead of @{clothing.image} it should be ${clothing.image} as it's a variable, not a link.

So the above line code of should be

<img th:src="@{'/display/image/' + ${clothing.id}}">

Try this in your displayItemImage method it's not advisable to directly write the content to the response entity and also change the MIME-TYPE to image/png or image/jpeg. Here's a better approach.

   @GetMapping("/display/image/{id}")
    public ResponseEntity<byte[]> displayItemImage(@PathVariable int id) {
        Item item = itemService.findItemById(id);
        byte[] image = item.getImage();
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.IMAGE_JPEG);
        return new ResponseEntity<>(image, headers, HttpStatus.OK);
    }

For testing the method I have used H2 database. Here's the test code with the results.

@SpringBootTest
class ShoppingSiteApplicationTests {
    @Autowired
    ItemService itemService;


    @Autowired
    private UserController yourController;

    private MockMvc mockMvc;




    @Test
    void testMethod() throws Exception {
        mockMvc = MockMvcBuilders.standaloneSetup(yourController).build();
        byte [] mockByte = {0x01, 0x02, 0x03};
        Item item = new Item();
        item.setImage(mockByte);

        itemService.saveItem(item);
        MvcResult result = mockMvc.perform(get("/display/image/" + item.getId()))
                .andExpect(status().isOk())
                .andExpect(content().contentType(MediaType.IMAGE_JPEG))
                .andReturn();

        byte[] responseBody = result.getResponse().getContentAsByteArray();
        assertArrayEquals(item.getImage(), responseBody);
    }
}

Test Results

Here's the live result from your Github Repository you can see the image displayed. The problem may be in the MYSQL setup or so, if yes please raise another question with the code. Hope it helps

Live image

Upvotes: 1

Related Questions