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. swoole 多进程共享数据

    进程作为程序执行过程中资源分配的基本单位,拥有独立的地址空间,同一进程的线程可以共享本进程的全局变量,静态变量等数据和地址空间,但进程之间资源相互独立.由于PHP语言不支持多线程,因此Swoole使用 ...

  2. 关系型数据库MySQL(一)_增删改查

    1.创建表单 create table product (product_id  char(4)  not null, product_name  varchar(100)  not null, sa ...

  3. 准确获取URL地址参数

    http://localhost:8080/?state=app&code=021axrkH0Il7Df2bEQkH0DMjkH0axrkP 准确获取code的值 getQueryString ...

  4. Codeforces 497B Tennis Game( 枚举+ 二分)

    B. Tennis Game time limit per test 2 seconds memory limit per test 256 megabytes input standard inpu ...

  5. Codeforces Paths and Trees

    Paths and Trees time limit per test3 seconds memory limit per test256 megabytes Little girl Susie ac ...

  6. [转]图片压缩功能在JBoss AS7出错有关问题

    图片压缩功能在JBoss AS7出错问题近日在为平台(http://www.zyiqibook.com)做些小的整改,途中基本很顺利,但就在后面出现了些纠结的问题,而这问题我之前遇到过,因为一时没有想 ...

  7. Centos7 忘记密码的情况下,修改root密码

    linux管理员忘记root密码,需要进行找回操作. 本文基于centos7环境进行操作,由于centos的版本是有差异的,继续之前请确定好版本 一.重启系统,在开机过程中,快速按下键盘上的方向键↑和 ...

  8. 第12篇Kubernetes 监控

        一.Weave Scope: Weave Scope 容器地图   创建 Kubernetes 集群并部署容器化应用只是第一步.一旦集群运行起来,我们需要确保一起正常,所有必要组件就位并各司其 ...

  9. 工具类Collections、Arrays(传入的是数组)

    Collections类: 1. Collections.sort(list)   //对list集合进行排序前提是 list里面存储的对象已经实现了 comparable接口 2. Collecti ...

  10. 使用springBoot完成阿里云短信验证

    <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot ...