解決Struts2 使用Common-FileUpload List<FileItem>爲空的問題

通常我們在解析form表單提交數據的時候使用FileUpload。但在最近的項目中出現了數據解析不成功的問題。
問題如題,造成這個問題的根本原因是因爲struts2對request對象進行了封裝,由HttpServletRequest變成MultiPartRequestWrapper。導致`fileList = upload.parseRequest(request);`獲取不到上傳的對象所以List爲空。
解決辦法:

1. 更改攔截器

<filter-mapping>
        <filter-name>struts2</filter-name>
        <url-pattern>/*</url-pattern>
</filter-mapping>

改成

<filter-mapping>
        <filter-name>struts2</filter-name>
        <url-pattern>*.action</url-pattern>
</filter-mapping>

攔截後綴名可自行定義

2. 修改Struts的配置文件
剔除對Request的封裝
步驟:
a)編寫類文件 繼承類JakartaMultiPartRequest
eg:

    public class RequestParseWrapper extends JakartaMultiPartRequest {  

  public void parse(HttpServletRequest servletRequest, String saveDir)throws IOException {}  
}

讓該類生效
在struts.xml(Struts的配置文件,具體名字按照自己項目定義)添加以下內容:
如果struts2的版本是status2.3.4
在配置文件struts.xml里加上

<bean type= "org.apache.struts2.dispatcher.multipart.MultiPartRequest"
name= "myRequestParser"   class= "類所在的包路徑.RequestParseWrapper"
scope= "default"   optional= "true " />
<constant   name= "struts.multipart.handler"   value= "myRequestParser"   />

如果struts的版本是struts2.3.15.1 以後的版本
在配置文件struts.xml里加上

<bean   type= "org.apache.struts2.dispatcher.multipart.MultiPartRequest"
name= "myRequestParser"   class= "類所在的包路勁.RequestParseWrapper"
scope= "default"   optional= "true "   />
<constant   name= " struts.multipart.parser"   value= "myRequestParser"   />

3. 使用MultiPartRequestWrapper
作爲struts更新瞭如此多的版本,依然沒有修復這個問題。具體原因我也不清楚,只是提出解決方案。
下面給出詳細代碼:

jsp頁面:

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>

<!DOCTYPE html>
<html>
<!--[if IE 6]><html class="ie ie6"><![endif]-->
<!--[if IE 7]><html class="ie ie7"><![endif]-->
<!--[if IE 8]><html class="ie ie8"><![endif]-->
<!--[if IE 9]><html class="ie ie9"><![endif]-->
<!--[if gt IE 9]><html> <![endif]-->
  <head>
    <base href="<%=basePath%>">
    <meta charset="UTF-8">
    <meta name="renderer" content="webkit">
    <meta content="IE=edge,chrome=1" http-equiv="X-UA-Compatible">
    <meta content="width=device-width; initial-scale=1; maximum-scale=1" name="viewport">
    <title>發送通知</title>
  </head>

  <body>
   <form enctype="multipart/form-data" name="filesend" id="file-form">
   通知標題:<input name="title" type="text" class="title"><br>
   通知內容:<textarea rows="10%" cols="50%" name="content" class="content"></textarea><br>
        <a href="javascript:;" onclick="javascript:addfile();" class="add-file">添加附件</a>
        <div class="ext-file"></div>
   </form>
   <div class="modal-footer">  
                <button class="btn btn-primary"  onclick="javascript:subimtBtn();">提交</button>  
   </div>
   <script type="text/javascript" src="js/jquery.min.js"></script>
    <script type="text/javascript" src="js/jquery.form.js"></script>
    <script src="js/plugins/layer/layer.min.js"></script>
    <script type="text/javascript">
    function addfile(){
        var br = $("<br>"); 
        var input = $("<input type='file' name='file' />"); 
        var af = $("<a type='button' name='remove' >移除</a>"); 
        $(".ext-file").append(br).append(input).append(af);
        af.click(function() { 
              br.remove(); 
              input.remove(); 
              af.remove(); 
              });
    };
    function subimtBtn() {
        var title="";
        title = $(".title").val();
        if(title==""){
            layer.msg("標題不能爲空!");
            return false;
         }
        var content="";
        content = $(".content").val();
        if(content==""){
            layer.msg("內容不能爲空!");
            return false;
         }
        var ajax_option={
            type: "post",
            url:"<%=basePath%>/message/notice!getMesg.ac",
            dataType: "json",
            success:function(data){
                 console.log(data)
            }
        }
        $('#file-form').ajaxSubmit(ajax_option);
        return ;
    }
</script>
  </body>
</html>

Action方法:

    private static final List<String> FILEEXT = Arrays.asList("xls", "xlsx", "doc","docx","jpg","gif","png");//允許的文件格式
    private static SimpleDateFormat DF = new SimpleDateFormat("ddHHmmss");//重新格式化的文件名
    private static final int FILESIZE = 5*1024*1024;//單個文件最大5M
    private String getFileDir(){
        if(FILEDIR.isEmpty()){
            FILEDIR = getFilepath()+"/upload";
        }
        return FILEDIR;
    }
    private String getFilepath(){
        if(FILEPATH.isEmpty()){
            String classPath = NoticeAction.class.getClassLoader().getResource("/").getPath();
            String rootPath = "";
            if("\\".equals(File.separator)){//windows下
                rootPath = classPath.substring(1,classPath.indexOf("/WEB-INF/classes"));
                FILEPATH = rootPath.replace("/", "\\");
            }else if("/".equals(File.separator)){//linux下
                rootPath = classPath.substring(0,classPath.indexOf("/WEB-INF/classes"));
                FILEPATH = rootPath.replace("\\", "/");
            }
        }
        return FILEPATH;
    }

    public void getMesg()throws Exception{
        try {
            if (ServletFileUpload.isMultipartContent(request())) {
                MultiPartRequestWrapper wrapper = (MultiPartRequestWrapper) request(); 
                String[]  filanames = wrapper.getFileNames("file");//所有的文件名
                File[] files = wrapper.getFiles("file");//上傳的所有文件
                String title = String.valueOf(wrapper.getAttribute("title"));
                if (!new File(getFileDir()).isDirectory()){//文件夾上傳目錄
                    new File(getFileDir()).mkdirs();
                }
                for(int i=0;i<files.length;i++){
                    File file = files[i];
                    String fileName  = filanames[i];
                    //檢查文件大小
                    if(file.length() > FILESIZE){
                        WriterJson(false, "", "操作失敗:文件"+fileName+"大小超出最大限度!");
                        return ;
                    }
                    //檢查擴展名
                    String fileExt = fileName.substring(fileName.lastIndexOf(".") + 1).toLowerCase();
                    if(!FILEEXT.contains(fileExt)){
                        WriterJson(false, "", "操作失敗:文件格式不正確");
                        return;
                    }
                    String newFileName = fileName+"_"+DF.format(new Date()) + "_" + new Random().nextInt(1000) +i+ "." + fileExt;//重命名文件名
                    try {
                        InputStream in = new FileInputStream(file);
                        File uploadFile = new File(getFileDir(), newFileName);
                        OutputStream out = new FileOutputStream(uploadFile);
                        byte[] buffer = new byte[1024 * 1024];
                        int length;
                        while ((length = in.read(buffer)) > 0) {
                            out.write(buffer, 0, length);
                        }
                        in.close();
                        out.close();
                    } catch (FileNotFoundException ex) {
                        ex.printStackTrace();
                    } catch (IOException ex) {
                        ex.printStackTrace();
                    }
                }
            }else{
                WriterJson(false, "", "類型不支持!");
            }
        }catch (Exception e) {
            e.printStackTrace();
        }
        WriterJson(true, "", "操作成功!");
    }

其中WriterJson爲項目封裝的Ajax返回。
操作截圖:
未美化的界面
相關js文件如下:
jquery.form.js 自己上傳,可自行搜索下載
layer.min.js 請移步官網下載

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章