mongodb存储图片和文件实践

本文涉及的产品
云数据库 MongoDB,通用型 2核4GB
简介:

可能很多人会问为何要用mongodb存储图片和文件,我的理由是mongodb作存储方便稳定易扩展,我们自己写的文件存储服务器肯定很LOW,除了含有巨量图片的大型系统,一般由公司自研图片存储外,大部分情况下,我们用mongodb足以应付。另外,很多人根本就不知道或者没尝试过用mongodb存储文件,而对方还故意问我为什么用这个。本文特此奉上代码并提供MongoDBClient与spring的集成。

工程结构代码 收藏代码

whatsmars-common  
  |-src  
    |-main  
      |-java  
        |-com.itlong.whatsmars.common.mongo  
          |-object  
            MongoDBConfig.java  
            MongoDBCredential.java  
            MongoDBDriver.java  
            ObjectIdCreator.java  
          |-serializer  
            CustomDateDeserializer.java  
            CustomDateSerializer.java  
          GridFSClient.java  
          MongoDBClient.java  
          ImageSizeEnum.java  
  pom.xml  
  
whatsmars-fs-web  
  |-src  
    |-main  
      |-java  
        |-com.itlong.whatsmars.fs.web  
          |-controller  
            FileController.java  
          |-service  
            |-impl  
              FileServiceImpl.java  
            FileService.java  
      |-resource  
        log4j.xml  
        mongodb-config.properties  
        spring-context.xml  
        spring-mvc-servlet.xml  
        spring-service  
  pom.xml  

主要依赖:
Xml代码 收藏代码

<!-- 图片压缩工具 -->  
        <dependency>  
            <groupId>org.imgscalr</groupId>  
            <artifactId>imgscalr-lib</artifactId>  
            <version>4.2</version>  
        </dependency>  
  
        <dependency>  
            <groupId>org.mongodb</groupId>  
            <artifactId>mongo-java-driver</artifactId>  
            <version>3.0.0</version>  
        </dependency>  

Java代码 收藏代码

public class MongoDBConfig {  
  
    private String addresses;  
  
  
    private List<MongoDBCredential> credentials;  
  
    public String getAddresses() {  
        return addresses;  
    }  
  
    public void setAddresses(String addresses) {  
        this.addresses = addresses;  
    }  
  
    public List<MongoDBCredential> getCredentials() {  
        return credentials;  
    }  
  
    public void setCredentials(List<MongoDBCredential> credentials) {  
        this.credentials = credentials;  
    }  
  
    public List<MongoCredential> buildCredentials() {  
        List<MongoCredential> mongoCredentials = new ArrayList<MongoCredential>();  
        for(MongoDBCredential item : this.credentials) {  
            MongoCredential credential = MongoCredential.createCredential(item.getUsername(),item.getDatabaseName(),item.getPassword().toCharArray());  
            mongoCredentials.add(credential);  
        }  
        return mongoCredentials;  
    }  
  
    public List<ServerAddress> buildAddresses() throws Exception{  
        List<ServerAddress> serverAddresses = new ArrayList<ServerAddress>();  
        String[] sources = addresses.split(";");  
        for(String item : sources) {  
            String[] hp = item.split(":");  
            serverAddresses.add(new ServerAddress(hp[0],Integer.valueOf(hp[1])));  
        }  
        return serverAddresses;  
    }  
}  

Java代码 收藏代码

public class MongoDBCredential {  
  
    private String databaseName;  
  
    private String username;  
    private String password;  
  
    public String getDatabaseName() {  
        return databaseName;  
    }  
  
    public void setDatabaseName(String databaseName) {  
        this.databaseName = databaseName;  
    }  
  
    public String getUsername() {  
        return username;  
    }  
  
    public void setUsername(String username) {  
        this.username = username;  
    }  
  
    public String getPassword() {  
        return password;  
    }  
  
    public void setPassword(String password) {  
        this.password = password;  
    }  
}  

Java代码 收藏代码

public class MongoDBDriver {  
  
    private Properties properties;  
    /** 
     */  
private MongoClient mongo = null;  
  
    /** 
     */  
private Integer connectionsPerHost = 32;  
  
    private Integer threadsAllowedToBlockForConnectionMultiplier = 5;  
  
    private Integer maxWaitTime = 30000;  
    private Integer connectTimeout = 30000;  
    private Integer socketTimeout = 30000;  
  
    private Integer maxConnectionIdle = 6000;  
  
  
    private MongoDBConfig configuration;  
  
    public void setProperties(Properties properties) {  
        this.properties = properties;  
    }  
  
    public void setConfiguration(MongoDBConfig configuration) {  
        this.configuration = configuration;  
    }  
  
    public void init() throws Exception{  
        if(properties != null){  
  
            String perHost = properties.getProperty("mongodb.driver.connectionsPerHost");  
            ////////////  
if(StringUtils.isNotBlank(perHost)){  
                connectionsPerHost = Integer.valueOf(perHost);  
            }  
            ////////////  
String multiplier = properties.getProperty("mongodb.driver.threadsAllowedToBlockForConnectionMultiplier");  
            if(StringUtils.isNotBlank(multiplier)){  
                threadsAllowedToBlockForConnectionMultiplier = Integer.valueOf(multiplier);  
            }  
            /////////////  
String waitTime = properties.getProperty("mongodb.driver.maxWaitTime");  
            if(StringUtils.isNotBlank(waitTime)){  
                maxWaitTime = Integer.valueOf(waitTime);  
            }  
            ////////////  
String ctimeout = properties.getProperty("mongodb.driver.connectTimeout");  
            if(StringUtils.isNotBlank(ctimeout)){  
                connectTimeout = Integer.valueOf(ctimeout);  
            }  
            ////////////  
String stimeout = properties.getProperty("mongodb.driver.socketTimeout");  
            if(StringUtils.isNotBlank(stimeout)){  
                socketTimeout = Integer.valueOf(stimeout);  
            }  
            ////////////  
String mci = properties.getProperty("mongodb.driver.maxConnectionIdle");  
            if(StringUtils.isNotBlank(mci)){  
                maxConnectionIdle = Integer.valueOf(mci);  
            }  
        }  
        ////init,db check and connected.  
execute();  
  
    }  
  
    private void execute() throws Exception{  
        MongoClientOptions.Builder builder = MongoClientOptions.builder();  
        builder.connectionsPerHost(this.connectionsPerHost);  
        builder.threadsAllowedToBlockForConnectionMultiplier(threadsAllowedToBlockForConnectionMultiplier);  
        builder.socketKeepAlive(true);  
        builder.maxWaitTime(this.maxWaitTime);  
        builder.connectTimeout(this.connectTimeout);  
        builder.socketTimeout(this.socketTimeout);  
        builder.maxConnectionIdleTime(maxConnectionIdle);  
  
        MongoClientOptions options = builder.build();  
  
        this.mongo = new MongoClient(configuration.buildAddresses(), configuration.buildCredentials(),options);  
  
    }  
  
  
    public void close() {  
        mongo.close();  
    }  
  
    public Mongo getMongo() {  
        return mongo;  
    }  
  
    public MongoDatabase getDatabase(String dbName) {  
        return mongo.getDatabase(dbName);  
    }  
  
    /** 
     * old api 
     * @param dbName 
* @return 
*/  
public DB getDB(String dbName) {  
        return mongo.getDB(dbName);  
    }  
  
}  

Java代码 收藏代码

public class ObjectIdCreator{  
  
    public static String creator(){  
        return new ObjectId().toString();  
    }  
}  

Java代码 收藏代码

public class CustomDateDeserializer extends JsonDeserializer<Date> {  
  
    private static final String[] pattern = { "yyyy-MM-dd HH:mm:ss" };  
  
    @Override  
    public Date deserialize(JsonParser arg0, DeserializationContext arg1)  
            throws IOException, JsonProcessingException {  
        if (JsonToken.VALUE_STRING.equals(arg0.getCurrentToken())) {  
            try {  
                return DateUtils.parseDate(arg0.getText(), pattern);  
            } catch (ParseException e) {  
                e.printStackTrace();  
            }  
        }  
        return null;  
    }  
}  

Java代码 收藏代码

public class CustomDateSerializer extends JsonSerializer<Date> {    
  private static final String pattern = "yyyy-MM-dd HH:mm:ss";  
  
  @Override    
  public void serialize(Date value, JsonGenerator jgen, SerializerProvider provider) throws IOException, JsonProcessingException {    
    jgen.writeString(DateFormatUtils.format(value, pattern));  
  }    
}  

Java代码 收藏代码

public class MongoDBClient {  
  
    protected MongoDBDriver mongoDBDriver;  
  
    protected String databaseName;  
  
    public void setMongoDBDriver(MongoDBDriver mongoDBDriver) {  
        this.mongoDBDriver = mongoDBDriver;  
    }  
  
  
  
    public void setDatabaseName(String databaseName) {  
        this.databaseName = databaseName;  
    }  
  
    public MongoCollection<Document> getCollection(String collectionName) {  
        MongoDatabase db = mongoDBDriver.getDatabase(this.databaseName);  
        return db.getCollection(collectionName);  
    }  
  
    public MongoDatabase getDatabase() {  
        return mongoDBDriver.getDatabase(this.databaseName);  
    }  
  
  
    public static void main(String[] args) throws Exception{  
  
        MongoDBDriver mongoDBDriver = new MongoDBDriver();  
        try{  
            MongoDBConfig mongoDBConfig = new MongoDBConfig();  
            //mongoDBConfig.setAddresses("61.171.123.234:27017");  
            mongoDBConfig.setAddresses("61.171.123.234:27017");  
            List<MongoDBCredential> credentials = new ArrayList<MongoDBCredential>();  
            MongoDBCredential credential = new MongoDBCredential();  
            credential.setDatabaseName("whatsmars-common");  
            credential.setUsername("whatsmars");  
            //credential.setPassword("haodai.com");  
            credential.setPassword("passwordiscommon");  
            credentials.add(credential);  
            mongoDBConfig.setCredentials(credentials);  
            mongoDBDriver.setConfiguration(mongoDBConfig);  
            mongoDBDriver.init();  
            MongoDBClient client = new MongoDBClient();  
            client.setDatabaseName("whatsmars-common");  
            client.setMongoDBDriver(mongoDBDriver);  
            ListCollectionsIterable<Document> documents = client.getDatabase().listCollections();  
            MongoCursor<Document> it = documents.iterator();  
            while (it.hasNext()) {  
                Document item = it.next();  
                System.out.println(item.toJson());  
            }  
            it.close();  
        } catch (Exception e) {  
            e.printStackTrace();  
        } finally {  
            mongoDBDriver.close();  
        }  
    }  
}  

Java代码 收藏代码

public class GridFSClient extends MongoDBClient{  
  
    private GridFS _gridFS = null;  
  
    private Object lock = new Object();  
  
    protected static final String[] IMAGE_FORMAT = {"jpg","jpeg","png"};  
  
  
    public void setMongoDBDriver(MongoDBDriver mongoDBDriver) {  
        this.mongoDBDriver = mongoDBDriver;  
    }  
  
    public GridFS getInstance() {  
        if(_gridFS != null) {  
            return _gridFS;  
        }  
        synchronized (lock) {  
            if(_gridFS != null) {  
                return _gridFS;  
            }  
            _gridFS = new GridFS(mongoDBDriver.getDB(this.databaseName));  
            return _gridFS;  
        }  
  
    }  
  
    public void close() {  
        mongoDBDriver.close();  
    }  
  
    /** 
     * 
     * @param inputStream 文件流 
     * @param format 文件格式,“pdf”,“png”等,不包含后缀符号“.” 
     * @return 
     */  
    public String saveFile(InputStream inputStream,String format,String uid) {  
        try {  
            GridFS gridFS = getInstance();  
  
            //随机生成文件名称,多次重试  
            String filename = this.randomFileName();  
            //如果有文件重复,则重新生成filename  
            while (true) {  
                GridFSDBFile _current = gridFS.findOne(filename);  
                //如果文件不存在,则保存操作  
                if (_current == null) {  
                    break;  
                }  
                filename = this.randomFileName();  
            }  
  
            GridFSInputFile file = gridFS.createFile(inputStream, filename);  
            if(format != null) {  
                file.put("format", format);  
            }  
            if(uid != null) {  
                file.put("uid",uid);  
            }  
            file.put("content-type","application/octet-stream");  
            file.save();  
            return concat(filename,format);  
        }catch (Exception e) {  
  
            throw new RuntimeException(e);  
        } finally {  
            try{  
                inputStream.close();  
            }catch (Exception ex) {  
                //  
            }  
        }  
    }  
  
    private String concat(String filename,String format) {  
        if(format == null) {  
            return filename;  
        }  
        if(format.startsWith(".")) {  
            return filename + format;  
        }  
        return filename + "." + format;  
    }  
  
    private String randomFileName() {  
        return RandomStringUtils.random(32, true, true).toLowerCase();  
    }  
  
    public void delete(String filename) {  
        GridFS gridFS = getInstance();  
        gridFS.remove(filename);  
    }  
  
    public InputStream getFile(String filename) {  
        GridFS gridFS = getInstance();  
        GridFSDBFile _current = gridFS.findOne(filename);  
        if(_current == null) {  
            return null;  
        }  
        return _current.getInputStream();  
    }  
  
    public InputStream getImage(String filename,String path) throws Exception{  
        //获取最大边,等比缩放  
        if(ImageSizeEnum.valueOfPath(path) == null) {  
            return null;  
        }  
  
        GridFS gridFS = getInstance();  
        GridFSDBFile _current = gridFS.findOne(filename);  
        if(_current == null) {  
            return null;  
        }  
  
        int size = ImageSizeEnum.valueOfPath(path).size;  
  
        int max = (Integer)_current.get("max");//图片的实际尺寸  
  
        InputStream result = null;  
        //裁剪  
        if(size < max) {  
            InputStream inputStream = _current.getInputStream();  
            BufferedImage image = ImageIO.read(inputStream);  
  
            inputStream.close();  
            ByteArrayOutputStream bos = new ByteArrayOutputStream();  
            BufferedImage thumbnail = Scalr.resize(image, size);//保留最大尺寸  
            String format = (String) _current.get("format");  
            ImageIO.write(thumbnail, format, bos);  
            result = new ByteArrayInputStream(bos.toByteArray());  
        } else {  
            result = _current.getInputStream();  
        }  
  
        return result;  
    }  
  
  
    /** 
     * 
     * @param inputStream 输入流 
     * @return 
     * @throws Exception 
     */  
    public String saveImage(InputStream inputStream,String uid) throws Exception{  
  
        BundleEntry bundleEntry = this.drain(inputStream);  
        if(bundleEntry == null) {  
            throw new RuntimeException("file isn't a image!");  
        }  
  
        ByteArrayInputStream bis = bundleEntry.inputStream;  
  
        String _currentFileName = this.isExistedImage(bundleEntry);  
  
        //如果文件md5已存在  
        if(_currentFileName != null) {  
            return _currentFileName;  
        }  
  
        String format = bundleEntry.format;  
        GridFS gridFS = getInstance();  
        String filename = this.randomFileName();  
        //检测文件名称  
        while(true){  
            GridFSDBFile _current = gridFS.findOne(filename);  
            //如果文件不存在,则保存操作  
            if (_current == null) {  
                break;  
            }  
            //否则,重新生成文件名称  
            filename = randomFileName();  
        }  
        //图片处理  
        bis.reset();  
  
        //保存原图  
        GridFSInputFile _inputFile = gridFS.createFile(bis, filename);  
        if(uid != null) {  
            _inputFile.put("uid", uid);  
        }  
        _inputFile.put("max",bundleEntry.max);  
        _inputFile.put("crc",bundleEntry.crc);  
        _inputFile.put("format",format);  
        _inputFile.put("md5_source",bundleEntry.md5);  
        _inputFile.save();  
  
        return concat(filename,format);  
  
    }  
  
    private String isExistedImage(BundleEntry entry) {  
        GridFS gridFS = getInstance();  
        DBObject query = new BasicDBObject();  
        query.put("crc",entry.crc);  
        query.put("md5_source",entry.md5);  
        GridFSDBFile _current = gridFS.findOne(query);  
        //根据MD5值查询,检测是否存在  
        if(_current == null) {  
            return null;  
        }  
        String format = (String)_current.get("format");  
        if(format.startsWith(".")) {  
            return _current.getFilename() + format;  
        }  
        return _current.getFilename() + "." + format;  
    }  
  
    /** 
     * 因为图片的stream需要reset,所以需要将流全部汲取 
     * @param inputStream 
     * @return 
     * @throws Exception 
     */  
    protected BundleEntry drain(InputStream inputStream) throws Exception{  
        //  
        ByteArrayOutputStream bos = new ByteArrayOutputStream();  
        //计算源文件的md5、crc,以防止图片的重复上传  
        Adler32 crc = new Adler32();  
        try{  
            while(true) {  
                int _c = inputStream.read();  
                if(_c == -1) {  
                    break;  
                }  
                bos.write(_c);  
                crc.update(_c);  
            }  
  
        }catch (Exception e) {  
            throw new RuntimeException(e);  
        } finally {  
            inputStream.close();  
        }  
  
        //第一步:图片格式  
        List<String> formats = new ArrayList<String>();//  
        ImageInputStream imageInputStream = ImageIO.createImageInputStream(new ByteArrayInputStream(bos.toByteArray()));  
        imageInputStream.mark();  
        try {  
            Iterator<ImageReader> it = ImageIO.getImageReaders(imageInputStream);  
            while (it.hasNext()) {  
                ImageReader reader = it.next();  
                String format  = reader.getFormatName().toLowerCase();  
                if(ArrayUtils.contains(IMAGE_FORMAT, format)) {  
                    formats.add(format);  
                }  
            }  
        }catch (Exception ex) {  
            //  
        }  
  
        //如果格式不合法,则直接返回  
        if(formats.isEmpty()) {  
            try {  
                imageInputStream.close();  
            } catch (Exception e) {  
                //  
            }  
            return null;  
        }  
  
        String md5 = DigestUtils.md5Hex(bos.toByteArray());//求原始图片的MD5,和crc  
        System.out.println("md5:" + md5);  
        imageInputStream.reset();  
  
        BufferedImage image = ImageIO.read(imageInputStream);  
  
        //获取最大边,等比缩放  
        int max = Math.max(image.getHeight(), image.getWidth());  
  
        bos = new ByteArrayOutputStream();  
        //如果尺寸超过最大值,则resize  
        if(max > ImageSizeEnum.PIXELS_MAX.size) {  
            max = ImageSizeEnum.PIXELS_MAX.size;  
        }  
        String format = formats.get(0);  
        BufferedImage thumbnail = Scalr.resize(image, max);//保留最大尺寸  
        ImageIO.write(thumbnail, format, bos);  
  
        return new BundleEntry(new ByteArrayInputStream(bos.toByteArray()),md5,crc.getValue(),format,max);  
    }  
  
  
    protected class BundleEntry {  
        String md5;  
        long crc;  
        String format;  
        int max;  
        ByteArrayInputStream inputStream;  
        BundleEntry(ByteArrayInputStream inputStream,String md5,long crc,String format,int max) {  
            this.md5 = md5;  
            this.crc = crc;  
            this.inputStream = inputStream;  
            this.format = format;  
            this.max = max;  
        }  
    }  
  
  
  
    public static void main(String[] args) throws Exception{  
  
        MongoDBDriver mongoDBDriver = new MongoDBDriver();  
        try {  
            GridFSClient client = new GridFSClient();  
            MongoDBConfig mongoDBConfig = new MongoDBConfig();  
            //mongoDBConfig.setAddresses("61.172.238.149:27017");  
            mongoDBConfig.setAddresses("61.172.240.58:27017");  
            List<MongoDBCredential> credentials = new ArrayList<MongoDBCredential>();  
            MongoDBCredential credential = new MongoDBCredential();  
            credential.setDatabaseName("whatsmars-fs");  
            credential.setUsername("whatsmars");  
            //credential.setPassword("haodai.com");  
            credential.setPassword("passwordisfs");  
            credentials.add(credential);  
            mongoDBConfig.setCredentials(credentials);  
            mongoDBDriver.setConfiguration(mongoDBConfig);  
            mongoDBDriver.init();  
            client.setDatabaseName("whatsmars-fs");  
            client.setMongoDBDriver(mongoDBDriver);  
            testUpload(client);  
            //testClear(client.getInstance());  
            //testGetImage(client.getInstance(),"xhgcguccxumuyl9hzdombgfvzgriv7rf",null);  
        } catch (Exception e) {  
            e.printStackTrace();  
        } finally {  
            mongoDBDriver.close();  
        }  
  
    }  
  
  
    protected static void testClear(GridFS gridFS) {  
        DBCursor cursor = gridFS.getFileList();  
        while (cursor.hasNext()) {  
            DBObject dbObject = cursor.next();  
            String filename = (String)cursor.next().get("filename");  
            System.out.println(filename);  
            System.out.println(dbObject.toString());  
            gridFS.remove(filename);  
        }  
        cursor.close();  
    }  
  
  
    protected static void testUpload(GridFSClient client) throws Exception{  
        FileInputStream inputStream = new FileInputStream(new File("/data/tmp/222222222.jpg"));  
  
        try {  
  
            String filename = client.saveImage(inputStream, null);  
            System.out.println(filename);  
            String source = filename.substring(0,filename.lastIndexOf("."));  
            System.out.println(source);  
            InputStream result = client.getImage(source, "x4");  
            if(result == null) {  
                System.out.println("not found!");  
            }  
            //vejibw36famkscjyksgke7bugzonnyan  
  
            FileOutputStream outputStream = new FileOutputStream("/data/tmp/" + filename);  
            while (true) {  
                int i = result.read();  
                if( i == -1) {  
                    break;  
                }  
                outputStream.write(i);  
            }  
            outputStream.flush();  
            outputStream.close();  
            result.close();  
        } catch (Exception e) {  
            e.printStackTrace();  
        } finally {  
            inputStream.close();  
        }  
  
    }  
  
    protected static void testGetImage(GridFS gridFS,String filename,String path) {  
        DBObject query = new BasicDBObject();  
        query.put("md5_source","9e131ae4ed7337d4712650229b827725");  
        GridFSDBFile file = gridFS.findOne(query);  
        if(file != null) {  
            System.out.println(file.getFilename());  
        }  
    }  
  
}  

Java代码 收藏代码

public enum ImageSizeEnum {  
  
    PIXELS_200(200, "x2"),  
    PIXELS_400(400, "x4"),  
    PIXELS_600(600, "x6"),  
    PIXELS_800(800, "x8"),  
  
    PIXELS_MAX(1024, "xm");//最大1024  
    public int size;  
  
    public String path;  
  
    ImageSizeEnum(int size, String path) {  
        this.size = size;  
        this.path = path;  
    }  
  
    public static ImageSizeEnum valueOfPath(String path) {  
        if(path == null) {  
            return  null;  
        }  
        for(ImageSizeEnum e : ImageSizeEnum.values()) {  
            if(e.path.equalsIgnoreCase(path)) {  
                return e;  
            }  
        }  
        return null;  
    }  
}  

mongodb-config.properties:
Xml代码 收藏代码

mongodb.driver.connectionsPerHost=32  
mongodb.driver.threadsAllowedToBlockForConnectionMultiplier=5  
mongodb.driver.maxWaitTime=30000  
mongodb.driver.connectTimeout=30000  
mongodb.driver.socketTimeout=30000  
mongodb.driver.maxConnectionIdle=60000  

spring-context.xml:
Xml代码 收藏代码

<?xml version="1.0" encoding="UTF-8"?>  
<beans xmlns="http://www.springframework.org/schema/beans"  
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
       xsi:schemaLocation="http://www.springframework.org/schema/beans  
           http://www.springframework.org/schema/beans/spring-beans-3.2.xsd"  
        default-autowire="byName">  
  
    <import resource="spring-service.xml" />  
</beans>  

spring-service.xml:
Xml代码 收藏代码

<?xml version="1.0" encoding="UTF-8"?>  
<beans xmlns="http://www.springframework.org/schema/beans"   
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
    xmlns:context="http://www.springframework.org/schema/context"  
    xsi:schemaLocation="  
        http://www.springframework.org/schema/beans  
        http://www.springframework.org/schema/beans/spring-beans-3.2.xsd  
        http://www.springframework.org/schema/context  
        http://www.springframework.org/schema/context/spring-context-3.2.xsd"  
    default-autowire="byName">  
  
    <context:component-scan base-package="com.itlong.whatsmars.fs.web.service" />  
  
    <bean id="mongodbProperties" class="org.springframework.beans.factory.config.PropertiesFactoryBean">  
        <property name="locations">  
            <list>  
                <value>classpath:mongodb-config.properties</value>  
            </list>  
        </property>  
    </bean>  
  
    <bean id="mongodbDriver" class="com.itlong.whatsmars.common.mongo.object.MongoDBDriver" init-method="init" destroy-method="close">  
        <property name="properties" ref="mongodbProperties"/>  
        <property name="configuration">  
            <bean class="com.itlong.whatsmars.common.mongo.object.MongoDBConfig">  
                <property name="addresses" value="${whatsmars.mongodb.filesystem.addresses}"/>  
                <property name="credentials">  
                    <list>  
                        <bean class="com.itlong.whatsmars.common.mongo.object.MongoDBCredential">  
                            <property name="databaseName" value="${whatsmars.mongodb.filesystem.dbname}"/>  
                            <property name="username" value="${whatsmars.mongodb.filesystem.username}"/>  
                            <property name="password" value="${whatsmars.mongodb.filesystem.password}"/>  
                        </bean>  
                    </list>  
                </property>  
  
            </bean>  
  
        </property>  
    </bean>  
  
    <bean id="gridFSClient" class="com.itlong.whatsmars.common.mongo.GridFSClient">  
        <property name="mongoDBDriver" ref="mongodbDriver"/>  
        <property name="databaseName" value="${whatsmars.mongodb.filesystem.dbname}"/>  
    </bean>  
  
</beans>  

spring-mvc-servlet.xml:
Xml代码 收藏代码

<?xml version="1.0" encoding="UTF-8"?>  
<beans xmlns="http://www.springframework.org/schema/beans"  
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
       xmlns:context="http://www.springframework.org/schema/context"  
       xmlns:mvc="http://www.springframework.org/schema/mvc"  
       xsi:schemaLocation="http://www.springframework.org/schema/beans  
           http://www.springframework.org/schema/beans/spring-beans-3.2.xsd  
           http://www.springframework.org/schema/context  
           http://www.springframework.org/schema/context/spring-context-3.2.xsd  
           http://www.springframework.org/schema/mvc  
           http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd">  
  
    <mvc:annotation-driven>  
        <mvc:message-converters>  
            <bean class="org.springframework.http.converter.StringHttpMessageConverter">  
                <property name = "supportedMediaTypes">  
                    <list>  
                        <value>text/plain;charset=UTF-8</value>  
                        <value>text/html;charset=UTF-8</value>  
                    </list>  
                </property>  
            </bean>  
  
        </mvc:message-converters>  
    </mvc:annotation-driven>  
    <context:component-scan base-package="com.itlong.whatsmars.fs.web.controller" />  
  
  
    <bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping"/>  
    <bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter"/>  
  
    <bean id="exceptionResolver" class="ExceptionHandler"/>  
  
</beans>  

Java代码 收藏代码

@Controller  
public class FileController {  
  
    private static final int SIZE = 1028576;//1M  
  
    @Autowired  
    private FileService fileService;  
  
    @RequestMapping("/file_upload")  
    @ResponseBody  
    public String uploadFile(@RequestParam(value = "format",required = false)String format,  
                             @RequestParam(value = "uid")String uid,  
                             @RequestParam("token")String token,  
                             HttpServletRequest request) {  
  
        String source = DESUtils.decrypt(token, CommonConstants.FS_SECURITY_KEY);  
        if(!source.equals(uid)) {  
            return ResultHelper.renderAsJson(ResultCode.VALIDATE_FAILURE);  
        }  
        ByteArrayOutputStream bos = new ByteArrayOutputStream();  
        try {  
            InputStream inputStream = request.getInputStream();//body inputstream  
            if (inputStream == null) {  
                return ResultHelper.renderAsJson(ResultCode.PARAMETER_ERROR);  
            }  
            int i = 0;  
            int maxSize = SIZE * 32;//最大32M  
            while (true) {  
                int _c = inputStream.read();  
                if (_c == -1) {  
                    break;  
                }  
                bos.write(_c);  
                i++;  
                if (i > maxSize) {  
                    inputStream.close();  
                    bos.close();  
                    return ResultHelper.renderAsJson(ResultCode.VALIDATE_FAILURE, "文件尺寸超过最大限制");  
                }  
            }  
            inputStream.close();  
        } catch (Exception e) {  
            return ResultHelper.renderAsJson(ResultCode.SYSTEM_ERROR);  
        }  
  
        //  
        ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());  
        Result result = this.fileService.uploadFile(bis, format,uid);  
        return ResultHelper.renderAsJson(result);  
    }  
  
  
    @RequestMapping("/image_upload")  
    @ResponseBody  
    public String uploadImage(@RequestParam("token")String token,  
                              @RequestParam("uid")String uid,  
                              @RequestParam(value = "return_size",required = false)Integer returnSize,  
                              HttpServletRequest request) {  
  
        String source = DESUtils.decrypt(token, CommonConstants.FS_SECURITY_KEY);  
        if(!source.equals(uid)) {  
            return ResultHelper.renderAsJson(ResultCode.VALIDATE_FAILURE);  
        }  
  
        ByteArrayOutputStream bos = new ByteArrayOutputStream();  
        try {  
            InputStream inputStream = request.getInputStream();//body inputstream  
            if (inputStream == null) {  
                return ResultHelper.renderAsJson(ResultCode.PARAMETER_ERROR);  
            }  
            int i = 0;  
            int maxSize = 6 * SIZE;//最大6M  
            while (true) {  
                int _c = inputStream.read();  
                if (_c == -1) {  
                    break;  
                }  
                bos.write(_c);  
                i++;  
                if (i > maxSize) {  
                    inputStream.close();  
                    bos.close();  
                    return ResultHelper.renderAsJson(ResultCode.VALIDATE_FAILURE, "文件尺寸超过最大限制");  
                }  
            }  
            inputStream.close();  
        } catch (Exception e) {  
            return ResultHelper.renderAsJson(ResultCode.SYSTEM_ERROR);  
        }  
  
        //  
        ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());  
        Result result = this.fileService.uploadImage(bis,uid,returnSize);  
        return ResultHelper.renderAsJson(result);  
    }  
  
    @RequestMapping("/ds/{filename}")  
    @ResponseBody  
    public void displayFile(@PathVariable("filename")String filename,HttpServletResponse response) {  
        Result result = this.fileService.displayFile(filename);  
        if(result.isSuccess()) {  
            InputStream stream = (InputStream)result.getModel("inputStream");  
            try {  
                OutputStream outputStream = response.getOutputStream();  
                if (stream != null) {  
                    BufferedInputStream bis = new BufferedInputStream(stream, 128);  
                    while (true) {  
                        int _current = bis.read();  
                        if (_current < 0) {  
                            break;  
                        }  
                        outputStream.write((byte) _current);  
                    }  
                }  
            } catch (Exception e) {  
                //  
            } finally {  
                try {  
                    stream.close();  
                }catch (Exception e) {  
                    //  
                }  
            }  
        }  
    }  
  
    @RequestMapping("/ds/{path}/{filename}")  
    @ResponseBody  
    public void displayImage(@PathVariable("filename")String filename,  
                             @PathVariable("path")String path,  
                             HttpServletResponse response) {  
  
        Result result = this.fileService.displayImage(filename,path);  
        if(result.isSuccess()) {  
            InputStream stream = (InputStream)result.getModel("inputStream");  
            try {  
                OutputStream outputStream = response.getOutputStream();  
                if (stream != null) {  
                    BufferedInputStream bis = new BufferedInputStream(stream, 128);  
                    while (true) {  
                        int _current = bis.read();  
                        if (_current < 0) {  
                            break;  
                        }  
                        outputStream.write((byte) _current);  
                    }  
                }  
//                String timestamp = (String)result.getModel("timestamp");  
//                if(timestamp != null) {  
//                    response.addDateHeader("Last-Modified",Long.valueOf(timestamp));  
//                }  
            } catch (Exception e) {  
                //  
            } finally {  
                try {  
                    stream.close();  
                }catch (Exception e) {  
                    //  
                }  
            }  
        }  
    }  
  
}  

Java代码 收藏代码

public interface FileService {  
  
    /** 
     * 上传文件,制定文件的格式 
     * @param inputStream 输入流 
     * @Param format 文件格式后缀 
     * @param uid 文件上传者 
     * 
     */  
    public Result uploadFile(InputStream inputStream, String format, String uid);  
  
    /** 
     * 图片上传 
     * @param inputStream 
     * @param returnSize 返回接近此size的url全路径 
     */  
    public Result uploadImage(ByteArrayInputStream inputStream, String uid, Integer returnSize);  
  
    /** 
     * 删除文件 
     * @param filename 
     * @return 
     */  
    public Result delete(String filename);  
  
    /** 
     * 获取文件 
     * @param filename 
     * @return 
     */  
    public Result displayFile(String filename);  
  
    public Result displayImage(String filename, String path);  
}  

Java代码 收藏代码

@Service  
public class FileServiceImpl implements FileService {  
  
    protected static final Logger logger = Logger.getLogger(FileService.class);  
  
    @Autowired  
    private GridFSClient gridFSClient;  
  
    @Override  
    public Result uploadFile(InputStream inputStream, String format,String uid) {  
        Result result = new Result();  
        try {  
            String filename = gridFSClient.saveFile(inputStream,format,uid);  
            result.addModel("filename",filename);  
            result.setSuccess(true);  
        } catch (Exception e) {  
            logger.error("upload file error,",e);  
            result.setResultCode(ResultCode.SYSTEM_ERROR);  
            result.setMessage("文件上传失败");  
        }  
        return result;  
    }  
  
    @Override  
    public Result uploadImage(ByteArrayInputStream inputStream,String uid,Integer returnSize) {  
        Result result = new Result();  
        try {  
            String filename = gridFSClient.saveImage(inputStream,uid);  
            result.addModel("filename",filename);  
  
            if(returnSize != null && returnSize > 0) {  
                //找出符合returnSize的path  
                for (ImageSizeEnum e : ImageSizeEnum.values()) {  
                    if (e.size >= returnSize) {  
                        result.addModel("uri",e.path + "/" + filename);  
                    }  
                }  
                //返回最大尺寸  
                result.addModel("uri",ImageSizeEnum.PIXELS_MAX.path + "/" + filename);  
            }  
            result.setSuccess(true);  
        } catch (Exception e) {  
            logger.error("upload image error,",e);  
            result.setResultCode(ResultCode.SYSTEM_ERROR);  
            result.setMessage("图片上传失败");  
        }  
        return result;  
    }  
  
    @Override  
    public Result delete(String filename) {  
        Result result = new Result();  
        try {  
            gridFSClient.delete(filename);  
            result.addModel("filename",filename);  
            result.setSuccess(true);  
        } catch (Exception e) {  
            logger.error("delete file error,",e);  
            result.setResultCode(ResultCode.SYSTEM_ERROR);  
            result.setMessage("文件删除失败");  
        }  
        return result;  
    }  
  
    @Override  
    public Result displayImage(String filename,String path) {  
        Result result = new Result();  
        try {  
            InputStream inputStream = gridFSClient.getImage(filename,path);  
            if(inputStream != null) {  
                result.addModel("inputStream", inputStream);  
                result.setSuccess(true);  
            }  
        } catch (Exception e) {  
            result.setResultCode(ResultCode.SYSTEM_ERROR);  
        }  
        return result;  
    }  
  
  
    @Override  
    public Result displayFile(String filename) {  
        Result result = new Result();  
        try {  
            InputStream inputStream = gridFSClient.getFile(filename);  
            if(inputStream != null) {  
                result.addModel("inputStream", inputStream);  
                result.setSuccess(true);  
            }  
        } catch (Exception e) {  
            result.setResultCode(ResultCode.SYSTEM_ERROR);  
        }  
        return result;  
    }  
}  

代码见 http://java.toutiao.im

原文链接:[http://wely.iteye.com/blog/2382451]

相关实践学习
MongoDB数据库入门
MongoDB数据库入门实验。
快速掌握 MongoDB 数据库
本课程主要讲解MongoDB数据库的基本知识,包括MongoDB数据库的安装、配置、服务的启动、数据的CRUD操作函数使用、MongoDB索引的使用(唯一索引、地理索引、过期索引、全文索引等)、MapReduce操作实现、用户管理、Java对MongoDB的操作支持(基于2.x驱动与3.x驱动的完全讲解)。 通过学习此课程,读者将具备MongoDB数据库的开发能力,并且能够使用MongoDB进行项目开发。 &nbsp; 相关的阿里云产品:云数据库 MongoDB版 云数据库MongoDB版支持ReplicaSet和Sharding两种部署架构,具备安全审计,时间点备份等多项企业能力。在互联网、物联网、游戏、金融等领域被广泛采用。 云数据库MongoDB版(ApsaraDB for MongoDB)完全兼容MongoDB协议,基于飞天分布式系统和高可靠存储引擎,提供多节点高可用架构、弹性扩容、容灾、备份回滚、性能优化等解决方案。 产品详情: https://www.aliyun.com/product/mongodb
相关文章
|
8月前
|
存储 NoSQL 分布式数据库
Hbase+ES和MongoDB存储大数据的选用
Hbase+ES和MongoDB存储大数据的选用
240 0
|
5天前
|
存储 NoSQL MongoDB
MongoDB数据库转换为表格文件的Python实现
MongoDB数据库转换为表格文件的Python实现
39 0
|
5天前
|
NoSQL Java MongoDB
【MongoDB 专栏】MongoDB 与 Spring Boot 的集成实践
【5月更文挑战第11天】本文介绍了如何将非关系型数据库MongoDB与Spring Boot框架集成,以实现高效灵活的数据管理。Spring Boot简化了Spring应用的构建和部署,MongoDB则以其对灵活数据结构的处理能力受到青睐。集成步骤包括:添加MongoDB依赖、配置连接信息、创建数据访问对象(DAO)以及进行数据操作。通过这种方式,开发者可以充分利用两者优势,应对各种数据需求。在实际应用中,结合微服务架构等技术,可以构建高性能、可扩展的系统。掌握MongoDB与Spring Boot集成对于提升开发效率和项目质量至关重要,未来有望在更多领域得到广泛应用。
【MongoDB 专栏】MongoDB 与 Spring Boot 的集成实践
|
5天前
|
NoSQL 安全 MongoDB
【MongoDB 专栏】MongoDB 的安全性考虑与实践
【5月更文挑战第11天】在数字化时代,MongoDB的数据安全至关重要。面临网络攻击、内部威胁、数据泄露和未授权访问等风险,我们需要重视MongoDB的安全性。关键措施包括身份验证和授权、数据加密、网络安全、备份和恢复、安全审计及正确配置。实践中应启用身份验证,配置访问控制,加密敏感数据,加强网络安全,并定期备份和审计。保持软件更新,结合业务需求制定安全策略,以确保数据的保密性、完整性和可用性。
【MongoDB 专栏】MongoDB 的安全性考虑与实践
|
5天前
|
存储 NoSQL MongoDB
【MongoDB 专栏】MongoDB 的 GridFS:存储与检索大文件
【5月更文挑战第10天】MongoDB&#39;s GridFS 是用于大规模数据和大文件存储的解决方案,它将文件分割成小块存储在不同文档中,以提升管理效率和避免性能问题。文件上传时记录元数据,通过唯一标识符实现快速检索。GridFS 提供高效存储、便捷检索和扩展性,适用于大文件管理。然而,应注意文件大小限制、数据一致性和性能优化。通过案例分析,展示了 GridFS 在实际应用中的优势和适用场景,为构建强大应用提供支持。
【MongoDB 专栏】MongoDB 的 GridFS:存储与检索大文件
|
5天前
|
NoSQL MongoDB 数据库
MongoDB数据恢复—MongoDB数据库文件被破坏的数据恢复案例
服务器数据恢复环境: 一台Windows Server操作系统服务器,服务器上部署MongoDB数据库。 MongoDB数据库故障&检测: 工作人员在未关闭MongoDB数据库服务的情况下,将数据库文件拷贝到其他分区。拷贝完成后将原MongoDB数据库所在分区进行了格式化操作,然后将数据库文件拷回原分区,重新启动MongoDB服务,服务无法启动。
|
5天前
|
NoSQL MongoDB 数据库
|
5天前
|
存储 JSON NoSQL
MongoDB的文档存储格式BSON和JSON的区别
MongoDB的文档存储格式BSON和JSON的区别
|
5天前
|
存储 NoSQL 关系型数据库
基于MongoDB实现聊天记录的存储
基于MongoDB实现聊天记录的存储
基于MongoDB实现聊天记录的存储
|
5天前
|
NoSQL 搜索推荐 算法
【MongoDB】MongoDB在推荐系统中的实践应用
【4月更文挑战第1天】【MongoDB】MongoDB在推荐系统中的实践应用