基于SSH的图片上传与下载的实例

图片的上传,一般是将图片的路径或图片名保存在数据库中,而不是把图片直接保存在数据库中。下载的时候也是先通过路径来查找图片是否存在再下载。

后台Form(在本例中为CertificateInfoForm)代码:

 private String  cer_picture ;   //图片名,保存于数据库中。
 private FormFile picture_path; //用于在页面上获取文件的路径以及将图片以流的形式进行保存

//省略get、set方法。

前台JSP代码:

<td width="16%" class="edit_content">
		证书图片:
</td>
<td width="33%" class="edit_content_text" colspan="3">
	<input type="file" name="picture_path" οnkeydοwn="return false;" class="input_text" />
</td>

这个JSP页面有一个地方需要提醒一下,一般新手都会碰到一个“argument type mismatch”的问题,那是因为如果提交的表单中有图片或者其他文件,则需要在form中添加enctype="multipart/form-data",如:

<html:form action="/certificate_info/certificateinfo.do?method=showCertificateInfo" method="post" enctype="multipart/form-data">
	

上传图片重要的一点就是要将图片以流的形式保存在本地服务器上。

后台Action代码:

CertificateInfoForm beanForm = (CertificateInfoForm) form;
		CertificateInfo certificateInfo =  new CertificateInfo();
		//使用反射将form的值赋给bean
		BeanFormConvertor.formToBean(certificateInfo,beanForm);
		FormFile file = beanForm.getPicture_path();
		String fileName = "";
		if(file!=null&&!"".equals(file.getFileName())){
			fileName = file.getFileName();
			String operator = ((PrivilegeUserregister)request.getSession().getAttribute("user")).getOperator();
			fileName = certificateInfoService.getFileNameByOperatorAndTimestamp(operator, fileName);//上一行与本行的作用是对图片名进行重命名
			String newDir = servlet.getServletContext().getRealPath("/certificate_info/uploadFile/");
			String path = "";
			//路径不存在的话,就先创建。
			if(!(new File(newDir)).isDirectory()){
				new File(newDir).mkdir();
				path = servlet.getServletContext().getRealPath("/certificate_info/uploadFile/") + "\\"+ fileName;
			}else{
				path = servlet.getServletContext().getRealPath("/certificate_info/uploadFile/") + "\\"+ fileName;
			}
			certificateInfoService.uploadFile(file, path);
			//将
			certificateInfo.setCer_picture(fileName);
			
		}
		certificateInfoService.addCertificateInfo(certificateInfo);
以上代码所做的事有:对文件进行重命名、判断路径是否存在,不存在还得先创建好文件夹、保存文件(图片)、将页面上传的图片的名字赋值给cer_picture,保存于数据库中。

对文件进行重命名,依个人需求而定。第一次上传图片,文件夹并没有存在,于是要先创建好文件夹,此后上传图片后就不用再次创建文件夹。

保存图片的uploadFile方法的代码如下:

public void uploadFile(FormFile file, String path) {
		InputStream is = null;
		OutputStream os = null;
		try {
			is = file.getInputStream();
			os = new FileOutputStream(path);
			byte[] content = new byte[file.getFileSize()];
			while(is.read(content)!=-1){
				os.write(content);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}finally{
			if(is!=null){
				try {
					is.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
			if(os!=null){
				try {
					os.close();
				} catch (Exception e2) {
					e2.printStackTrace();
				}
			}
		}
		
	}

至此,图片的上传基本解决。接下来说下,图片下载的问题。

图片下载,一般都会给定一个链接,然后根据ID查找此图片的路径,再判断图片是否存在。我这里简单地用到了dwr,一个Ajax的框架。

JSP页面代码 :

<tr>
						<td width="16%" class="edit_content">
							证书图片:
						</td>
						<td width="33%" class="edit_content_text" colspan="3">
							<a href="#" οnclick="return downloadAttachment(${certificateInfo.id});return false;">
								<c:out value="${certificateInfo.cer_picture}" escapeXml="true" />
								<input type="hidden" name="uploadFilePath" value="<%=session.getServletContext().getRealPath("/certificate_info/uploadFile/") %>"/>
							</a>
						</td>
					</tr>
从这里可以看出来,为什么我只保存图片的名字而不是路径加名字,因为下载的时候,会从页面上将路径传到后台。

这里可以看下JS中downloadAttachment方法的代码:

 var selectId = "";
  	 function downloadAttachment(id){
  	 	
			selectId = id;
			var uploadFilePath = document.getElementById("uploadFilePath").value;
			//checkFileIsExit返回的是一个boolean型,同时调用result函数。
			certificateInfoService.checkFileIsExist(uploadFilePath,selectId,result);
			return false;
		}
顺便在此贴出JS中的result方法的代码:

function result(rel){
			//附件存在
			if(rel){
				window.location.href="<%=request.getContextPath()%>/certificate_info/certificateinfo.do?method=downloadAttachment&id="+selectId;
			}else{
				alert("对不起,你所请求的附件不存在!");
			}
		}


在downloadAttachment方法中可以看到,此方法直接调用了后台service中的checkFileIsExist方法。如何做到这一点呢,那是因为使用了我之前说的DWR。

在dwr文件中只需简单的配置即可。

<dwr>
<allow>
<!-- 证书信息  -->
		<create creator="spring" javascript="certificateInfoService">
		    <param name="beanName" value="certificateInfoService" />
		    <include method="checkFileIsExist" />
		</create>
	</allow>
</dwr>

在JS中调用到后台中的哪个方法就进行配置,当然<include/>可以包含多个,即一个JS方法中调用了多个后台中的方法。

然后,在JSP中还需添加:

<script type='text/javascript' src='<%=request.getContextPath()%>/dwr/interface/certificateInfoService.js'></script>
不然,会出现你所调用的方法没有定义的异常。

这样配置好DWR之后,downloadAttachment就可以直接调用checkFileIsExist方法了。在后台中其实现代码如下:

public boolean checkFileIsExist(String uploadFilePath, String id) {
		CertificateInfo bean = certificateInfoDAO.findCertificateInfo(Integer.parseInt(id));
		if(bean.getCer_picture()!=null&&!bean.getCer_picture().trim().equals("")){
			String path = uploadFilePath+"\\"+bean.getCer_picture();
			
			File file = new File(path);
			if (file.exists()) {
				System.out.println("0000");
				return true;
			} else {
				return false;
			}
		}else{
			return false;
		}
	}
以上代码很容易理解,就是找到路径及图片名字,再调用File的exists方法就可以判断文件是否存在了。

上面说过,执行完downloadAttachment会调用 result方法,这样就可以直接进行图片的下载了。

可以看下后台的downloadAttachment的代码:

CertificateInfo bean = certificateInfoDAO.findCertificateInfo(Integer.parseInt(id));
		String attachment = bean.getCer_picture();
		FileInputStream fis = null;
		OutputStream os = null;
		
		try {
        	response.setContentType("application/x-msdownload");
			response.setHeader("Content-Disposition","attachment;" + " filename="+ new String(attachment.getBytes(), "iso-8859-1"));
			String path = servlet.getServletContext().getRealPath("/certificate_info/uploadFile/")+"\\"+attachment;
			fis = new FileInputStream(path);
			os = response.getOutputStream();
			byte[] b = new byte[1024];
			int leng;
			while((leng=fis.read(b)) != -1){
				os.write(b, 0, leng);
			}
		} catch (Exception e) {
			e.printStackTrace();
	}finally {  
        if (fis != null) {
            try {
            	fis.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        if (os != null) {
            try {
            	os.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
	 }
setContentType()是告诉浏览器此文件是纯下载方式(另外有在线打开方式),setHeader中设置了文件类型的后缀名、文件名以及防止图片出现乱码进行了编码设置。

之后就是再读取图片,以流的形式进行下载。这样,图片的下载也实现了。


另外,在更新的时候,有时也会更换图片,但是在更新页面回显的时候,不仅需要显示图片的名字或路径,还需要有图片上传的选择框。这样,如果对于图片没有更改,那么再次点击提交的时候,就会发现,图片不存在了。原因是显而易见的。本人愚笨,想了一个比较笨的方法,具体代码不贴出来了,只说下自己的思路。

在回显的时候,将已存入的图片名或路径用一个隐藏域赋值给一个属性,然后在后台再接收到这个属性的值。接着再判断页面上的图片File是否存在,如果存在则表示图片已更换,如果不存在,则将之前的图片名再次存入至数据库中。这样就可以解决了。。

虽然方法有点笨拙,但好歹也解决了问题。望大神能提供更好的方法。。


另:本文中有说得不好的地方,望各位指出来。在下不甚感激。








  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值