打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
CMS项目总结:18、文件上传commons

commons-fileupload包依赖于commons-io

<form action="ArticleServlet" method="post" enctype="multipart/form-data">     涉及到上传文件一定要在form中定义enctype="multipart/form-data">,并且method=post

<input type="file" name="attachs" id="attachs">    类型叫file。    在定义enctype=multipart/form-data”后即使是普通的表单域也不能通过request.getParameter()来获取。

由于原先的代码中已经使用了很多的request.getParameter()方法,所以不适合改动所有的这个方法,我们需要想个新技巧来在不改动或者很少改动原先代码的情况下实现文件上传的功能。

 

实际上HttpServletRequest是个interface,所以在doPostdoGet那些方法中用的肯定不是HttpServletRequest的实例(因为接口是没有实例的),那里的request是接口的某个具体实现,这个实现是由容器tomcat自动创建的,实际上调用的是RequestFacade(实现了HttpServletRequest接口的类,多态)

现在如果上传的form中有fileenctype="multipart/form-data">先在BaseServlet(访问各种ArticleServletChannelServlet的入口)中用MultipartRequestWrap中的request代替原先的request,待会儿在仔细的研究关于具体MultipartRequestWrap,代替的代码如下:

boolean isMultipart = ServletFileUpload.isMultipartContent(request);判断request是否是multipart类型,如果是的话request = new MultipartRequestWrapper(request);MultipartRequestWrapper中的request来替换原先的requestRequestFacade)。

关于用MultipartRequestWrapper代替RequestFacade,是用到了Decorator设计模式。

HttpServletRequestWrapper没有默认的无参的构造方法

还需要创建Attachment(附件)的Bean类,同时添加到ArticleBean中:

以及在数据库中创建attachmenttable

接下来进入正题:

1分析MultipartRequestWrap的代码:

在MultipartRequestWrapper中实现了request的多态替换,原有的代码不需要改动就能继续使用request.getParameter()request.getParameterMap()。(不替换前如果form中有文件上传,那么request.getParameter()request.getParameterMap()方法是不能用的)。这段代码就不逐行分析了,将来用的时候在看吧,不难。

表单域中可能存在同名name的(譬如多选的下拉选择框,当选中多个时(相同的name)),这时就用到

这段代码。

Attachment数据放入request的代码:

2、Attachment插入Article中;

ArticleServlet中添加的代码:

我们原先是这么实现的:

为了往Article中添加一些Attachment,在ArticleServlet中创建List,再调用setAttachment()。而更好的实现应该是:

避免了在ArticleServlet中做复杂的操作,同时在ArticleServlet中不需要知道attachments是个List还是Set……。好处还有可以由Article决定如何添加Attachment注意这里有个GRASP模式(GRASP模式中的专家模式,专家模式:一个职责应该放在具有这个职责所需信息的类中,往Article中添加Attachment的职责应该放在具有AttachmentArticle类中。)

3、添加文章时往数据库中填充t_attachment表中的字段,删除文章时将文章对应的附件信息从t_attachment表中删除

1、在ArticleDaoForMyBatisImpl中添加文章(及附件)的代码:

在Article.xml中插入t_attachment的代码:

2、在ArticleDaoForMyBatisImpl中删除文章(及附件)的代码:

由于删除文章的同时删除附件,所以我们需要根据aritcle的id来找出article,再找出attachmentschannels,原本可以再单独调用findAttachmentByArticle,但是我们用了这种resultMap的简便办法,通过一次调用Article a = (Article) session.selectOne(Article.class.getName()+".findById", articleId);就根据articleid字段取出t_channelst_attachments表中的相关数据,放到Articlechannelsattachments属性中。

附件的在硬盘中的存储信息是放在t_attachment中的,所以我们根据List attachments = a.getAttachments();取出文章的信息,然后调用new File(realPath).delete();删除硬盘中的附件信息。最后再

//删除数据库中的相关记录

session.delete(Article.class.getName() + ".del_attachments_by_articleId", articleId);

//删除文章

session.delete(Article.class.getName()+".del", articleId);

注意顺序一定要对,先删了硬盘的数据,再删数据库中的t_attachment,最后再删t_article中的数据,先删对象的关联,再删对象自己。(因为如果先删了t_attachment,就找不到附件存储在硬盘的地址信息了,先删t_article,那么就没有articleid了,也不好删t_attachment了)。

3、ArticleDaoForMyBatisImpl中不删文章,只是单独删除附件:

ArticleServlet中删除附件的代码:

ArticleDaoForMyBatisImpl中的代码:

Article.xml文件中的代码:

本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
自由动力3.6版90个问答-4
前端教程:DjangoURL映射
浅谈C#中的延迟加载(2)——善用virtual
简化JavaMail:小巧 Jakarta Commons-Email 简单教程
丢手绢找朋友
http://www.jscsedu.com/Article/ShowArticle.asp?ArticleID=79
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服