1.初步學習實現方式
(1)這裏是第一次實驗寫的代碼,將文件的上傳和下載寫成了一個工具類,可以直接調用。
package com.huangjian.util;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.math.BigDecimal;
import java.sql.Connection;
import java.sql.ResultSet;
import java.text.SimpleDateFormat;
import java.util.Date;
import org.apache.log4j.Logger;
import com.huangjian.common.util.JdbcTools;
import com.mysql.jdbc.PreparedStatement;
/**
* @desc: APEXSOFT_PROJECT
* @author: 黃堅
*/
public class FileHandler {
private static final Logger logger= Logger.getLogger(FileHandler.class);//log大家可以自己配置也可以不配置
private static final String downPath ="C:/Users/huangjian/Desktop/hj/";//這裏改寫成自己下載的目錄結構
/**
* 上傳文件到db方法
*/
public static String upLoadFile(String id,String path){
File file=new File(path);
// 獲取文件名稱
String fileName = file.getName();
// 獲取時間
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String date = format.format(new Date());
Connection con = null;
PreparedStatement ps = null;
try {
con = JdbcTools.getConnection();
//獲取輸入流
FileInputStream inputStream=new FileInputStream(file);
String sql = "INSERT INTO oa_worddoctable(ID,FFileName,FFileSize,FFileData,FState,FUser,FTime) VALUES(?,?,?,?,'0',?,?)";
ps = (PreparedStatement) con.prepareStatement(sql);
ps.setBigDecimal(1, new BigDecimal(id));
ps.setString(2, fileName);
ps.setBigDecimal(3, new BigDecimal((int)file.length()));
ps.setBinaryStream(4, inputStream,(int)file.length());
ps.setString(5, "-100");
ps.setString(6,date);
ps.executeUpdate();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
logger.error(e);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
logger.error(e);
}finally {
JdbcTools.release(con, ps);
}
return null;
}
/**
* 下載文件方法
*/
@SuppressWarnings("resource")
public static String downFile(String id){
Connection con = null;
PreparedStatement ps = null;
ResultSet rs = null;
try {
con = JdbcTools.getConnection();
// 從數據庫中讀出要還原文件的二進制碼,這裏我讀的是數據庫爲id的文件
String sqlString = "select * from oa_worddoctable where ID="+id;
ps = (PreparedStatement) con.prepareStatement(sqlString);
rs = ps.executeQuery();
byte[] Buffer = new byte[4096];
if (rs.next()) {
// 下載保存到本地文件
File file = new File(downPath+new String(rs.getBytes("FFilename")));
if (!file.exists()) {
try {
file.createNewFile();
} catch (Exception e) {
e.printStackTrace();
}
}
FileOutputStream outputStream = new FileOutputStream(file);
// 取字段用getBinaryStream()
InputStream iStream = rs.getBinaryStream("FFileData");
int size = 0;
while ((size = iStream.read(Buffer)) != -1) {
System.out.println(size);
outputStream.write(Buffer, 0, size);
}
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
logger.error(e);
}finally{
JdbcTools.release(rs, con, ps);
}
return null;
}
public static void main(String[] args) {
// TODO Auto-generated method stub
System.out.println("test上傳" );
FileHandler.upLoadFile("150", "自己的測試目錄");
System.out.println("test下載");
FileHandler.downFile("151");
}
}
這樣就能完成簡單的上傳下載的功能啦,對初步學習很有幫助!
2.深入後實現方式
(1)由於項目使用了structs,所以這裏類的風格是structs。
首先是下載
package com.dz.action;
import java.io.BufferedOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URLEncoder;
import java.sql.Blob;
import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.ResultSet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.log4j.Logger;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.actions.DispatchAction;
import com.apex.form.DataAccess;
import com.apex.form.SystemConfig;
import oracle.jdbc.OracleTypes;
import oracle.sql.BLOB;
/**
* @desc: APEXSOFT_PROJECT
* @author: 黃堅
*/
public class AppDownloadAction extends DispatchAction {
private static final Logger LG = Logger.getLogger(AppDownloadAction.class);
@SuppressWarnings("resource")
public ActionForward execute(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response)
throws Exception {
LG.info("開始下載文件...");
String id = request.getParameter("id");//
CallableStatement cstmt = null;
Connection con = null;
ResultSet rs = null;
InputStream in = null;
OutputStream outp = null;// 不要關閉
BufferedOutputStream bof = null;
String filenamedisplay = request.getParameter("fileName");// 下載時默認的文件名
try {
con = DataAccess.getDataSource().getConnection();
String databaseType = SystemConfig.INSTANCE.getDatabaseType();
if (databaseType.equals("SQLSERVER")) {
cstmt = con.prepareCall("{call sp_OA_WordDocDownload (?)}");
cstmt.setString(1, id);// --結果串語句
rs = cstmt.executeQuery();
if (rs.next()) {
Blob blob = (Blob) rs.getBlob(1);// 備註:oracle 的blob轉換有區別
in = blob.getBinaryStream();// ****獲得流****
}
} else if (databaseType.equals("ORACLE")) {
cstmt = con.prepareCall("{call sp_OA_WordDocDownload (?,?)}");
cstmt.registerOutParameter(1, OracleTypes.BLOB);
cstmt.setInt(2, Integer.parseInt(id));//
cstmt.execute();
BLOB blob = (BLOB) cstmt.getObject(1);
in = blob.getBinaryStream();// ****獲得流****
}
if (databaseType.equals("MYSQL")) {
cstmt = con.prepareCall("{call sp_OA_WordDocDownload (?)}");
cstmt.setString(1, id);// --結果串語句
rs = cstmt.executeQuery();
if (rs.next()) {
Blob blob = (Blob) rs.getBlob(1);// 備註:MYSQL的blob轉換有區別
in = blob.getBinaryStream();// ****獲得流****
}
}
} catch (Exception e) {
e.printStackTrace();
return null;
} finally {
if (rs != null)
rs.close();
if (cstmt != null)
cstmt.close();
if (con != null)
con.close();
}
response.reset();// 可以加也可以不加
response.setContentType("application/x-download;charset=gb2312");// 設置爲下載application/x-download
if (filenamedisplay == null) {
filenamedisplay = "附件";
}
filenamedisplay = URLEncoder.encode(filenamedisplay, "UTF-8");// 處理中午亂碼
response.addHeader("Content-Disposition",
"attachment;filename=" + filenamedisplay);
try {
outp = response.getOutputStream();
bof = new BufferedOutputStream(outp);
byte[] b = new byte[1024];
int i = 0;
while ((i = in.read(b)) > 0) {
bof.write(b, 0, i);
bof.flush();
}
return null;
} catch (Exception e) {
e.printStackTrace();
return null;
} finally {
if (in != null) {
in.close();
}
}
}
}
(2)上傳文件
package com.dz.action;
import java.io.File;
import java.io.InputStream;
import java.math.BigDecimal;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.apache.log4j.Logger;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.actions.DispatchAction;
import com.apex.form.DataAccess;
import com.apex.form.User;
import com.apex.form.UserContext;
/**
* @desc: APEXSOFT_PROJECT
* @author: 黃堅
*/
public class AppUploadAction extends DispatchAction {
private static final Logger LG = Logger.getLogger(AppUploadAction.class);
@SuppressWarnings({"static-access", "unchecked"})
public ActionForward execute(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response)
throws Exception {
LG.info("開始保存簽名文件...");
InputStream is = null;
String fileName = null;
BigDecimal userId = BigDecimal.valueOf(-1);
User user = UserContext.getContext().getUser();
if(user != null){
int uid = Integer.parseInt(user.getId());
userId= new BigDecimal(uid);
}
Map<String,String> props = new HashMap<String,String>();
try {
//使用Apache文件上傳組件處理文件上傳步驟:
//1、創建一個DiskFileItemFactory工廠
DiskFileItemFactory diskFileItemFactory = new DiskFileItemFactory();
//2、創建一個文件上傳解析器
ServletFileUpload fileUpload = new ServletFileUpload(diskFileItemFactory);
//解決上傳文件名的中文亂碼
fileUpload.setHeaderEncoding("UTF-8");
//3、判斷提交上來的數據是否是上傳表單的數據
if(!fileUpload.isMultipartContent(request)){
//按照傳統方式獲取數據
LG.error("文件不是表單數據,保存失敗");
return null;
}
//4、使用ServletFileUpload解析器解析上傳數據,解析結果返回的是一個List<FileItem>集合,每一個FileItem對應一個Form表單的輸入項
List<FileItem> list = fileUpload.parseRequest(request);
for (FileItem item : list) {
//如果fileitem中封裝的是普通輸入項的數據
if(item.isFormField()){
String name = item.getFieldName();
//解決普通輸入項的數據的中文亂碼問題
String value = item.getString("UTF-8");
props.put(name, value);
}else{
//如果fileitem中封裝的是上傳文件,得到上傳的文件名稱,
fileName = item.getName();
if(fileName==null||fileName.trim().equals("")){
LG.error("文件名缺省,上傳失敗");
continue;
}
//處理獲取到的上傳文件的文件名的路徑部分,只保留文件名部分
fileName = fileName.substring(fileName.lastIndexOf(File.separator)+1);
//獲取item中的上傳文件的輸入流
is = item.getInputStream();
}
}
LG.info("fileName:" +fileName +" ,props:" + props.toString());
saveDocAppToDb(userId+"",props.get("id"),fileName,is);
LG.info("入庫成功!");
return null;
} catch (FileUploadException e) {
LG.error("發生異常,入庫失敗!");
e.printStackTrace();
return null;
}finally{
//關閉輸入流
if(is != null){
is.close();
}
}
}
private void saveDocAppToDb(String userId,String docid,String fileName, InputStream inStream)
throws Exception {
Connection conn = null;
String strSql = "";
PreparedStatement ps = null;
try {
if ((docid == null) || (docid.length() == 0)) {
LG.error("文檔id缺失,不做入庫處理");
return;
}
Date dTime = new Date();
DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String saveTime = df.format(dTime);
strSql = "update OA_WordDocTable set FFilename=?,FFilesize=?,FFiledata=?,FUser=?,FTime=? where id="
+ docid;
conn = DataAccess.getDataSource().getConnection();
ps = conn.prepareStatement(strSql);
ps.setString(1, fileName);
ps.setInt(2, inStream.available());
ps.setBinaryStream(3, inStream, inStream.available());
ps.setString(4,userId);
ps.setString(5,saveTime);
ps.executeUpdate();
ps.close();
} catch (Exception e) {
LG.error("入庫失敗!");
e.printStackTrace();
return;
} finally {
if (ps != null) {
ps.close();
}
if (inStream != null) {
inStream.close();
}
}
}
}
(3)附加一個上傳圖片的小例子
package com.dz.action;
import java.io.DataOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.sql.Blob;
import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.ResultSet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.log4j.Logger;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.actions.DispatchAction;
import com.dz.common.util.JdbcUtil;
/**
* @desc: APEXSOFT_PROJECT
* @author: 黃堅
*/
public class DownImageAction extends DispatchAction {
private static final Logger LG = Logger.getLogger(DownImageAction.class);
public ActionForward execute(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response)
throws Exception {
String id = request.getParameter("id");
String column = request.getParameter("column");
String table = request.getParameter("table");
CallableStatement cstmt = null;
Connection con = null;
ResultSet rs = null;
InputStream in = null;
DataOutputStream fos = null;
OutputStream outp = null;// 不要關閉
try {
con = JdbcUtil.getDataSource(true).getConnection();
cstmt = con.prepareCall("select "+column+" from "+table+" where id ="+id);
rs = cstmt.executeQuery();
if (rs.next()) {
Blob blob = (Blob) rs.getBlob(1);// 備註:oracle 的blob轉換有區別
in = blob.getBinaryStream();// ****獲得流****
}
} catch (Exception e) {
LG.error(e);
e.printStackTrace();
return null;
} finally {
if (rs != null)
rs.close();
if (cstmt != null)
cstmt.close();
if (con != null)
con.close();
}
response.reset();// 可以加也可以不加
response.addHeader("Content-Disposition",
"inline;filename=123.jpg");
response.addHeader("Content-Encoding",
"identity");
response.setContentType("image/jpeg");
try {
outp = response.getOutputStream();
fos = new DataOutputStream(outp);
byte[] b = new byte[in.available()];
int i = 0;
while ((i = in.read(b)) > 0) {
fos.write(b, 0, i);
fos.flush();
}
return null;
} catch (Exception e) {
e.printStackTrace();
return null;
} finally {
if (in != null) {
in.close();
}
}
}
}