• 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;
        }
    
    }
    View Code

    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>
    View Code

    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>
    View Code

    结果:

    此时的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;
        }
    
    }
    View Code

    为什么会指针的错误???

    当一个<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进行覆盖原始文件。

  • 相关阅读:
    深度学习一些专有名词
    面对imbalance data的时候
    关于各个loss的理解--持续更新
    关于gan的流程理解
    IIS8.0 配置应用程序初始化功能
    IIS7.5 配置应用程序初始化功能
    模拟差的网络环境
    安装Android Studio
    java.lang.NoClassDefFoundError: HttpServletRequest
    Fiddler 断点调试http请求
  • 原文地址:https://www.cnblogs.com/amosli/p/3516815.html
Copyright © 2020-2023  润新知