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

Angular6 hiding component selector

It's sometimes useful to have angular's component selector not to be rendered in the page, as sometimes this can cause problems with...