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
Resource class
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
@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
}
404 exception
1
2
3
4
@ResponseStatus(value = HttpStatus.NOT_FOUND)
public class ResourceNotFoundException extends RuntimeException {
 
}
controller
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
/**
 * @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<byte[]> 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<byte[]> responseEntity = new ResponseEntity<byte[]>(binary, headers, HttpStatus.OK);
            return responseEntity;
 
 
        }
 
 
    }
 
    private String mimetype(String fileName) {
        return ConfigurableMimeFileTypeMap.getDefaultFileTypeMap().getContentType(fileName);
    }
 
 
}
 
 
</byte[]></byte[]></byte[]>

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

No comments:

Post a Comment

OSX show used ports or listening applications with their PID

On OSX you can display applications listening on a given port using the lsof the commands described below will show listening application...