最近项目中遇到将照片信息存入调用webservice访问的其它项目指定的数据库中,解决方法如下:
上传: 前台选择照片后点击上传按钮,调用后台,生成File 类型 最后形成流的方式调用数据库,存入数据库 ,照片存入oracle数据库中是以BLOB类型存储的,
关键代码:protected void doPost(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
logger.info("服务层操作:图片上传 ImageFileUpload类 doPost方法 ");
WebApplicationContext wac =
WebApplicationContextUtils.getRequiredWebApplicationContext(getServletContext());
this.uploadImage = (UploadImage)wac.getBean("uploadImage");
boolean isMultipart = ServletFileUpload.isMultipartContent(request);
if (isMultipart) {
FileItemFactory factory = new DiskFileItemFactory();
ServletFileUpload upload = new ServletFileUpload(factory);
Iterator items;
try {
items = upload.parseRequest(request).iterator();
while (items.hasNext()) {
FileItem item = (FileItem) items.next();
if (!item.isFormField()) {
String name = item.getName();
String fileName = name.substring(
name.lastIndexOf('\\') + 1, name.length());
// web绝对路径
String path = request.getSession().getServletContext()
.getRealPath("/");
path = path + fileName;
File uploadedFile = new File(path);
item.write(uploadedFile);//上传到jboss部署的medicalRes.war下面
// InputStream photoStream = new FileInputStream(
// uploadedFile);
UpdateMessage message = uploadImage.add(uploadedFile);
response.setContentType("text/html");
response.setCharacterEncoding("GBK");
PrintWriter out = response.getWriter();
out.print("filename=" + message.getCode());
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
public UpdateMessage add(File file) {
UpdateMessage message = null;
String pid = this.createPid();
try {
if (file == null) {
throw new ServiceException(
ServiceExceptionType.TYPE_PARAM_NULL, "添加时被添加的数据对象不能为空");
}
String mappingSQL = "INSERT INTO MRR_SERVICE_IMAGE ( HR99_00_007 , HR99_00_008) "
+ "VALUES (?,?)";
List<Parameter> parameterList = new ArrayList<Parameter>();
int i = 1;
parameterList.add(new Parameter(i++, pid));
//SerializableBlob blob = (SerializableBlob)entity.getUserphoto();
// BLOB blob2 = (BLOB) blob.getWrappedBlob();
parameterList.add(new Parameter(i++, file));
message = this.addByHial(mappingSQL, parameterList);
message.setDesc("医务人员照片信息添加操作已成功提交!");
message.setCode(pid);
} catch (MRException e) {
if (message == null) {
message = new UpdateMessage();
}
message.setCode(e.getErrorCode());
message.setDesc(e.getMessage());
}
return message;
}
public int executeUpdate(String dummySql, Object[] args)
throws HIALException {
try {
if (StringUtil.isEmpty(dummySql)) {
throw new ExecuteException("执行组建中的参数SQL不能为空。");
}
if (args == null) {
throw new ExecuteException("执行组建中的参数args不能为空。");
} else {
if (args == null) {
args = new Object[] {};
}
for (Object o : args) {
if (o == null) {
throw new ExecuteException("执行组建中的参数Object[]不连续。");
}
}
}
SQLCacheObject sqlCache = translator.translate(dummySql);
String tSQL = sqlCache.getRealSQL();
int result = -1;
//NOTES:根据所修改的表判断是否需要修改参数 BY: 2012-11-15
if(tSQL.indexOf("T_IRR_IMAGE")>0){
File file = (File) args[1];
Connection con = null;
PreparedStatement pstmt = null;
try {
InputStream photoStream = new FileInputStream(file);
ApplicationContext ac = new FileSystemXmlApplicationContext("classpath:com/xbzc/hial/config/atomikosConfig.xml");
DriverManagerDataSource docstoreDS = (DriverManagerDataSource)ac.getBean("irrDS");
con = docstoreDS.getConnection();
pstmt = null;
//String sql = "INSERT INTO t_irr_image (PID,userphoto) VALUES (?,?)";
pstmt = con.prepareStatement(tSQL);
pstmt.setString(1, (String) args[0]);
pstmt.setBinaryStream(2, photoStream,(int) file.length());
result = pstmt.executeUpdate();
pstmt.close();
con.close();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}finally{
if (pstmt != null) {
try {
pstmt.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (con != null) {
try {
con.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}else{
/* NOTES: zhangjun*/
String grantid = sqlCache.getDb();
String password = sqlCache.getPwd();
JdbcTemplate jdbcTemplate = findJdbcTemplate(grantid, password);
//int result = -1;
if (jdbcTemplate != null) {
result = jdbcTemplate.update(tSQL, args);
} else {
throw new ExecuteException("数据库访问账号或密码错误。");
}
}
return result;
} catch (DataAccessException e) {
throw new ExecuteException(e);
}
}
上面的关键代码: pstmt.setBinaryStream(2, photoStream,(int) file.length());
保存结束.
下载以及展现的部分代码:
protected void doGet(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
logger.info("服务层操作:图片下载 ImageFileDown doPost方法 ");
WebApplicationContext wac =
WebApplicationContextUtils.getRequiredWebApplicationContext(getServletContext());
this.uploadImage = (UploadImage)wac.getBean("uploadImage");
BufferedOutputStream bos = null;
String photoId = request.getParameter("photoId");
try {
TUmPhoto tUmPhoto = new TUmPhoto();
tUmPhoto.setPid(photoId);
QueryMessage message = uploadImage.query(tUmPhoto, null);
List list = message.getList();
byte []by = (byte[]) list.get(0);
// 利用这个输出流可以将数据返回到客户端
bos = new BufferedOutputStream(response.getOutputStream());
InputStream ins = new ByteArrayInputStream(by);
byte[] buf = new byte[1024];
int len = 0;
while ((len = ins.read(buf)) != -1) {
bos.write(buf, 0, len);
}
ins.close();
} catch (final IOException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
} finally {
if (bos != null) {
bos.flush();
bos.close();
bos = null;
}
}
//刷新或关闭的方法被调用时。所有数据缓冲区的信息将会被发送到客户端
response.flushBuffer();
}
================================================================================
public QueryMessage query(TUmPhoto entity, PagingVO paging) {
QueryMessage message = null;
try {
if (entity == null) {
throw new ServiceException(
ServiceExceptionType.TYPE_PARAM_NULL, "查询数据时查询数据对象不能为空");
}
String mappingSQL = "SELECT HR99_00_008 FROM MRR_SERVICE_IMAGE WHERE 1=1 ";
List<Parameter> parameterList = new ArrayList<Parameter>();
int i = 1;
if (StringUtil.notEmpty(entity.getPid())) {
mappingSQL += " AND HR99_00_007 = ? ";
parameterList.add(new Parameter(i++, entity.getPid()));
}
List<Map<String, Object>> resultList = this.queryByHial(mappingSQL,
paging, parameterList);
List<Object> list = new ArrayList<Object>();
for (Map<String, Object> map : resultList) {
byte []bb = (byte[]) map.get("userphoto");
list.add(bb);
}
message = new QueryMessage();
message.setList(list);
} catch (MRException e) {
if (message == null) {
message = new QueryMessage();
}
message.setCode(e.getErrorCode());
message.setDesc(e.getMessage());
}
return message;
}
HIAL端部分代码:
List<Map<String, Object>> result = new ArrayList();
BLOB blob = null;
byte[] data = null;
// NOTES:根据所修改的表判断是否需要修改参数 BY: 2012-11-15
if (tSQL.indexOf("T_IRR_IMAGE") > 0) {
String photoId = (String) args[0];
Connection con = null;
PreparedStatement pstmt = null;
ResultSet rs = null;
try {
ApplicationContext ac = new FileSystemXmlApplicationContext(
"classpath:com/xbzc/hial/config/atomikosConfig.xml");
DriverManagerDataSource docstoreDS = (DriverManagerDataSource) ac
.getBean("irrDS");
con = docstoreDS.getConnection();
pstmt = null;
pstmt = con.prepareStatement(tSQL);
pstmt.setString(1, photoId);
rs = pstmt.executeQuery();
if (rs.next()) {
blob = (BLOB) rs.getBlob("HR99_00_008");
InputStream inStream = blob.getBinaryStream();
try {
long nLen = blob.length();
int nSize = (int) nLen;
data = new byte[nSize];
inStream.read(data);
inStream.close();
} catch (IOException e) {
System.out.println("获取图片数据失败,原因:" + e.getMessage());
}
}
Map map = new HashMap();
map.put("userphoto", data);
result.add(map);
} catch (Exception e) {
e.printStackTrace();
} finally {
if (rs != null) {
try {
rs.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (pstmt != null) {
try {
pstmt.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (con != null) {
try {
con.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
返回的data是个二进制流.
知识扩展:public abstract class ServletOutputStream extends OutputStream
这是一个由Servlet引擎使用的抽象类。Servlet通过使用ServletResponse接口的使用获得了对一个这种类型的对象的说明。利用这个输出流可以将数据返回到客户端。
这个类的子类必须提供一个向OutputStream接口写入有关信息的方法。
在这个接口中,当一个刷新或关闭的方法被调用时。所有数据缓冲区的信息将会被发送到客户端,也就是说响应被提交了。请注意,关闭这种类型的对象时不一定要关闭隐含的socket流。
发送到客户端之后: flex前台的执行使用了 Bitmap , URLStream ,FileReference 等.
注意: 下载时,从数据库拿出来后是通过流的方式read到byte数组的:
if (rs.next()) {
blob = (BLOB) rs.getBlob("HR99_00_008");
InputStream inStream = blob.getBinaryStream();
try {
long nLen = blob.length();
int nSize = (int) nLen;
data = new byte[nSize];
inStream.read(data);
inStream.close();
} catch (IOException e) {
System.out.println("获取图片数据失败,原因:" + e.getMessage());
}
}
,然后再从byte数组中拿出通过流的方式传递给客户端:(部分代码)
bos = new BufferedOutputStream(response.getOutputStream());
InputStream ins = new ByteArrayInputStream(by);
byte[] buf = new byte[1024];
int len = 0;
while ((len = ins.read(buf)) != -1) {
bos.write(buf, 0, len);
}