Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to upload and retrieve file in mongodb in spring boot application without using GridFSTemplate?

I want to upload files and retrieve them from mongodb in spring boot application. But I don't want to use GridFSTemplate because my file size will not be greater than 16 MB. I am not choosing GridFSTemplate because none of the requirements mentioned in link https://docs.mongodb.com/manual/core/gridfs/#faq-developers-when-to-use-gridfs do not meet my requirements. Is working with Document to save files and retrieve them using MongoTemplate a good approach? MyDocument definition will look like

@Document
public class MyDocument {
    @Id
    private String id;
    private String emailId;
    private String docType;
    @CreatedDate
    private DateTime created;
    @LastModifiedDate
    private DateTime modified;
    private File document;
}

Storing file

MyDocument document = new MyDocument();
document.setEmailId("[email protected]");
document.setDocType("passport");
document.setDocument(file);
mongoTemplate.insert(document);

I want to store file along with some information like email. Later I will retrieve this file based on email parameter. Please suggest if this approach is good or any other better solution is appreciated.

like image 890
Sarvesh Avatar asked Nov 20 '17 10:11

Sarvesh


People also ask

What is the difference between MongoOperations and MongoTemplate?

MongoTemplate provides a simple way for you to save, update, and delete your domain objects and map those objects to documents stored in MongoDB. You can save, update and delete the object as shown below. MongoOperations is the interface that MongoTemplate implements.

What is the use of GridFS in MongoDB?

GridFS is the MongoDB specification for storing and retrieving large files such as images, audio files, video files, etc. It is kind of a file system to store files but its data is stored within MongoDB collections. GridFS has the capability to store files even greater than its document size limit of 16MB.

Which annotation is used to link a MongoDB document with a spring bean?

To take full advantage of the object mapping functionality inside the Spring Data/MongoDB support, you should annotate your mapped objects with the @org. springframework. data. mongodb.


1 Answers

I could finally figure out the way to store files without using GridFS in mongodb. First thing you have to note that we have to store byte[] representation of file.

import org.bson.types.Binary;
import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.mapping.Document;
import org.springframework.data.mongodb.core.mapping.Field;
@Document
public class DemoDocument {
    @Id
    @Field
    private String id;

    @Field
    private String emailId;

    @Field
    private String docType;

    @Field
    private Binary file;
}

Make sure your file object is org.bson.types.Binary. Following is my controller code to save object in monogodb.

@PostMapping("/upload")
public String singleFileUpload(@RequestParam("file") MultipartFile multipart, @RequestParam("email") String email) {
    try {
        DemoDocument demoDocument = new DemoDocument();
        demoDocument.setEmailId(email);
        demoDocument.setDocType("pictures");
        demoDocument.setDocument(new Binary(BsonBinarySubType.BINARY, multipart.getBytes()));
        mongoTemplate.insert(demoDocument);
        System.out.println(demoDocument);
    } catch (Exception e) {
        e.printStackTrace();
        return "failure";
    }
    return "success";
}

You can retrieve this object from mongodb as following.

@PostMapping("/retrieve")
public String retrieveFile(@RequestParam("email") String email){
    DemoDocument demoDocument = mongoTemplate.findOne(new BasicQuery("{emailId : \""+email+"\", docType : \"pictures\"}"), DemoDocument.class);
    System.out.println(demoDocument);
    Binary document = demoDocument.getDocument();
    if(document != null) {
        FileOutputStream fileOuputStream = null;
        try {
            fileOuputStream = new FileOutputStream(RETRIEVE_FOLDER + "prof_pic.jpg");
            fileOuputStream.write(document.getData());
        } catch (Exception e) {
            e.printStackTrace();
            return "failure";
        } finally {
            if (fileOuputStream != null) {
                try {
                    fileOuputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                    return "failure";
                }
            }
        }
    }
    return "success";
}

Please note this is just sample working code for understanding. It can be written in fully object oriented way keeping design principles in mind.

like image 119
Sarvesh Avatar answered Oct 19 '22 10:10

Sarvesh