java struts2入門學習實例--使用struts2快速實現上傳

1、文件上傳快速入門

 

1)、關於上傳表單三要素

>>儘可能以POST請求方式上傳,由於GET支持文件大小是有限制的。html

>>必需要加上enctype="multipart/form-data"表示上傳的文件,以隨着請求體通過特殊編碼後,一同傳入服務器java

>>每一個表單項,必須取一個名字(name),由於服務器端便於經過名字(name)收集信息.web

 

 2)、fileUpload攔截器文件上傳攔截器,自動注入三個參數,以下所示:

    private String uploadContentType;//上傳文件的類型,(Fileupload攔截器傳入的參數)
    private File upload;//上傳的文件,(Fileupload攔截器傳入的參數)
    private String uploadFileName;//上傳文件的真實文件名,(Fileupload攔截器傳入的參數)
    

與jsp頁面中的name相對應.apache

注意: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.jspeclipse

<%@ 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.xmljsp

<?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進行覆蓋原始文件。

相關文章
相關標籤/搜索