JAva-webファイルアップロードダウンロードにより、複数のセキュリティアクセスの問題を解決

12906 ワード

ファイルのアップロードとダウンロードにより、複数のセキュリティアクセスの問題を解決できます.これは去年先生が教えてくれた方法で、ここでメモとして記録しておきます.
 
説明:ファイルのアップロードについては、ブラウザがアップロード中にファイルをストリーム形式でサーバ側に提出するので、サーブレットを直接使用してアップロードファイルの入力ストリームを取得してから、中の要求パラメータを解析するのは面倒なので、apacheのオープンソースツールcommon-fileuploadというファイルアップロードコンポーネントを採用するのが一般的です.このcommon-fileuploadアップロードコンポーネントのjarパッケージはapache公式サイトにダウンロードしたり、strutsのlibフォルダの下に見つけたりすることができます.strutsアップロードの機能はこれに基づいて実現されています.common-fileuploadはcommon-ioというパッケージに依存するので、このパッケージをダウンロードする必要があります.
 
demo:JavaWebファイルアップロードダウンロード
 
以下は構築手順です.
 
1、2個のパッケージを追加する:
 
commons-fileupload-1.2.1.jar
commons-io-1.3.2.jar

 
二、ファイルのアップロード
 
2.1、ファイルアップロードjspページ:upload.jsp
 



    
    My JSP 'upload.jsp' starting page   
	
	
	    
	
	
  
  
  
    

1:
2:

 
2.2.ファイルアップロードの処理サーブレット:UploadServicelet
 
ファイルアップロードの詳細:
 
 
1.サーバーの安全を保証するために、アップロードファイルは外部から直接アクセスできないディレクトリの下に置くべきで、例えばWEB-INFディレクトリの下に置くべきである.
2.ファイルの上書きを防ぐために、アップロードファイルに一意のファイル名を作成します.
3.1つのディレクトリの下にファイルが多すぎるのを防ぐために、hashアルゴリズムを使用してストレージを分散します.
4.アップロードファイルの最大値を制限します.
5.アップロードファイルの種類を制限するには、アップロードファイル名を受け取ったときに、接尾辞名が合法かどうかを判断します.
 
上記の5つの詳細については、次のような質問が必要です.
 
1、外部から私たちのアップロードしたファイルリソースにアクセスしないように、アップロードリソースをWEB-INFディレクトリの下に置きます.
 
2、MD 5アルゴリズムを使用して一意の文字列を生成することができ、その文字列とアップロードファイル名を「」を使用する(英語の下線)アップロードされたファイルの一意性を確保するために、最終的なファイル名を構成します.
 
 
/**
* @Method: makeFileName
* @Description:           ,    :uuid+"_"+       
* @param filename        
* @return uuid+"_"+       
*/ 
private String makeFileName(String filename){  //2.jpg
	 //            ,                
	 return UUID.randomUUID().toString() + "_" + filename;
}

 
 
3、私たちのアップロードファイルをばらばらにして、それぞれ複数の異なるディレクトリで使用します.
/**
*                ,   hash      
* @Method: makePath
* @Description: 
* @param filename    ,            
* @param savePath       
* @return       
*/
private String makePath(String filename,String savePath){
	//      hashCode  ,     filename              
	int hashcode = filename.hashCode();
	int dir1 = hashcode&0xf;  //0-15
	int dir2 = (hashcode&0xf0)>>4;  //0-15
	//        
	String dir = savePath + "\\" + dir1 + "\\" + dir2;  //upload\2\3  upload\3\5
	//File              
	File file = new File(dir);
	//       
	if(!file.exists()){
		//    
		file.mkdirs();
	}
	return dir;
}

 
4、以下のオブジェクトの属性を設定して、単一アップロードファイルの最大値と単一アップロードの総ファイルサイズを制限します.
ServletFileUpload upload = new ServletFileUpload(factory);
//               ,      1024*1024  ,   1MB
upload.setFileSizeMax(1024*1024);
//            ,   =                  ,     10MB
upload.setSizeMax(1024*1024*10);

 
5、私達はファイルの情報をアップロードすることによってファイルの全名称を得ることができて、全名称から接尾辞名を切り取ってファイルのタイプを判断することができます
//         
//  :                 ,                   , :c:\a\b\1.txt,           , :1.txt
String fileFullName = item.getName();
System.out.println(fileFullName);
String fileName = fileFullName.substring(fileFullName.lastIndexOf("\\")+1);
//          
String fileExtName = fileName.substring(fileName.lastIndexOf(".")+1);
//             ,                          
System.out.println("          :"+fileExtName);

 
すべてのUploadServiceletコード:
 
package com.gx.servlet;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.List;
import java.util.UUID;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileUploadBase;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;

public class UploadServlet extends HttpServlet {

	public void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		String message = null;
		try {
			 //  Apache              :
			//1、    DiskFileItemFactory  
			DiskFileItemFactory factory = new DiskFileItemFactory();
			
			//2、           
			ServletFileUpload upload = new ServletFileUpload(factory);
			//            
			upload.setHeaderEncoding("UTF-8");
			//3.         (                   )
			if(!upload.isMultipartContent(request)){
				//         ,             
				return;
			}
			 //               ,      1024*1024  ,   1MB
			upload.setFileSizeMax(1024*1024);
			//            ,   =                  ,     10MB
			upload.setSizeMax(1024*1024*10);
			
			//4、  ServletFileUpload         ,          List  ,
			//   FileItem    Form      
			List list = upload.parseRequest(request);
			for(FileItem item : list){
				//  fileitem             
				if(item.isFormField()){
					String name = item.getFieldName();
					String value = item.getString();
					System.out.println("name="+name+",value="+value);
				}else{//  fileitem         
					//         
					//  :                 ,                   , :  c:\a\b\1.txt,           , :1.txt
					String fileFullName = item.getName();
					String fileName = fileFullName.substring(fileFullName.lastIndexOf("\\")+1);
					//          
					String fileExtName = fileName.substring(fileName.lastIndexOf(".")+1);
					//             ,                          
					System.out.println("          :"+fileExtName);
					
					//         
					String savePath = this.getServletContext().getRealPath("/upload");
					//         
					String saveFileName = makeFileName(fileName);
					//         
					String realSavePath = makePath(saveFileName, savePath);
					InputStream in = item.getInputStream();
					byte [] buffer = new byte[1024];
					int len = 0;
					OutputStream os= new FileOutputStream(realSavePath+File.separator+saveFileName);
					while((len=in.read(buffer))!=-1){
						os.write(buffer, 0, len);
					}
					in.close();
					os.close();
				}
			}
		} catch (FileUploadBase.FileSizeLimitExceededException e) {
				e.printStackTrace();
				request.setAttribute("message", "         !!!");
				request.getRequestDispatcher("/message.jsp").forward(request, response);
				return;
			}catch (FileUploadBase.SizeLimitExceededException e) {
				e.printStackTrace();
				request.setAttribute("message", "                 !!!");
			    request.getRequestDispatcher("/message.jsp").forward(request, response);
				 return;
			}catch (Exception e) {
				message= "      !";
				e.printStackTrace();
		}
	}

	public void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		doGet(request, response);
	}
	
	/**
	* @Method: makeFileName
	* @Description:           ,    :uuid+"_"+       
	* @param filename        
	* @return uuid+"_"+       
	 */ 
	private String makeFileName(String filename){  //2.jpg
		 //            ,                
		 return UUID.randomUUID().toString() + "_" + filename;
	}
	
	 /**
	*                ,   hash      
	* @Method: makePath
	* @Description: 
	* @param filename    ,            
	* @param savePath       
	* @return       
	*/
	private String makePath(String filename,String savePath){
		//      hashCode  ,     filename              
		int hashcode = filename.hashCode();
		int dir1 = hashcode&0xf;  //0-15
		int dir2 = (hashcode&0xf0)>>4;  //0-15
		//        
		String dir = savePath + "\\" + dir1 + "\\" + dir2;  //upload\2\3  upload\3\5
		//File              
		File file = new File(dir);
		//       
		if(!file.exists()){
			//    
			file.mkdirs();
		}
		 return dir;
		}

}

コメントが多いので、コードが少し乱れているように見えますが、コピーしてみましょう.
 
2.3、Web.xmlファイルにUploadServiceletを登録する


    UploadServlet

    com.gx.servlet.UploadServlet

  

  

    UploadServlet

    /servlet/UploadServlet

  

 
 
三、ファイルのダウンロード
 
3.1、ファイルアップロードjspページ:download.jsp
 



  
    My JSP 'download.jsp' starting page
	
	
	    
  
  
    ダウンロード
  


 
 
fileName=..._中国jpgこれは上にアップロードした画像で、自分で対応して直します
 
3.2、ファイルのダウンロードを処理するservlet:DownloadServicelet
package com.gx.servlet;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.OutputStream;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.sun.org.apache.xml.internal.security.utils.Base64;

public class DownloadServlet extends HttpServlet {

	public void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
        response.setCharacterEncoding("UTF-8");
		//         
		String fileName = request.getParameter("fileName");
		fileName = new String(fileName.getBytes("iso8859-1"),"UTF-8");
		//          /upload         
		String fileSaveRootPath=this.getServletContext().getRealPath("/upload");
		//              
		String path = findFileSavePathByFileName(fileName,fileSaveRootPath);
		//        
		File file = new File(path,fileName);
		System.out.println("      :"+path+"\\"+fileName);
		//       
		if(!file.exists()){
			request.setAttribute("message", "           !!");
			request.getRequestDispatcher("/message.jsp").forward(request, response);
			return;
		}
		//     
		String realName = fileName.substring(fileName.indexOf("_")+1);
		 //     ,          
		response.setHeader("Content-Disposition", String.format("attachment;filename*=utf-8’zh_cn%s",java.net.URLEncoder.encode(realName,"UTF-8")));
		//        ,        
		FileInputStream in = new FileInputStream(file);
		//     
		OutputStream out = response.getOutputStream();
		//     
		byte buffer[] = new byte[1024];
		int len = 0;
		//                  
		while((len=in.read(buffer))>0){
		     //            ,      
		    out.write(buffer, 0, len);
		  }
		//       
		in.close();
		//     
		out.close();
	}

	public void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		doGet(request, response);
	}

		/**
		* @Method: findFileSavePathByFileName
		* @Description:                             
		* @param filename        
		* @param saveRootPath           ,   /upload  
		* @return            
		*/ 
		public String findFileSavePathByFileName(String filename,String saveRootPath){
			int hashcode = filename.hashCode();
			int dir1 = hashcode&0xf;  //0--15
			int dir2 = (hashcode&0xf0)>>4;  //0-15
			String dir = saveRootPath + "\\" + dir1 + "\\" + dir2;  //upload\2\3  upload\3\5
			File file = new File(dir);
			if(!file.exists()){
			    //    
			    file.mkdirs();
			}
			return dir;
		}
}

 
3.3、Web.xmlファイルにDownloadServiceletを登録する

    DownloadServlet
    com.gx.servlet.DownloadServlet
  
  
    DownloadServlet
    /servlet/DownloadServlet
  

 
 
 
 
 
以上、ファイルアップロードダウンロード機能を簡単に実現しました.
 
demo:JavaWebファイルアップロードダウンロード
 
 
人はlianを必要としないで、天下は敵なしです.いいねを頼む