java struts2入门学习实例--使用struts2快速实现上传
一、文件上传快速入门
1)、关于上传表单三要素
>>尽量以POST请求方式上传,因为GET支持文件大小是有限制的。
>>必须要加上enctype="multipart/form-data"表示上传的文件,以随着请求体经过特殊编码后,一同传入服务器
>>每个表单项,必须取一个名字(name),因为服务器端便于通过名字(name)收集信息.
2)、fileUpload拦截器文件上传拦截器,自动注入三个参数,如下所示:
private String uploadContentType;//上传文件的类型,(Fileupload拦截器传入的参数)
private File upload;//上传的文件,(Fileupload拦截器传入的参数)
private String uploadFileName;//上传文件的真实文件名,(Fileupload拦截器传入的参数)
与jsp页面中的name相对应.
注意:upload和表单项与<s:file>中的name属性一致
upload拼上contentType其中C要大写.
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib uri="/struts-tags" prefix="s" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<s:form action="UploadAction" enctype="multipart/form-data" method="POST">
<s:textfield name="username"/>
<s:file name="upload" />
<s:submit value="提交"/>
</s:form>
</body>
</html>
3)框架自身有fileUpload文件上传拦截器
在默认栈中,有一个fileUpload文件上传拦截器,但是没有下载拦截器,源码参见struts2-core-2.3.16-sources.jar/struts-default.xml
4)、代码分析
UploadAction.java
package action; import java.io.File; import com.opensymphony.xwork2.ActionSupport; /**
* @ClassName: UploadAction
* @Description: 文件上传
* @author: amosli
* @email:amosli@infomorrow.com
* @date Jan 14, 2014 1:50:28 AM
*/
public class UploadAction extends ActionSupport {
private static final long serialVersionUID = -8920466592471253212L;
private String username;// 用户名
private String uploadContentType;// 上传文件的类型,(Fileupload拦截器传入的参数)
private File upload;// 上传的文件,(Fileupload拦截器传入的参数)
private String uploadFileName;// 上传文件的真实文件名,(Fileupload拦截器传入的参数) public void setUsername(String username) {
this.username = username;
} public void setUploadContentType(String uploadContentType) {
this.uploadContentType = uploadContentType;
} public void setUpload(File upload) {
this.upload = upload;
} public String getUsername() {
return username;
} public String getUploadContentType() {
return uploadContentType;
} public File getUpload() {
return upload;
} public String getUploadFileName() {
return uploadFileName;
} public void setUploadFileName(String uploadFileName) {
this.uploadFileName = uploadFileName;
} public String uploadMethod() { return SUCCESS;
} }
upload_success.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib uri="/struts-tags" prefix="s" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
恭喜,上传文件成功!
<hr>
</body>
</html>
upload.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
"http://struts.apache.org/dtds/struts-2.3.dtd"> <struts>
<package name="upload" namespace="/" extends="struts-default">
<action name="UploadAction" class="action.UploadAction" method="uploadMethod">
<result name="success" type="dispatcher">
/WEB-INF/upload_success.jsp
</result>
</action>
</package>
</struts>
struts.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
"http://struts.apache.org/dtds/struts-2.3.dtd"> <struts>
<!-- 加载其他配置文件 -->
<include file="config/upload.xml"></include>
</struts>
程序运行逻辑:
浏览器中输入:http://localhost:8080/struts2_learn/upload.jsp---》输入用户名,选择要上传的文件---》点击提交---》触发UploadAction---》从内存中查找对应的配置文件struts.xml->upload.xml->UploadAction.java,若调用成功--》数据转发到upload_success.jsp。
5)效果如下图所示:

成功上传提示:

二、文件上传快速入门提高
1)如何将上文件上传者的姓名显示出来,如何将文件类型,以及文件名显示出来?将upload_success.jsp改写如下:
<body>
恭喜,上传文件成功!
<hr>
<b>上传用户名:</b> <s:property value="username"/><br>
<b>文件类型:</b> <s:property value="uploadContentType"/><br>
<b>上传的文件:</b> <s:property value="upload"/><br>
<b>上传文件的真实文件名:</b> <s:property value="uploadFileName"/><br>
</body>
上面是通过struts2的标签进行获取对应的属性值,这里的value与定义UploadAction.java中定义的必须一致,并且提供get()方法。下面看效果:

2)、上传一个超过5M的文件,看有什么提示?
这里上传一个大小为9M多的文件,struts-2.3.16-docs.zip,看提示如下图所示。
浏览器中的提示如下:

eclipse终端提示为:
从上面提示可以看到maximum (2097152),计算下来为2M,这个是哪里配置得来的??
>>>查看源码包中,struts2-core-2.3.16-sources.jar/org/apache/struts2/default.properties中有配置为:struts.multipart.maxSize=2097152
同时底层源码显示struts.multipart.parser=jakarta,使用的是jakarta开源组件完成上传的,和传统web应用是一样的,struts2只是将其封装了而已。
如何才能上传大一点的文件呢?很显然必须把默认的配置改掉
在upload_struts.xml中添加下面常量,将默认值改为20M重新上传
<constant name="struts.multipart.maxSize" value="20971520"></constant>
注意:上面更改的是上传文件的总大小,所有上传文件的大小之和。
结果:

3)、如何自定义单个上传文件的大小?
查看org.apache.struts2.interceptor.FileUploadInterceptor拦截器的源码,其中有setMaximumSize,这里maximumSize就是单个文件的大小进行设置。
配置upload.xml文件:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
"http://struts.apache.org/dtds/struts-2.3.dtd"> <struts>
<constant name="struts.multipart.maxSize" value="20971520"></constant>
<!-- 对上传文件总大小进行设置 -->
<package name="upload" extends="struts-default">
<action name="UploadAction" class="action.UploadAction" method="uploadMethod">
<result name="success" type="dispatcher">
/WEB-INF/upload_success.jsp
</result>
<!-- 对系统的拦截器进行设置 -->
<interceptor-ref name="fileUpload">
<!-- 对单个上传文件的大小进行设置,5M-->
<param name="maximumSize">5242880</param>
</interceptor-ref>
</action>
</package> </struts>
结果:

此时的UserAction.java为
package action; import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream; import javax.servlet.ServletContext; import org.apache.struts2.ServletActionContext; import com.opensymphony.xwork2.ActionSupport; /**
* @ClassName: UploadAction
* @Description: 文件上传
* @author: amosli
* @email:amosli@infomorrow.com
* @date Jan 14, 2014 1:50:28 AM
*/
public class UploadAction extends ActionSupport {
private static final long serialVersionUID = -8920466592471253212L;
private String username;// 用户名
private String uploadContentType;// 上传文件的类型,(Fileupload拦截器传入的参数)
private File upload;// 上传的文件,(Fileupload拦截器传入的参数)
private String uploadFileName;// 上传文件的真实文件名,(Fileupload拦截器传入的参数) public void setUsername(String username) {
this.username = username;
} public void setUploadContentType(String uploadContentType) {
this.uploadContentType = uploadContentType;
} public void setUpload(File upload) {
this.upload = upload;
} public String getUsername() {
return username;
} public String getUploadContentType() {
return uploadContentType;
} public File getUpload() {
return upload;
} public String getUploadFileName() {
return uploadFileName;
} public void setUploadFileName(String uploadFileName) {
this.uploadFileName = uploadFileName;
} public String uploadMethod() throws Exception {
ServletContext context = ServletActionContext.getServletContext();
String real_path = context.getRealPath("/WEB-INF/upload/");
InputStream inputStream = new FileInputStream(upload);
OutputStream outputStream = new FileOutputStream(real_path+"/"+uploadFileName);
byte[] b = new byte[1024];
int len = 0 ;
while((len=inputStream.read(b))>0){
outputStream.write(b, 0, len);
}
//关闭流
inputStream.close();
outputStream.close();
//删除tmp文件,最好是用tyrcatch finally进行删除
upload.delete(); return SUCCESS;
} }
为什么会指针的错误???
当一个<action>标签,不引用任何拦截器时,默认会执行defaultStack中的18个拦截器;
当引用指定的拦截器时,将不会执行默认的拦截器。
所以如果只指定执行FileUploadInterceptor时,其它拦截器不执行将不能进行注解操作,即会产生空指针错误。
那么如何使用指定的拦截器和默认的拦截器同时工作呢??
<!-- 显示引用默认的拦截器 -->
<interceptor-ref name="defaultStack"></interceptor-ref>
只需要在<action>标签中再填加名称为defaultStack的拦截器引用即可。
重新上传9.1M的文件后,结果如下:

4)、如何将错误提示消息回显?
这里只需要在upload.xml中配置 名称为input的result属性即可,再将数据转发到upload.jsp页面。
<result name="input" type="dispatcher">
upload.jsp
</result>
结果如下:

5)、如何对上传文件的扩展名加以限制??
<!-- 对系统的拦截器进行设置 -->
<interceptor-ref name="fileUpload">
<!-- 对单个上传文件的大小进行设置,5M-->
<param name="maximumSize">5242880</param>
<!-- 对允许的文件扩展名进行设置,这里以英文逗号隔开 -->
<param name="allowedExtensions">.txt,.xml</param>
</interceptor-ref>
这里只允许.txt和.xml文件上传,上传一个.html文件和一个.txt文件验证是否有效。


但实际情况很容易就可以更改扩展名,所以实质上对提交安全性效果不是特别大。
6)、如何限制上传文件的类型??
<!-- 对系统的拦截器进行设置 -->
<interceptor-ref name="fileUpload">
<!-- 对单个上传文件的大小进行设置,5M-->
<param name="maximumSize">5242880</param>
<!-- 对允许的文件扩展名进行设置,这里以英文逗号隔开 -->
<param name="allowedExtensions">.txt,.xml</param>
<!-- 对允许的文件类型进行设置,这里以英文逗号进行隔开 -->
<param name="allowedTypes">text/plain,text/xml</param>
</interceptor-ref>
这里文件类型是没办法人工去更改的,所以能够较扩展名来说实质上拦截效果更强,与上面很类似,这里就不再演示,其中需要注意的是文件类型不要写错了。
7)、如何更改英文提示信息??
提示信息在:/org/apache/struts2/struts-messages.properties
默认配置在:/org/apache/struts2/default.properties
default.properties 会加载struts-messages.properties,所以这里可以写个properties进行覆盖原始文件。
java struts2入门学习实例--使用struts2快速实现上传的更多相关文章
- git入门学习(一):github for windows上传本地项目到github
Git是目前最先进的分布式版本控制系统,作为一个程序员,我们需要掌握其用法.Github发布了Github for Windows 则大大降低了学习成本和使用难度,他甚至比SVN都简单. 一.首先在g ...
- java struts2入门学习实例--使用struts2快速实现多个文件上传
一.错误提示信息配置 昨天说到更改默认错误配置信息,我测试很多遍,一直都不对.下面贴出来,待以后有好方法了再补充吧. 首先新建一个properties文件,这里命名为testupload.proper ...
- java struts2入门学习实例--使用struts进行验证
一.为什么要进行验证? 验证几乎是注册登录的必须前提,验证的主要作用有两点: 1.安全性 2.对用户提供差异化服务. 二.如何验证? ActionSupport类中有一个validate()方法,这是 ...
- java struts2入门学习实例--用户注册
一.用户注册示例 register.jsp <%@ page language="java" contentType="text/html; charset=UT ...
- java struts2入门学习实例--将客户端IP地址和访问方式输出到浏览器
实例1:实现客户端IP地址和访问方式输出到浏览器. IpAction.java package com.amos.web.action; import javax.servlet.http.HttpS ...
- java struts2入门学习实例--用户注册和用户登录整合
需求: 1.用户注册(user_register.jsp)-->注册成功(UserRegister.action)-->显示注册信息(register_success.jsp)2.用户登录 ...
- java多线程入门学习(一)
java多线程入门学习(一) 一.java多线程之前 进程:每一个进程都有独立的代码和数据空间(进程上下文),进程间的切换会有较大的开销.一个进程包括1--n个线程. 线程:同一类线程共享代码 ...
- Plupload上传实例《模仿微云上传实例》,带源码
Plupload上传实例<模仿微云上传实例>,带源码,作者:鱼塘总裁 如有疑问,加群交流:646104701 一.实例截图 1.上传过程 2.上传成功 3.上传失败 4.最小化 二.所需文 ...
- java struts2入门学习--OGNL语言基本用法
一.知识点学习 1.struts2中包含以下6种对象,requestMap,sessionMap,applicationMap,paramtersMap,attr,valueStack; 1)requ ...
随机推荐
- springboot 项目mybatis plus 设置 jdbcTypeForNull (oracle数据库需配置JdbcType.NULL, 默认是Other)
方法1: application.yml mybatis-plus: configuration: jdbc-type-for-null: 'null' #注意:单引号 方法2: 查看mp-start ...
- 7个提高效率的JavaScript调试工具
现在的JavaScript事实上已然成为了流行的web语言,即使它并不完美.很多程序员不喜欢用JavaScript写代码,是因为写到后来总会出现各种莫名其妙的bug,而且在开发大型应用程序的过程中很容 ...
- 我对android 软件栈了解
android 软件栈如图所示: Android平台的核心是Linux内核,它负责设备驱动程序.资源访问.电源管理和完成其他操作系统的职责.提供的设备驱动程序包括显示器.照相机,键盘.WiFi.闪存. ...
- 理解TensorFlow的Queue
https://www.jianshu.com/p/d063804fb272 这篇文章来说说TensorFlow里与Queue有关的概念和用法. 其实概念只有三个: Queue是TF队列和缓存机制的实 ...
- 逻辑回归应用之Kaggle泰坦尼克之灾
机器学习系列(3)_逻辑回归应用之Kaggle泰坦尼克之灾 标签: 机器学习应用 2015-11-12 13:52 3688人阅读 评论(15) 收藏 举报 本文章已收录于: 机器学习知识库 分类 ...
- MonoDB的数据准备
首先是数据的录入,为了分析我们服务器集群的性能,需要准备大量的用户数据,幸运的是mtools提供了mgenerate方法供我们使用.他可以根据一个数据模版向 MongoDB 中插入任意条 json ...
- C#.NET常见问题(FAQ)-如何不显示窗口的关闭按钮
如果把ControlBox设置为false,则右上角三个按钮都看不到了 最好的方法是重写窗体的CreateParams方法,如下图所示 更多教学视频和资料下载,欢迎关注以下信息: 我的优酷空间 ...
- Windows下的Qt Creator的安装
采用Qt和Qt creator分别下载和安装的方式:(需要手动设置关联Qt和Qt Creator) 一.软件下载 从http://qt-project.org/downloads分别下载Qt和Qt ...
- cocos2d-js Shader系列3:多重纹理 multiple textures multiple samplers
上一篇,我们学习了怎么便捷的控制sprite的颜色,而这个都是默认一个texture的,如果要实现类似mask的效果,或者更个性化的多纹理效果,怎么实现呢? 这就是这一节需要介绍的内容. 例如上图的效 ...
- Flash:TextField字体不显示/文字不显示/文字丢失
节约大家时间,先说结论: 1.是否文字中包含了\r\n等字符,flash中,\r和\n都会换行.需要过滤掉其中1个 2.是否文本框大小不够,文字被挤到下一行了.设置单行.多行 3.TextFi ...