Devashish Bhardwaj
Devashish Bhardwaj

Reputation: 11

Fetching image from MySQL database in Spring boot and thymeleaf

I am trying to create a service which fetch image of a student along with other text details of student stored in database and display it on an html page. I tried but some hash value is being returned.

My Model Class

@Entity
@Table(name = "details")
public class Student {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private long id;

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

    @Column(name = "pic" , length = 2000)
    private byte[] pic;



    public Student(long id, String name, byte[] pic) {
        super();
        this.id = id;
        this.name = name;
        this.pic = pic;
    }



    public Student() {
        super();
        // TODO Auto-generated constructor stub
    }



    public long getId() {
            return id;
        }

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

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public byte[] getPic() {
        return pic;
    }

    public void setPic(byte[] pic) {
        this.pic = pic;
    }

    @Override
    public String toString() {
        return "Student [id=" + id + ", name=" + name + "];
    }
    }

Without Using a rest contoller will it be achieved like this?

My Controller

@Controller
public class ImgShowController {

    @Autowired
    EntityRepository entityRepository;



    @RequestMapping("/list")
    public String getAllStudents(Model model) {

        List<Imge> list = (List<Imge>) entityRepository.findAll();
        model.addAttribute("students", list);
        return "liststudents";

    }



    @RequestMapping(path= {"/particularlist","/particularlist/{id}"})
    public String  getImage(@PathVariable("id") Long id, Model model) {

        final Optional<Student> imget = entityRepository.findById(id);
        Imge imge = new Imge(imget.get().getId(), imget.get().getName(), decompressBytes(imget.get().getPic()));
        model.addAttribute("particularStudent", imge);
        return "particularstudent";


    }
    }

Decompress Byte function

public static byte[] decompressBytes(byte[] data) {
    Inflater inflater = new Inflater();
    inflater.setInput(data);
    ByteArrayOutputStream outputStream = new ByteArrayOutputStream(data.length);
    byte[] buffer = new byte[1024];
    try {
        while (!inflater.finished()) {
            int count = inflater.inflate(buffer);
            outputStream.write(buffer, 0, count);
        }
        outputStream.close();
    } catch (IOException ioe) {
    } catch (DataFormatException e) {
    }
    return outputStream.toByteArray();
}

Upvotes: 0

Views: 1649

Answers (1)

Random Guy
Random Guy

Reputation: 1134

First of all, I would suggest mentioning that you store binary object (LOB) in pic column in your entity class:

@Lob
@Column(name = "pic" , length = 2000)
private byte[] pic;

And then, it seems that Thymeleaf does not allow you to inject image directly into model, so you have 2 ways to accomplish this:

1.Adding another controller to serve you images

@GetMapping("/students/{id}/image")
public void studentImage(@PathVariable String id, HttpServletResponse response) throws IOException {
    var student = entityRepository.findById(id);
    var imageDecompressed = decompressBytes(student.get().getPic());

    response.setContentType("image/jpeg");
    InputStream is = new ByteArrayInputStream(imageDecompressed);
    IOUtils(is, response.getOutputStream());
}

and then referring to it from model like this:

<img th:src="@{'students/' + @{studentId} + '/image'}">

2.Using base64

You need to encode image as base64 string:

var base64EncodedImage = Base64.getEncoder().encodeToString(imageData);

and then setting into model like this:

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

I would suggest using the first way because otherwise you would depend on image size and overall payload would be 30% larger (base64), so by using the first way you let user's browser decide how and when to load particular image

Upvotes: 1

Related Questions