實現用戶資源和項目分離使用到了下面這個工具類:
保存路徑工具類
package cn.gukeer.common.utils;
import com.github.pagehelper.StringUtil;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.core.io.ClassPathResource;
import org.springframework.web.multipart.MultipartFile;
import java.io.*;
import java.util.Properties;
import java.util.StringTokenizer;
/**
* 文件管理幫助類,處理應用之外的文件,如照片、郵件附件等不依賴於應用存在而存在的文件。 注意:裡面的文件路徑除了特殊說明外都是基於VFS根路徑的
*
* @author guowei
*/
public abstract class VFSUtil {
private static Log log = LogFactory.getLog(VFSUtil.class);
/**
* VFS 根路徑(最後沒有/號)
*/
private static String VFS_ROOT_PATH;
static {
try {
readVFSRootPath();// 給VFS_ROOT_PATH賦初始值
} catch (Exception e) {
log.error("讀取配置文件出錯!", e);
}
}
/**
* 讀取VFS路徑配置文件
*/
private static void readVFSRootPath() {
String key = null;
if (System.getProperty("os.name").toUpperCase().indexOf("WINDOWS") != -1) {
key = "vfsroot.windows";
} else {
key = "vfsroot.linux";
}
try {
Properties p = new Properties();
InputStream inStream = new ClassPathResource("/db.properties").getInputStream();
p.load(inStream);
VFS_ROOT_PATH = p.getProperty(key);
} catch (Exception e1) {
VFS_ROOT_PATH = "";
log.error("[vfsroot路徑讀取]配置文件模式出錯!", e1);
}
if (StringUtil.isEmpty(VFS_ROOT_PATH)) {
if (System.getProperty("os.name").toUpperCase().indexOf("WINDOWS") != -1) {
VFS_ROOT_PATH = "C:/gukeer/vfsroot/";
} else {
VFS_ROOT_PATH = "/opt/gukeer/vfsroot/";
}
}
}
/**
* 獲取當前的VfsRootPath
*
* @return
*/
public static String getVFSRootPath() {
return VFS_ROOT_PATH;
}
/**
* 獲取文件輸入流
*
* @param file
* @param fileStream
* @return
*/
public static InputStream getInputStream(File file, boolean fileStream) {
if (fileStream == true) {//使用文件流
FileInputStream fin = null;
try {
fin = new FileInputStream(file);
} catch (FileNotFoundException e) {
if (log.isDebugEnabled()) {
log.debug(e);
}
String msg = "找不到指定的文件[" + file.getName() + "]。";
if (log.isDebugEnabled()) {
log.debug(msg);
}
throw new FileOperationException(msg, e);
}
return fin;
} else { // 使用內存流
InputStream in = null;
if (file != null && file.canRead() && file.isFile()) {
try {
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
FileInputStream stream = new FileInputStream(file);
BufferedInputStream bin = new BufferedInputStream(stream);
int len = 0;
byte[] b = new byte[1024];
while ((len = bin.read(b)) != -1) {
buffer.write(b, 0, len);
}
stream.close();
in = new ByteArrayInputStream(buffer.toByteArray());
} catch (Exception e) {
String msg = "不能讀取文件[" + file.getName() + "]";
if (log.isErrorEnabled()) {
log.error(msg, e);
}
throw new FileOperationException(msg, e);
}
} else {
String msg = "不是文件或文件不可讀[" + file.getName() + "]";
if (log.isDebugEnabled()) {
log.debug(msg);
}
throw new FileOperationException("不是文件或文件不可讀");
}
return in;
}
}
}
注意事項:①在resources文件夾內配置properties文件,包含vfsroot路徑信息(windows和linux兩個路徑),修改上傳方法使用戶上傳的文件和其他資源均存儲在vfsroot路徑下,並將圖片存儲路徑保存在數據庫內方便客戶端讀取使用; properties配置demo:
#db config jdbc.schema=gk_platform jdbc.driver=com.mysql.jdbc.Driver jdbc.url=jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=utf-8&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=UTC&useSSL=false jdbc.username=root jdbc.password=123456 vfsroot.windows=C:/platform/vfsroot/ vfsroot.linux=/opt/platform/vfsroot/②由於客戶端不能直接請求訪問位於服務器物理路徑上的資源,因此前端頁面采用流讀取的方式顯示圖片和其他資源;在controller內添加如下方法:
/**
* 讀取圖片文件
*
* @param response
* @throws Exception
*/
@RequestMapping("/website/showPicture")
public void showPicture(HttpServletResponse response, String picPath) throws Exception {
File file = new File(VFS_ROOT_PATH + picPath);
if (!file.exists()) {
logger.error("找不到文件[" + VFS_ROOT_PATH + picPath + "]");
return;
}
response.setContentType("multipart/form-data");
InputStream reader = null;
try {
reader = VFSUtil.getInputStream(file, true);
byte[] buf = new byte[1024];
int len = 0;
OutputStream out = response.getOutputStream();
while ((len = reader.read(buf)) != -1) {
out.write(buf, 0, len);
}
out.flush();
} catch (Exception ex) {
logger.error("顯示圖片時發生錯誤:" + ex.getMessage(), ex);
} finally {
if (reader != null) {
try {
reader.close();
} catch (Exception ex) {
logger.error("關閉文件流出錯", ex);
}
}
}
}
前台jsp頁面調用:<img src="<%=contextPath%>${image.imagesUrl}">,例如:
<img src='test/website/showPicture?picPath=/images/upload/image/20160608/1465355183063.png'/>
數據庫保存圖片的URL為/website/showPicture?picPath=/images/upload/image/20160608/1465355183063.png