Spring mvc send binary content from controller

Sometimes binary files such as images, documents are stored in the database; these binary files need then to be served dynamically

Below I'll show a code snippet showing how to handle this easily with Spring MVC

Before we begin just in case this is the list of libraries I used when coding this example :

  • Spring 3+
  • Spring Data JPA
  • Eclipselink 2.4+
  • Apache Tika
  • Slugify


@Entity
public class Resouce{

    @Id @Column(name = "ID")
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Column(name = "FILE_NAME", length = 200)
    private String fileName;


   @Column(name = "FILE")
    @Lob
    private byte[] file;

   //SETTERS - GETTERS OMMITED
}


@ResponseStatus(value = HttpStatus.NOT_FOUND)
public class ResourceNotFoundException extends RuntimeException {

}


/**
 * @author ulf
 */
@Controller
@RequestMapping("/resource")
public class ResourceController{

    // a basic Spring data repository
    @Autowired
    private ResourceRepostiory resourceRepository;

    
    // simple tika instance for handling mimetype resolution
    @Autowired
    private Tika tika;

    @RequestMapping(method = RequestMethod.GET)
    public ResponseEntity resource(@RequestParam("resourceId") Long resourceId) throws IOException {

        byte[] binary = null;
        String fileName = "";


            Resouce resource= resourceRepository.findOne(resourceId);

            if (resource!= null  && section.getFile() !=null ) {
                binary = section.getFile();
                fileName = section.getFileName();
            }


        if (binary == null) {
            throw new ResourceNotFoundException();
        } else {

            String extension = FilenameUtils.getExtension(fileName);

            // slugify the fileName to handle the Google Chrome error complaining of duplicate content disposition headers whenever the file name contains a ,
            fileName = new Slugify(true).slugify(FilenameUtils.removeExtension(fileName)) +"."+extension;

            HttpHeaders headers = new HttpHeaders();
            headers.setContentType(MediaType.parseMediaType(mimetype(fileName)));
            headers.setContentDispositionFormData(fileName, fileName);
            headers.setCacheControl("must-revalidate, post-check=0, pre-check=0");
            ResponseEntity responseEntity = new ResponseEntity(binary, headers, HttpStatus.OK);
            return responseEntity;


        }


    }

    private String mimetype(String fileName) {
        return ConfigurableMimeFileTypeMap.getDefaultFileTypeMap().getContentType(fileName);
    }


}


And that's it you should now be able to serve resources dynamically based on their id

Popular posts from this blog

Multi-hop ssh tunnel - howto : Creating a SSH tunnel with port forwarding between multiple hosts

Spring boot and spring data jpa tutorial - A sample application using spring 4.0 spring boot and JPA (part 2/2)

MongoDB spring data $elemMatch in field projection