前言
虽然java的口号:Write Once, Run Anywhere ,但现实很残酷!不同的操作系统、不同的容器总是让我们:Write Once,Debug Anywhere。所以关键还是要看设计,好的设计能减少迁移成本。
最近需要将roller迁移到百度云中,发现roller设计的真不错。非常容易就看迁移到云中了。
迁移的主要是数据,roller使用mysql,而百度云也提高mysql,这个基本不需要考虑迁移。主要是roller的图片上传功能:
1、如何将已经上传的图片迁移到百度的bcs中?
2、如何以最小的代价让将上传图片的功能迁移到百度bcs中?
增加一个切换开关:roller.properties
baiduyun.accessKey=dtjTg3L9xm baiduyun.secretKey=9V1L9mul9IVb baiduyun.bucket=hello enabled.use.baiduyun=true
package org.apache.roller.weblogger.business; import java.io.InputStream; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.roller.weblogger.config.WebloggerConfig; import org.apache.roller.weblogger.pojos.FileContent; import org.apache.roller.weblogger.pojos.MediaFile; import org.apache.roller.weblogger.pojos.Weblog; import org.apache.roller.weblogger.util.RollerMessages; import com.baidu.inf.iis.bcs.BaiduBCS; import com.baidu.inf.iis.bcs.auth.BCSCredentials; import com.baidu.inf.iis.bcs.model.Empty; import com.baidu.inf.iis.bcs.model.ObjectMetadata; import com.baidu.inf.iis.bcs.model.X_BS_ACL; import com.baidu.inf.iis.bcs.request.PutObjectRequest; /** * Manages contents of the file uploaded to Roller weblogs. * * This base implementation writes file content to a file system. */ public class BaiduYunFileContentManagerImpl extends FileContentManagerImpl { private static Log log = LogFactory.getLog(BaiduYunFileContentManagerImpl.class); private String host = "bcs.duapp.com"; private String accessKey = ""; private String secretKey = ""; private String bucket = ""; private BaiduBCS baiduBCS = null; /** * Create file content manager. */ public BaiduYunFileContentManagerImpl() { accessKey = WebloggerConfig.getProperty("baiduyun.accessKey"); secretKey = WebloggerConfig.getProperty("baiduyun.secretKey"); bucket = WebloggerConfig.getProperty("baiduyun.bucket"); BCSCredentials credentials = new BCSCredentials(accessKey, secretKey); baiduBCS = new BaiduBCS(credentials, host); baiduBCS.setDefaultEncoding("UTF-8"); // Default UTF-8 } /** * @see org.apache.roller.weblogger.model.FileContentManager#getFileContent(weblog, java.lang.String) */ public FileContent getFileContent(Weblog weblog, String fileId) throws FileNotFoundException, FilePathException { log.info("=====================get file content:" + fileId); final InputStream is = baiduBCS.getObject(bucket, getObjectStoragePath(weblog, fileId)).getResult().getContent(); return new FileContent(weblog, fileId, null) { private InputStream ins = is; @Override public InputStream getInputStream() { return ins; } }; } private String getObjectStoragePath(Weblog weblog ,String fileId) { return ‘/‘ + weblog.getHandle() + ‘/‘ + fileId; } public void saveFileContent(Weblog weblog, MediaFile mediaFile) throws FileNotFoundException, FilePathException, FileIOException { log.info("==========saveFileContent start ->" + mediaFile.getId()); ObjectMetadata objectMetadata = new ObjectMetadata(); objectMetadata.setContentType(mediaFile.getContentType()); objectMetadata.setContentLength(mediaFile.getLength()); PutObjectRequest request = new PutObjectRequest(bucket, getObjectStoragePath(weblog, mediaFile.getId()), mediaFile.getInputStream(), objectMetadata); ObjectMetadata result = baiduBCS.putObject(request).getResult(); log.info(result); baiduBCS.putObjectPolicy(bucket, getObjectStoragePath(weblog, mediaFile.getId()),X_BS_ACL.PublicRead); log.info("==========saveFileContent end"); } /** * @see org.apache.roller.weblogger.model.FileContentManager#deleteFile(weblog, java.lang.String) */ public void deleteFile(Weblog weblog, String fileId) throws FileNotFoundException, FilePathException, FileIOException { log.info("==========deleteFile start:" + fileId); Empty result = baiduBCS.deleteObject(bucket, getObjectStoragePath(weblog, fileId)).getResult(); baiduBCS.deleteObject(bucket, getObjectStoragePath(weblog, fileId) + "_sm").getResult(); log.info(result); log.info("==========deleteFile start"); } /** * @see org.apache.roller.weblogger.model.FileContentManager#overQuota(weblog) */ public boolean overQuota(Weblog weblog) { return false; } @Override public boolean canSave(Weblog weblog, String fileName, String contentType, long size, RollerMessages messages) { return true; } }
JPAWebloggerModule.java
if(WebloggerConfig.getBooleanProperty("enabled.use.baiduyun")) { binder.bind(FileContentManager.class).to( BaiduYunFileContentManagerImpl.class); } else { binder.bind(FileContentManager.class).to( FileContentManagerImpl.class); }
最后想说的是这个方法参数设计不太好,应该把MediaFile作为参数,而非用其个别字段(fileId和inputstream)
public void saveFileContent(Weblog weblog, String fileId, InputStream is) throws FileNotFoundException, FilePathException, FileIOException;
这样,roller就可以把百度bcs作为存储图片的服务器了。
原文地址:http://blog.csdn.net/rol2er/article/details/25654839