Struts1.3——文件上传和下载
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——文件上传和下载的更多相关文章
- JavaWeb -- Struts1 多文件上传与下载 DownloadAction, DispatchAction
1. 多文件上传与下载 上传下载jsp: <%@ page language="java" import="java.util.*" pageEncodi ...
- java web学习总结(二十四) -------------------Servlet文件上传和下载的实现
在Web应用系统开发中,文件上传和下载功能是非常常用的功能,今天来讲一下JavaWeb中的文件上传和下载功能的实现. 对于文件上传,浏览器在上传的过程中是将文件以流的形式提交到服务器端的,如果直接使用 ...
- (转载)JavaWeb学习总结(五十)——文件上传和下载
源地址:http://www.cnblogs.com/xdp-gacl/p/4200090.html 在Web应用系统开发中,文件上传和下载功能是非常常用的功能,今天来讲一下JavaWeb中的文件上传 ...
- JavaWeb学习总结,文件上传和下载
在Web应用系统开发中,文件上传和下载功能是非常常用的功能,今天来讲一下JavaWeb中的文件上传和下载功能的实现. 对于文件上传,浏览器在上传的过程中是将文件以流的形式提交到服务器端的,如果直接使用 ...
- java文件上传和下载
简介 文件上传和下载是java web中常见的操作,文件上传主要是将文件通过IO流传放到服务器的某一个特定的文件夹下,而文件下载则是与文件上传相反,将文件从服务器的特定的文件夹下的文件通过IO流下载到 ...
- 使用jsp/servlet简单实现文件上传与下载
使用JSP/Servlet简单实现文件上传与下载 通过学习黑马jsp教学视频,我学会了使用jsp与servlet简单地实现web的文件的上传与下载,首先感谢黑马.好了,下面来简单了解如何通过使用 ...
- JavaWeb学习总结(五十)——文件上传和下载
在Web应用系统开发中,文件上传和下载功能是非常常用的功能,今天来讲一下JavaWeb中的文件上传和下载功能的实现. 对于文件上传,浏览器在上传的过程中是将文件以流的形式提交到服务器端的,如果直接使用 ...
- 文件上传和下载(可批量上传)——Spring(三)
在文件上传和下载(可批量上传)——Spring(二)的基础上,发现了文件下载时,只有在Chrome浏览器下文件名正常显示,还有发布到服务器后,不能上传到指定的文件夹目录,如上传20160310.txt ...
- 文件上传和下载(可批量上传)——Spring(二)
针对SpringMVC的文件上传和下载.下载用之前“文件上传和下载——基础(一)”的依然可以,但是上传功能要修改,这是因为springMVC 都为我们封装好成自己的文件对象了,转换的过程就在我们所配置 ...
随机推荐
- Html5 学习笔记 【PC固定布局】 实战6 咨询页面
最终效果: Html页面代码: <!DOCTYPE html> <html lang="zh-cn"> <head> <meta char ...
- checkBox的全选与全不选
//初始加载 $(function () { LoadCart(); }); var RMB = 0; var Index = 0; var shu = 0; var ResultStr = &q ...
- JavaScript-打开新窗口(window.open)和 关闭窗口(window.close)
JavaScript-打开新窗口 open() 方法可以查找一个已经存在或者新建的浏览器窗口. 语法: window.open([URL], [窗口名称], [参数字符串]) 参数说明: URL:可选 ...
- u盘在电脑读不出来,但别的可以读
其实一般这种问题都是驱动程序问题导致的,解决方法很简单,不管是win7还是win10都适用: 插入u盘然后在设备管理里删掉设备重新插拔试试. 详细步骤是: 插上U盘 打开设备管理器 ...
- 记录一次kibana启动Unable to fetch data from reporting collector
版本不匹配导致 应该es与kibana版本一致 本文链接:https://blog.csdn.net/qq_33293753/article/details/87894882
- mySQL学习入门教程——4.内置函数
四.内置函数: 包括了字符串函数.数值函数.日期函数.流程控制函数.其他函数(获取数据库信息)... 一.字符串函数[比较常用,需要掌握]1. concat(s1,s2,...,sn) #把传入的 ...
- python-opencv实现简单的车牌定位
车牌定位的原理:https://blog.csdn.net/relocy/article/details/78705662 训练好的分类器:https://github.com/zeusees/Hyp ...
- Web设计规范----控件、组件
什么是控件?什么组件? 组件控件分类可以根据组件控件属性进行分类,也可以根据组件控件的功能进行划分.一般按功能划分,例如表单类就可以划分为:单文本输入,多文本输入.日历时间选择器.下拉选择列表.单选多 ...
- SQL数据库—<7>事务、异常和游标
事务 一.什么是事务能够保证数据的一致性的代码控制,要么执行提交,要么滚回事务的初始状态 二.事务的四大特性:ACIDA:原子性-------事务不可拆开,要么执行要么回滚无中间状态C:一致性---- ...
- mybatis的缓存机制及用例介绍
在实际的项目开发中,通常对数据库的查询性能要求很高,而mybatis提供了查询缓存来缓存数据,从而达到提高查询性能的要求. mybatis的查询缓存分为一级缓存和二级缓存,一级缓存是SqlSessio ...