日期:2014-05-16  浏览次数:20404 次

JSP实现指定盘符路径下的图片显示

开发人员都知道<img src="">标签,只要src指定相应路径就能够显示图片,但是这里有一个限制条件:如果项目被部署在服务器上(比如Java web项目部署在tomcat下)运行时,src路径只能指定项目中的图片。比如<img src="/common/java.jpg">表示显示该项目下common目录下的名为java.jpg的图片。而如果你希望显示服务器某个盘符下的指定图片,比如<img src="c:\xxx\xx.jpg">,即使该目录下有指定图片,这样写也是找不到该图片的,因为出于安全性考虑不能读取当前项目以外的数据。

最近在做一个小项目玩,有个添加用户功能,我需要上传用户图片后在页面显示该用户图片。上传功能已实现,代码在这里可以看到:http://blessht.iteye.com/blog/1405057,为了防止图片丢失,我的图片是上传到硬盘指定目录下,现在的难题是如何把图片显示出来。

在网上看了很多解决方案,其中有一种方案我觉得很好:img标签的src不是图片路径,而是一个servlet请求,该servlet通过java代码读取图片并以流的形式将图片数据打印到页面,这样就能显示指定盘符下的图片了。

首先看下运行效果:




?

?

?

?

  • 实现说明
前面图显示很清楚:首先用户添加页面点击“上传”按钮显示上传界面,再指定相应图片点击上传,上传成功后关闭窗口并且将上传文件相应信息通过js回调函数的形式返回到父窗体。父窗体获取参数再通过jquery ajax的load方法加载一个jsp页面,该jsp页面实际只有一个<img>标签,用于显示图片,这样通过异步的形式就把指定图片找出来了。
首先是父窗体,用户添加页面的部分代码:
<script>

......

function openUpload_(){
	openUpload(null,'JPG,GIF,JPEG,PNG','5',callback);
}

/**
 * 回调函数,获取上传文件信息
 * realName真实文件名
 * saveName文件保存名
 * maxSize文件实际大小
 */
function callback(realName,saveName,maxSize){
	$("#photo_").val(saveName);
	$("#div_photo").load(root+"/showImage.jsp?saveName="+saveName+"&width_=200&height_=200");
}
</script>

......

<tr>
			<td>头像:</td>
			<td>
				<input type="hidden" name="photo" id="photo_"></input>
				<input type="button" onclick="openUpload_()" value="上传"/>
			</td>
		</tr>
		<tr>
			<td colspan="2">
				<div id="div_photo"></div>
			</td>
		</tr>
? 然后是showImage.jsp的代码
<body>
<%
	String root = request.getContextPath();
	String saveName = request.getParameter("saveName");
	String width_ = request.getParameter("width_");
	String height_ = request.getParameter("height_");
%>
<img src="<%=root%>/CommonController.jhtml?method=showImage&saveName=<%=saveName%>" width="<%=width_%>" height="<%=height_%>">
</body>
? 最后是CommonController类的showImage方法用于处理图片流数据:
/**
	 * 显示图片
	 * @param request
	 * @param response
	 * @return
	 * @throws ServletException
	 * @throws IOException
	 */
	public ModeAndView showImage(HttpServletRequest request,
			HttpServletResponse response) throws ServletException, IOException {
		String saveName = request.getParameter("saveName");
		
		FileInputStream hFile = new FileInputStream(fileUploadPro.getProperty("filePath")+saveName); // 以byte流的方式打开文件 d:\1.gif 
		int i=hFile.available(); //得到文件大小 
		byte data[]=new byte[i]; 
		hFile.read(data);  //读数据 
		response.setContentType("image/*"); //设置返回的文件类型 
		OutputStream toClient=response.getOutputStream(); //得到向客户端输出二进制数据的对象 
		toClient.write(data);  //输出数据 
		
		toClient.flush();
		toClient.close(); 
		hFile.close(); 
		return null;
	}
?
至此一个困扰我两天的问题终于解决了,目前还剩下一个错误就是:每次显示图片时会报一个错误:java.lang.IllegalStateException: getOutputStream() has already been called for this response,希望有解决方法的朋友指点一下,谢谢!另外还有什么好的办法,大家也可以分享一下!
注:目前上传显示图片在IE8下可用,其它浏览器不能保证。