系统很早存在一个上传的问题,主要涉及到的是与开源软件的jasper文件的集成.之前一直是在数据库客户端,通过for update的方式.后来进行了改进,采用的是jdbc的方式,同时该了一下hibernate的blob字段的映射配置,问题基本解决.说基本是因为不同服务器对blob字段的包装问题,具体:
向oracle写入blob数据时,如下:
oracle.sql.BLOB blob = (oracle.sql.BLOB) rs.getBlob(1);
BufferedOutputStream bos = new BufferedOutputStream(blob.getBinaryOutputStream());
bos.write(image);
在本地的tomcat服务器上上传没问题,
但是发布到weblogic上,使用weblogic的连接池,就抛错了,如下:
后来查了一下,原因是通过weblogic连接池取出的连接取出的blob对象是weblogic封装过的OracleThinBlob,而不是oracle.sql.BLOB。然后又看了一下OracleThinBlob的方法与oracle.sql.BLOB类似,所以采用了下面的写法,避免异常(用到的是泛型的解决方法):
if("0".equals(type)){//上传图片
String update_fmp = "update web_prn_fmp set c_image_name=?,b_image=? where c_prn_fmp = '" + prnFmp+"'";
String query_fmp = "select b_image from web_prn_fmp where c_prn_fmp = ? FOR UPDATE" ;
pstmt = conn.prepareStatement(update_fmp);
pstmt.setString(1,imageName);
pstmt.setString(2,"0");//初始化blob数据,否则后续的调用会出现空指针异常.
pstmt.executeUpdate();
pstmt.clearParameters();
pstmt = conn.prepareStatement(query_fmp);
pstmt.setString(1,prnFmp);
rs = pstmt.executeQuery();
if(rs.next())
{
// oracle.sql.BLOB b_image = (oracle.sql.BLOB) rs.getBlob("b_image");
// java.io.OutputStream writer = b_image.getBinaryOutputStream();//得到对应于数据库相应blob字段的输出流
// BufferedOutputStream out = new BufferedOutputStream(writer);
//tomcat和weblogic对blob字段进行了不同的包装,需使用如下的泛型方案代码 zengshaotao 2011-03-14
Object obj = rs.getBlob("b_image");
Class clazz = obj.getClass();
Method method = clazz.getMethod("getBinaryOutputStream", new Class[]{});
OutputStream os = (OutputStream)method.invoke(obj, new Object[]{});
BufferedOutputStream out = new BufferedOutputStream(os);
out.write(image);
rs.close();
//writer.close();
out.close();
conn.commit();
conn.setAutoCommit(true);//恢复现场
}else{
throw new Exception("没有得到与给定的单证格式代码相应的记录!");
}
}