1.Struts文件上传

在Web开发中,会经常涉及到文件的上传和下载,比如在注册账户的时候,我们需要上传自己的头像等。 
我们可以利用Struts很方便地实现文件的上传。

1.1 开发步骤

现在,假设我们要在注册的时候上传自己的头像。新建项目名称为StrutsFileUpAndDown,并引入Struts1.3

(1)首先,写注册的JSP页面register.jsp 
它的body内容如下:

  1. <body>
  2. <h1>注册用户</h1>
  3. <% --如果表单有文件控件,则需要重新指定表单的编码方式 --%>
  4. <form enctype="multipart/form-data" action="/StrutsFileUpAndDown/register.do" method="post">
  5. 名字:<input type="text" name="name" /><br>
  6. 头像:<input type="file" name="photo" /><br>
  7. <input type="submit" value="注册" />
  8. </form>
  9. </body>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 这里使用普通的HTML标签来写表单。一定要注意加上form的enctype属性,并且内容为”multipart/form-data”
  • 这里必须使用post方法提交,get方法会出错
  • action的地址刚开始的时候可以先空着,后面有了Action之后,再补上去。这里我的Action的path为”/register”

(2)添加对应的ActionForm,名字为UserForm

  1. public class UserForm extends ActionForm {
  2. private String name = null;
  3. private FormFile photo = null;
  4. public String getName() {
  5. return name;
  6. }
  7. public void setName(String name) {
  8. this.name = name;
  9. }
  10. public FormFile getPhoto() {
  11. return photo;
  12. }
  13. public void setPhoto(FormFile photo) {
  14. this.photo = photo;
  15. }
  16. }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 要知道的是,JSP中的文件控件对应的是FormFile对象,该对象由Struts框架提供。

(2)添加对应的Action,名字为RegisterAction,并配置path为/register 
最关键的地方就在于Action是怎么写的,我们点击注册之后,是由Action来处理这个逻辑的,文件也就是通过这个Action传上来的。

  • 首先我们要得到UserForm中的内容:
  1. UserForm userForm = (UserForm) form;
  2. String username = userForm.getName();
  3. FormFile formFile = userForm.getPhoto();
  • 1
  • 2
  • 3
  • 接着,我们保存文件,FormFile对象有getInputStream()方法可以得到文件的输入流。此时我们还需要一个输出流OutputStream,用于将输入流拿到的东西通过输出流保存到服务器的磁盘。但要注意输出流的输出路径是Tomcat下的绝对路径
  1. // 文件名称
  2. String fileName = formFile.getFileName();
  3. // 获取输入流
  4. InputStream is = formFile.getInputStream();
  5. // 得到一个输出流
  6. // 首先得到file文件夹上传到Tomcat服务器后的绝对路径
  7. String path = request.getServletContext().getRealPath("file");
  8. OutputStream os = new FileOutputStream(path + "\\" + fileName);
  9. // 读取文件并写出到服务器file文件夹下
  10. int len = 0;
  11. // 做一个缓存
  12. byte[] bytes = new byte[1024];
  13. // 循环处理
  14. while ((len = is.read(bytes)) > 0) {
  15. // 读一点,写一点
  16. os.write(bytes, 0, len);
  17. }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

当然,这整个过程要处理异常。如果不出错的话,我们就可以将文件上传给服务器了。

【注意,这里省略一些简单的配置步骤】

1.2 改进

(1)问题1:中文乱码的处理,如果用户上传的文件是中文名称会出现乱码

此时,过滤器可以很好地解决这个问题。只需要加上一个过滤器,将request的编码设置为utf-8即可。

  1. public class EncodingFilter implements Filter {
  2. @Override
  3. public void destroy() {
  4. }
  5. @Override
  6. public void doFilter(ServletRequest arg0, ServletResponse arg1,
  7. FilterChain arg2) throws IOException, ServletException {
  8. arg0.setCharacterEncoding("utf-8");
  9. arg2.doFilter(arg0, arg1);
  10. }
  11. @Override
  12. public void init(FilterConfig arg0) throws ServletException {
  13. }
  14. }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

配置如下:

  1. <filter>
  2. <filter-name>EncodingFilter</filter-name>
  3. <filter-class>com.gavin.filter.EncodingFilter</filter-class>
  4. </filter>
  5. <filter-mapping>
  6. <filter-name>EncodingFilter</filter-name>
  7. <url-pattern>/*</url-pattern>
  8. </filter-mapping>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

(2)问题2:这里我们保存在服务器的文件名称是用户上传的名称,那么如果有两个用户上传的文件名称一样就会出现覆盖的情况,所以我们要在服务器端进行文件名的处理

这里,我们不再使用用户上传的文件的名称。那么又怎么样才能保证文件名的唯一呢?

  • 1.一种方法是以当前的时间(年+月+日+时+分+秒+毫秒)作为文件的名称
  • 2.另外,可以直接使用java.util.UUID类,UUID不会重复,这种方法最为简单。
  1. String uuid = UUID.randomUUID().toString();
  • 1
  • 3.当然,使用UUID之后,还要加上原来文件的后缀才行,所以干脆写一个工具类:
  1. public class MyTools {
  2. /**
  3. * 得到文件后缀
  4. * @param fileName
  5. * @return
  6. */
  7. public static String getFileSuffix(String fileName) {
  8. return fileName.substring(fileName.lastIndexOf("."));
  9. }
  10. /**
  11. * 得到UUID
  12. * @return
  13. */
  14. public static String getUUID(){
  15. String uuid = UUID.randomUUID().toString();
  16. return uuid;
  17. }
  18. }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

(3)问题3:如果用户上传的不是图片怎么办?如果用户上传的图片太大了怎么办?

所以这里我们要进行文件的限制,要进行文件的类型和大小的限制,如果不符合要求,则跳转至一个错误页面并给出提示: 
这里我限制文件的大小上限为10MB,如下:

  1. if (fileSize > 10 * 1024 * 1024) {
  2. request.setAttribute("error", "文件大小不能超过10MB!");
  3. return mapping.findForward("error");
  4. }
  5. if(!formFile.getContentType().startsWith("image/")){
  6. request.setAttribute("error", "文件格式有错,请检查!");
  7. return mapping.findForward("error");
  8. }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

【注意】文件的类型是不是图片,不是通过后缀名来判断的,要调用FormFile的方法,具体的文件类型你可以查看Tomcat安装目录下的conf文件夹下的web.xml文件中的配置。

所以,最后,一个完整的RegisterAction是这样的:

  1. public class RegisterAction extends Action {
  2. public ActionForward execute(ActionMapping mapping, ActionForm form,
  3. HttpServletRequest request, HttpServletResponse response) {
  4. UserForm userForm = (UserForm) form;
  5. String username = userForm.getName();
  6. FormFile formFile = userForm.getPhoto();
  7. // 通过FormFile我们可以获取关于用户上传文件的各种信息,比如大小,名字等
  8. String fileName = formFile.getFileName();
  9. int fileSize = formFile.getFileSize();
  10. if (fileSize > 10 * 1024 * 1024) {
  11. request.setAttribute("error", "文件大小不能超过10MB!");
  12. return mapping.findForward("error");
  13. }
  14. if(!formFile.getContentType().startsWith("image/")){
  15. request.setAttribute("error", "文件格式有错,请检查!");
  16. return mapping.findForward("error");
  17. }
  18. InputStream is = null;
  19. OutputStream os = null;
  20. String uuid = MyTools.getUUID();
  21. String suffix = MyTools.getFileSuffix(fileName);
  22. String newFileName = uuid + suffix;
  23. try {
  24. is = formFile.getInputStream();
  25. String path = request.getServletContext().getRealPath("file");
  26. System.out.println(path);
  27. os = new FileOutputStream(path + "\\" + newFileName);
  28. int len = 0;
  29. byte[] bytes = new byte[1024];
  30. while ((len = is.read(bytes)) > 0) {
  31. os.write(bytes, 0, len);
  32. }
  33. //这里省略保存数据库的操作
  34. //逻辑上的正常跳转,这里也省略
  35. } catch (Exception e) {
  36. e.printStackTrace();
  37. } finally {
  38. try {
  39. if (os != null) {
  40. os.close();
  41. }
  42. if (is != null) {
  43. is.close();
  44. }
  45. } catch (Exception e2) {
  46. e2.printStackTrace();
  47. }
  48. }
  49. request.setAttribute("error", "注册出错!");
  50. return mapping.findForward("error");
  51. }
  52. }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57

2.Struts文件下载

文件下载,我们在介绍原生Servlet的时候已经介绍过,可以参考【Servlet——使用http响应头Content-Disposition下载文件的示例】

当然,那时候我们是把下载的业务逻辑写在一个Servlet中,这里其实也没有什么不同,只不过我们要将业务逻辑写在一个Struts的Action中,并且该Action不需要配置相应的表单。

当我们点击下载的超链接时,让它请求这个Action即可。并且最后让该Action跳转至原来的页面:

  1. return mapping.findForward("goback");
  • 1

版权声明:本文为博主原创文章,未经博主允许不得转载。

Struts1.3——文件上传和下载的更多相关文章

  1. JavaWeb -- Struts1 多文件上传与下载 DownloadAction, DispatchAction

    1. 多文件上传与下载 上传下载jsp: <%@ page language="java" import="java.util.*" pageEncodi ...

  2. java web学习总结(二十四) -------------------Servlet文件上传和下载的实现

    在Web应用系统开发中,文件上传和下载功能是非常常用的功能,今天来讲一下JavaWeb中的文件上传和下载功能的实现. 对于文件上传,浏览器在上传的过程中是将文件以流的形式提交到服务器端的,如果直接使用 ...

  3. (转载)JavaWeb学习总结(五十)——文件上传和下载

    源地址:http://www.cnblogs.com/xdp-gacl/p/4200090.html 在Web应用系统开发中,文件上传和下载功能是非常常用的功能,今天来讲一下JavaWeb中的文件上传 ...

  4. JavaWeb学习总结,文件上传和下载

    在Web应用系统开发中,文件上传和下载功能是非常常用的功能,今天来讲一下JavaWeb中的文件上传和下载功能的实现. 对于文件上传,浏览器在上传的过程中是将文件以流的形式提交到服务器端的,如果直接使用 ...

  5. java文件上传和下载

    简介 文件上传和下载是java web中常见的操作,文件上传主要是将文件通过IO流传放到服务器的某一个特定的文件夹下,而文件下载则是与文件上传相反,将文件从服务器的特定的文件夹下的文件通过IO流下载到 ...

  6. 使用jsp/servlet简单实现文件上传与下载

    使用JSP/Servlet简单实现文件上传与下载    通过学习黑马jsp教学视频,我学会了使用jsp与servlet简单地实现web的文件的上传与下载,首先感谢黑马.好了,下面来简单了解如何通过使用 ...

  7. JavaWeb学习总结(五十)——文件上传和下载

    在Web应用系统开发中,文件上传和下载功能是非常常用的功能,今天来讲一下JavaWeb中的文件上传和下载功能的实现. 对于文件上传,浏览器在上传的过程中是将文件以流的形式提交到服务器端的,如果直接使用 ...

  8. 文件上传和下载(可批量上传)——Spring(三)

    在文件上传和下载(可批量上传)——Spring(二)的基础上,发现了文件下载时,只有在Chrome浏览器下文件名正常显示,还有发布到服务器后,不能上传到指定的文件夹目录,如上传20160310.txt ...

  9. 文件上传和下载(可批量上传)——Spring(二)

    针对SpringMVC的文件上传和下载.下载用之前“文件上传和下载——基础(一)”的依然可以,但是上传功能要修改,这是因为springMVC 都为我们封装好成自己的文件对象了,转换的过程就在我们所配置 ...

随机推荐

  1. JS 提取公式中的参数

    'A+B-C/D*E'.split(/[*/()+-]/)  => [A,B,C,D,E]

  2. Objective-C Properties 详解

    关于Objective-C 的property,很多iOS开发的新手都会很迷惑,也会包括有经验的iOS开发程序员, 因为Objective-C的property,说多不多,说少却也不少,从MRR(Ma ...

  3. excel vlookup的使用

    表1 姓名 部门 ***   ***   ***   ***   表2 姓名 部门 ***  *** *** ***  *** ***  *** ***  找表2的姓名对应部门,粘贴在表1中 vloo ...

  4. shell cp拷贝的用法

    个人觉得这个记录的比较全 自己查阅: cp [options] <source file or directory> <target file or directory> 或 ...

  5. CSS深入理解line-height

    1.line-height高度基于基线 2. 3.p元素的高度由行高决定的 4. 5.

  6. sql优化 分字段统计查询

    select count(1) from pd_xxx_origin_xxx_data where create_time like '2019-02-23%' and source='20036' ...

  7. ARM与Cortex

    arm系列从arm11开始,以后的就命名为cortex,并且性能上大幅度提升. 从cortex开始,分为三个系列,a系列,r系列,m系列. m系列与arm7相似,不能跑操作系统(只能跑ucos2),偏 ...

  8. git update-index --assume-unchanged on directory 转摘自:http://stackoverflow.com/questions/12288212/git-update-index-assume-unchanged-on-directory

    30down votefavorite 16 git 1.7.12 I want to mark all files below a given directory as assume-unchang ...

  9. Ubuntu中实现Docker内安装jenkins+jenkins远程触发

    前面做了在ubuntu中安装jenkins+docker实现自动部署,但是得安装jdk8+tomcat8环境,比较麻烦,因此本文记录如何将jenkins直接装在dockers内并且实现远程触发功能. ...

  10. SSH工具

    SSH是什么:SSH是一种网络协议,用于计算机之间的加密登录   应用:用来连接远程服务器   适用人员:需要操作服务器的程序员,linux管理员等   需要的基础知识: http://www.ee. ...