1.服务端代码
服务端代码从Oracle中读出Blob数据,使用BASE64算法编码,BASE64编码将数据按6位分组,转化为2^6共64个字符(A..Z,0..9和其他字符等),关于编码的具体细节,可以查阅相关资料。这里需要注意的是当数据库查不到图片的时候,处于数据冗余考虑,我们希望用一张存放在服务器上的默认图片来代替,而不采用在每条记录插入默认BLOB数据;这张默认图片同样需要采用BASE64算法编码,并传送给服务调用端。要注意的问题是关于图片的相对路径如何定位。
/* -----------------------*
* 处理照片数据
* -----------------------*/
BASE64Encoder encoder = new BASE64Encoder();
InputStream is = null;
ByteArrayOutputStream baos = new ByteArrayOutputStream();
String picData = "";
Blob pic = ent.getZp0000();//
try{
//图片文件为空的时候,使用默认图片代替,在普通的Java类中访问服务器的图片,
//其相对路径要使用类装载器来定位
if(null==pic || pic.length()<2L){
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
if (classLoader == null) {
classLoader = WsLocationConfig.class.getClassLoader();
}
is = classLoader.getResourceAsStream("no_pic.jpg");
int c = 0;
while((c=is.read())!=-1){
baos.write(c);
}
byte[] buff = baos.toByteArray();
picData = encoder.encode(buff);
System.out.println(picData);
}else{
byte[] buff = pic.getBytes(1L, new Long(pic.length()).intValue());
picData = encoder.encode(buff);
System.out.println(picData);
}
}catch(SQLException e){
System.out.println(e.getMessage());
e.printStackTrace();
}catch(FileNotFoundException e){
System.out.println(e.getMessage());
e.printStackTrace();
}catch(IOException e){
System.out.println(e.getMessage());
e.printStackTrace();
}
reXML.append("<?xml version=\"1.0\" encoding=\"GBK\"?>");
reXML.append("<person>");
reXML.append("<picture>").append(picData).append("</picture>");
reXML.append("</person>");
return reXML.toString();
这段代码将Blob数据转化为byte[]数组,并使用BASE64Encoder 编码,将编码后的字符串组合到XML中以便传送。
2.调用端代码
调用端代码其实和普通的服务调用相同,只是将服务器的图像编码解码,得到byte[],并将这些数据存储到上下文,供图片解析Servlet来处理。为什么要将图片存储到上下文?因为图片不是从本地数据库读取,它只是以字节数据的形式临时存储到本地服务器内存中,可能的做法是给它生成一个文件存储到硬盘,但这样要频繁操作IO,而且相对路径难以处理,存储到上下文也许是比较好的选择,当然,你可能需要控制图片的数据量,对于正常的业务,这种做法已经可以承受大部分的需求了。
/* ----------------------------*
* 图片处理
* ----------------------------*/
String picData = foo.elementText("picture");
String key = foo.elementText("idcard");
BASE64Decoder decoder=new BASE64Decoder();
byte[] data=decoder.decodeBuffer(picData);
PictureMap pcm = new PictureMap(key,data);
String html = htmlBuffer.toString();
xml.setHtml(html);
xml.setPicutre(pcm); //PictureMap是存储了图片的key值和byte[]图片数据的HashMap名-值对
//将图片放到上下文
request.getSession().setAttribute("picture", xml.getPicutre().getPictureMap());
============================
3.图片显示
通过Servlet从上下文取出图片数据,并输出到前台
import java.io.IOException;
import java.util.HashMap;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class ReadXmlPicture extends HttpServlet{
private static final long serialVersionUID = 1L;
public void init(){
}
public void doGet( HttpServletRequest req, HttpServletResponse res)
throws ServletException, IOException {
HashMap map = null;
byte[] pic = null;
ServletOutputStream picDataToFront = null; //要输出的图片流
String key = req.getParameter("cid");//根据身份证查询
map = (HashMap)req.getSession().getAttribute("picture");
if(null==map){
return;
}
try{
pic = (byte[]) map.get(key); //取得照片
res.setContentType("image/jpeg");
picDataToFront=res.getOutputStream(); //获取输出流
for (int i = 0; i < pic.length; i++) {
picDataToFront.write(pic[i]); //输出到页面
}
picDataToFront.close(); //关闭输出流
}catch(IOException ioe){
System.out.println(ioe.getMessage());
ioe.printStackTrace();
}
}
public void doPost(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException{
doGet(req,res);
}
public void destroy(){
}
}
这样,就可以实现Web Services远程调用的图片传输了。


没有评论:
发表评论