1.Struts文件上传

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

1.1 开发步骤

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

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

<body>
<h1>注册用户</h1>
<% --如果表单有文件控件,则需要重新指定表单的编码方式 --%>
<form enctype="multipart/form-data" action="/StrutsFileUpAndDown/register.do" method="post">
名字:<input type="text" name="name" /><br>
头像:<input type="file" name="photo" /><br>
<input type="submit" value="注册" />
</form>
</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

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

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

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

1.2 改进

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

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

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

配置如下:

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

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

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

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

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

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

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

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

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

public class RegisterAction extends Action {
public ActionForward execute(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response) {
UserForm userForm = (UserForm) form;
String username = userForm.getName();
FormFile formFile = userForm.getPhoto(); // 通过FormFile我们可以获取关于用户上传文件的各种信息,比如大小,名字等
String fileName = formFile.getFileName();
int fileSize = formFile.getFileSize(); if (fileSize > 10 * 1024 * 1024) {
request.setAttribute("error", "文件大小不能超过10MB!");
return mapping.findForward("error");
} if(!formFile.getContentType().startsWith("image/")){
request.setAttribute("error", "文件格式有错,请检查!");
return mapping.findForward("error");
} InputStream is = null;
OutputStream os = null;
String uuid = MyTools.getUUID();
String suffix = MyTools.getFileSuffix(fileName);
String newFileName = uuid + suffix;
try {
is = formFile.getInputStream();
String path = request.getServletContext().getRealPath("file");
System.out.println(path);
os = new FileOutputStream(path + "\\" + newFileName);
int len = 0;
byte[] bytes = new byte[1024];
while ((len = is.read(bytes)) > 0) {
os.write(bytes, 0, len);
} //这里省略保存数据库的操作
//逻辑上的正常跳转,这里也省略
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (os != null) {
os.close();
}
if (is != null) {
is.close();
}
} catch (Exception e2) {
e2.printStackTrace();
}
}
request.setAttribute("error", "注册出错!");
return mapping.findForward("error");
}
}
  • 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跳转至原来的页面:

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. phpstorm中sass编译时目录或内容包含中文字符报错

    ruby版本:ruby 2.4.1p111 (2017-03-22 revision 58053) [x64-mingw32] sass版本:Sass 3.4.24 (Selective Steve) ...

  2. smartGit的使用

    合理管理自己的代码,对程序员来说是一件很重要的事,今天我也走上了github托管之路 要在Git上托管代码,首先你要要github官网创建一个代码仓库,用来放你的代码. 一,要托管到github,那你 ...

  3. VS2015 编写C++的DLL,并防止DLL导出的函数名出现乱码(以串口通信为例,实现串口通信)

    参考链接:https://blog.csdn.net/songyi160/article/details/50754705 1.新建项目 建立好的项目界面如下: 接着在解决方案中找到[头文件]然后右击 ...

  4. 加载的DAL数据访问层的类型

    using System; using System.Collections; using System.Reflection; using CSFrameworkV4_5.Core; using C ...

  5. MSF——Meterpreter(三)

    MSF系列: MSF——基本使用和Exploit模块(一) MSF——Payload模块(二) MSF——Meterpreter(三) MSF——信息收集(四) 一.简介 Meterpreter是Me ...

  6. Dubbo 系列(07-5)集群容错 - Mock

    Dubbo 系列(07-5)集群容错 - Mock [toc] Spring Cloud Alibaba 系列目录 - Dubbo 篇 1. 背景介绍 相关文档推荐: Dubbo 实战 - 服务降级 ...

  7. HDU 5125 magic balls(线段树+DP)

    magic balls Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total ...

  8. Javascript基础五(BOM和DOM)

    1.BOM概念 什么是BOM?         BOM是Browser Object Model的缩写,简称浏览器对象模型.这个对象就是window         BOM提供了独立于内容而与浏览器窗 ...

  9. Nginx Web 基础入门

    目录 Nginx Web 基础入门 Nginx快速安装 两种方式部署Nginx 如何升级nginx或者添加功能 使用systemd管理nginx nginx相关配置文件 nginx的配置文件详解 虚拟 ...

  10. go语言从例子开始之Example4.常量

    Go 支持字符.字符串.布尔和数值 常量 . package main import "fmt" import "math" const 用于声明一个常量. c ...