最近项目中遇到将照片信息存入调用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); }