Spring MVC And JPA Upload and Retrieve Photo To Postgres

Sat, Mar 1, 2014

Java Programming #java #programming

Sometimes we need to implement file upload functionality in our system, one can be a function to let the HR admin upload the photo of a worker. After uploaded, admin can see the photo they’ve uploaded in the profile page. In this sample we are going to use  Spring MVC and JPA as the backend code, and Postgres as the database.

First we will need to define some fields in the model class, for me, I created three, one to store the photo, one to store the file length and another one to store the mime type of the photo.

@Column(name="photo_blob")
@Type(type="org.hibernate.type.BinaryType") 
private byte[] photoBlob;
    
@Column(name = "photo_content_length")
private Integer photoContentLength;
    
@Column(name = "photo_content_type", length = 50)
private String photoContentType;

In Postgres, the column “photo_blob” is using the type of “bytea”.

As for the controller, we will be defining 2 methods, one for upload and another one for retrieve.

@RequestMapping(value="upload-photo", method=RequestMethod.POST)
    public  String handleFileUpload(@RequestParam("idNo") String idNo, @RequestParam("file") MultipartFile file, Model uiModel){
    // only do the upload if user selected file to upload
        if (!file.isEmpty()) {
            try {
                //get worker from db
                TblWorker worker = tblWorkerService.findTblWorker(idNo);
                //convert file input stream to byte array, so that we can store it into db.
                byte[] bytes = IOUtils.toByteArray(file.getInputStream());
                worker.setPhotoContentLength(Long.valueOf(file.getSize()).intValue());
                worker.setPhotoContentType(file.getContentType());
                worker.setPhotoBlob(bytes);
                tblWorkerService.updateTblWorker(worker);
                
                //after done updating the record, redirect back to worker page
                return "redirect:/workers/show/" + encodeUrlPathSegment(idNo);
            } catch (Exception e) {
                return "You failed to upload " + idNo + " => " + e.getMessage();
            }
        } else {
            return "redirect:/workers/show/" + encodeUrlPathSegment(idNo);
        }
    }
    
    // This method allows you to load image from an url like the following
    // http://hostname/workers/photo/1
    // to display as an image in the html file, we can use
    // <img src="http://hostname/workers/photo/1" />
    @RequestMapping("/photo/{idNo}")
    public void download(@PathVariable("idNo") String idNo, HttpServletRequest request, HttpServletResponse response) {
        try {
            
            TblWorker worker = tblWorkerService.findTblWorker(idNo);
            response.setHeader("Content-Disposition", "inline;filename="" +worker.getName()+ """);
            
            if(worker.getPhotoBlob() == null) {
                // if this worker doesn't have any photo, redirect to a default image.
                response.sendRedirect(request.getContextPath() + "/img/no_img_180.png");
            } else {
                // else display the photo by writing the byte array to the response.
                OutputStream out = response.getOutputStream();
                response.setContentType(worker.getPhotoContentType());
                response.setContentLength(worker.getPhotoContentLength());
                IOUtils.copy(new ByteArrayInputStream(worker.getPhotoBlob()), out);

                out.flush();
                out.close();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

Leave a message if you want a complete sample code for this. Thank you for reading.