formaction="/DrawingInputMultiAction"enctype="multipart/form-data">
fileproperty="drawingFile"/>
....省略
form>
控制层:
在Action中将传入的ActionForm中的文件字段赋给VO值对象,并调用业务代理类的上传方法。
核心代码:
//新增
if(actionType.equals("insert")){
//得到文件类型
intiFileType=this.getFileType(drawingInputForm.getFileExtendName());
if(iFileType==0){
//不支持文件类型
this.addError(request,"drawing.errors.upload.UnSupportedFileType");
}else{
DrawingVOobjDrawingVO=newDrawingVO();
//图纸基本属性
objDrawingVO.setDrawingName(drawingInputForm.getDrawingName());
...省略其他set方法
//执行新增(上传)
intiRt=objDrawingMan.insertDrawing(objDrawingVO);
...省略
}
Facade门面:
通过业务代理类调用DAO中的上传方法,对客户端完全透明。
publicintinsertDrawing(DrawingVOdrawingVO)throwsComtopModuleException{
try{
DrawingDAOdrawingDAO=newDrawingDAO();
returndrawingDAO.insertDrawing(drawingVO);
}catch(DrawingExceptionex){
thrownewComtopModuleException("drawing.errors.insert",ex);
}
}
持久层:
DAO中实现和ORACLE数据库的底层交涉,完成真正的文件上传。
需要先插入一个空BLOB对象,然后Update这个空对象。
publicintinsertDrawing(DrawingVOdrawingVO)throwsDrawingException{
PreparedStatementpstmt=null;
Statementstmt=null;
Connectionconn=null;
intiKey=0;
ResultSetrs=null;
//定义SQL语句
StringstrSQLInsert=null;
StringstrSQLUpdate=null;
try{
conn=dataSource.getConnection();
conn.setAutoCommit(false);
//插入空BLOB,empty_blob(),其中表中的Content是BLOC类型字段
strSQLInsert=
"insertintoPROD_DRAWING(DRAWING_ID,DRAWING_NAME,省略..."+
"CONTENT)"+
"values(?
?
省略...,empty_blob())";
//得到待处理文件
FormFiledrawingFile=drawingVO.getDrawingFile();
//插入普通字段
pstmt=conn.prepareStatement(strSQLInsert);
//得到主键
iKey=Toolkit.getInstance().getNextKey(DrawingInfo.ID_STORE_KEY_DRAWING);
pstmt.setInt(1,iKey);
....省略其他set方法
pstmt.executeUpdate();
stmt=conn.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,
ResultSet.CONCUR_UPDATABLE);
strSQLUpdate=
"SELECTCONTENTFROMPROD_DRAWINGWHEREDRAWING_ID='"+
iKey+"'"+"FORUPDATE";
//读出记录以增加图片Blob字段
rs=stmt.executeQuery(strSQLUpdate);
if(rs.next()){
logger.debug("开始写入BLOB");
//这里不能用oracle.sql.BLOB,会报ClassCast异常
weblogic.jdbc.vendor.oracle.OracleThinBlobblob=(weblogic.jdbc.vendor.
oracle.
OracleThinBlob)rs.getBlob
(1);
logger.debug("得到输出流");
OutputStreamoutStream=blob.getBinaryOutputStream();
InputStreamfin=drawingFile.getInputStream();
logger.debug("开始分配缓存");
byte[]b=newbyte[blob.getBufferSize()];
intlen=0;
while((len=fin.read(b))!
=-1){
logger.debug("正在写入BLOB流");
outStream.write(b,0,len);
}
logger.debug("关闭所有流");
fin.close();
outStream.flush();
outStream.close();
}
rs.close();
mit();
}catch(Exceptionex){
...省略
}finally{
DBUtil.destroyDB(rs,pstmt,conn);
}
returniKey;
}
2读取BLOB字段的流程
从数据库中读出BLOB数据没有上述由于连接池的不同带来的差异,程序流程同插入BLOB字段,但是读BLOB就不用那么复杂了,只需要J2SE的标准类java.sql.Blob就可以取得输出流。
DAO中的核心代码:
publicDrawingVOreadDrawing(intdrawingId)throwsDrawingException{
PreparedStatementpstmt=null;
Connectionconn=null;
DrawingVOobjDrawingVO=null;
ResultSetrs=null;
//定义SQL语句
StringstrSQL="SELECT*FROMPROD_DRAWINGWHEREDRAWING_ID=?
";
try{
conn=dataSource.getConnection();
pstmt=conn.prepareStatement(strSQL);
//设置参数
pstmt.setInt(1,drawingId);
//执行查询
rs=pstmt.executeQuery();
while(rs.next()){
objDrawingVO=newDrawingVO();
objDrawingVO.setDrawingId(rs.getInt("DRAWING_ID"));
objDrawingVO.setDrawingName(rs.getString("DRAWING_NAME"));
...省略其他set方法
//setBLOB到VO中
objDrawingVO.setContent(rs.getBlob("CONTENT"));
}
}catch(Exceptionex){
...省略
}finally{
DBUtil.destroyDB(rs,pstmt,conn);
}
returnobjDrawingVO;
}
这样,传到Action中VO对象就包含这个BLOB对象了,然后需要在Action中对该对象转为输入流,可以选择文件输出流或Servlet输出流,根据具体情况定,这里选择文件输出流。
核心代码:
privateStringgetBlobToFile(Blobblob,DrawingVOobjDrawingVO)throwsException{
InputStreamins=blob.getBinaryStream();
//用文件模拟输出流
StringstrFileName=objDrawingVO.getDrawingName()+"."+
objDrawingVO.getFileExtendName();
StringstrRootFilePath=this.getServlet().getServletContext().getRealPath("");
StringstrFilePath="/temp/"+strFileName;
StringcontextFilePath=strRootFilePath+strFilePath;
//定义文件对象
Filefile=newFile(this.getServlet().getServletContext().getRealPath("")+"/temp");
if(!
file.exists()){
file.mkdir();
}
//定义输出流
OutputStreamfout=newFileOutputStream(contextFilePath,true);
//下面将BLOB数据写入文件
byte[]b=newbyte[1024];
intlen=0;
while((len=ins.read(b))!
=-1){
fout.write(b,0,len);
}
//依次关闭
fout.close();
ins.close();
returnstrFilePath;
}
最后,在Action中调用这个私有方法,完成读取操作。
import java.io.*;
import java.sql.*;
public class BlobOperation
{
public static void addLob(long id, String binFile) throws SQLException
{
Connection con = null;
PreparedStatement ps = null;
ResultSet rs = null;
try
{
con = ConnectionFactory.getConnection(); //换成你自己取连接的方法
con.setAutoCommit(false);
String sql = "INSERT INTO Blob_Tbl(id, binfile, bincontent)";
sql += " VALUES(?
?
?
)";
ps = con.prepareStatement(sql);
ps.setLong(1, id);
ps.setString(2, binFile);
ps.setBlob(3, oracle.sql.BLOB.empty_lob());
ps.executeUpdate();
//DatabaseUtils.closeObject(ps);
ps = con.prepareStatement("SELECT bincontent FROM Blob_Tbl WHERE id = " + id + " for update ");
rs = ps.executeQuery();
if (rs.next())
{
oracle.sql.BLOB binContent = (oracle.sql.BLOB) rs.getBlob
(1);
/* write blob content */
OutputStream binOut = binContent.getBinaryOutputStream();
BufferedOutputStream out = new BufferedOutputStream(binOut);
BufferedInputStream in = new BufferedInputStream(new FileInputStream(binFile));
int c;
while ((c = in.read()) !
= -1)
{
out.write(c);
}
in.close();
out.close();
}
mit();
} catch (Exception e)
{
e.printStackTrace();
try
{
con.rollback();
} catch (SQLException se)
{
}
throw new SQLException(e.getMessage());
} finally
{
DatabaseUtils.closeObject(rs, ps, con);
}
}
public static void fetchLob(long id, String filename) throws SQLException
{
Connection con = null;
Statement st = null;
ResultSet rs = null;
try
{
con = ConnectionFactory.getConnection();
String sql = "SELECT * From Blob_Tbl Where id = " + id;
st = con.createStatement();
rs = st.executeQuery(sql);
while (rs.next())
{
String binFile = rs.getString("binfile");
oracle.sql.BLOB binContent = (oracle.sql.BLOB) rs.getBlob("bincontent");
/* read blob content */
BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream(filename));
BufferedInputStream in = new BufferedInputStream(binContent.getBinaryStream());
int c;
while ((c = in.read()) !
= -1)
{
out.write(c);
}
in.close();
out.close();
}
} catch (Exception e)
{
throw new SQLException(e.getMessage());
} finally
{
DatabaseUtils.closeObject(rs, st, con);
}
}
public static void main(String[] args) throws Exception
{
if (args.length == 0)
{
addLob(1, "a.jpg");
} else
{
fetchLob(1, args[0]);
}
}
}
packagecom.semovy.test;
importjava