형제 JavaWeb 튜토리얼 파일 업로드 기술의 IT 밴드

웹 응용 프로그램 개발에서, 파일 업로드 및 다운로드 기능은 매우 일반적으로 사용되는 기능은 다음과 같습니다.

파일 업로드, 브라우저, 그것은 일반적 아파치를 사용하여 더 번잡 선택되는 직접 사용 서블릿 입력을 업로드 된 파일 스트림을 획득 한 다음 요청 파라미터 안에 분석하는 경우 서버에 스트림 전송 한 파일을 업로드하는 과정에 오픈 소스 도구 공통 파일 업로드이 파일 업로드 컴포넌트. 이 공통 파일 업로드 항아리 패키지 업로드 컴포넌트 아파치의 공식 얼굴을 다운로드 온라인으로 갈 수 있습니다. 이 패키지를 다운로드해야하므로 공통 파일 업로드는 공통 IO 패키지에 따라 달라집니다.

 

개발 환경 구축

그림과 같이 프로젝트, 관련 항아리 패키지 아파치 평민 - 파일 업로드 파일 업로드 구성 요소의 추가를 만들 FileUploadAndDownload.

6c8ca398701946b69c31787994edcd18.png

도 항아리 패키지 (20) 가져 오기

 

업로드 파일

다음과 같이 ● 쓰기 파일 업로드 페이지는 upload.jsp 페이지 코드는 다음과 같습니다

<% @ 페이지 언어 = "자바"의 contentType = "text / html과; 문자셋 = UTF-8"

    pageEncoding = "UTF-8"%>

<! DOCTYPE html로>

<HTML>

<head>

<메타 캐릭터 = "UTF-8">

<제목> 밴드 브라더스의 IT 교육 </ 제목>

</ head>

<body>

    <양식 액션 = "$ {pageContext.request.contextPath} / 업로드"

        에 enctype = "multipart / form-data"에있어서 = "POST">

        업로드 사용자 : <입력 유형 = "텍스트"이름 = "사용자 이름"> /> <br

        업로드 파일 1 : <입력 유형 = "파일"이름 = "파일 1"> /> <br

        업로드 파일 2 : <입력 유형 = "파일"이름 = "파일 2"> /> <br

        <input 타입 = "제출"값 = "提交">

    </ FORM>

   </ body>

</ HTML>

● 메시지를 작성 다음과 같이 페이지, message.jsp 페이지 코드는 메시지를 표시합니다

<% @ 페이지 언어 = "자바"의 contentType = "text / html과; 문자셋 = UTF-8"

    pageEncoding = "UTF-8"%>

<! DOCTYPE html로>

<HTML>

<head>

<메타 캐릭터 = "UTF-8">

<제목> 밴드 브라더스의 IT 교육 </ 제목>

</ head>

<body>

    $ {메시지}

</ body>

</ HTML>

● 쓰기 처리 파일 업로드 서블릿

패키지 com.xdl.servlet;

수입 java.io.File에;

수입 java.io.FileOutputStream의;

수입 때 java.io.IOException;

수입 java.io.InputStream를;

수입은 java.util.List;

수입 javax.servlet.ServletException;

수입 인 javax.servlet.http.HttpServlet;

수입 나오는 javax.servlet.http.HttpServletRequest;

수입의 javax.servlet.http.HttpServletResponse;

수입 org.apache.commons.fileupload.FileItem;

수입 org.apache.commons.fileupload.disk.DiskFileItemFactory;

수입 org.apache.commons.fileupload.servlet.ServletFileUpload;

공용 클래스에서 UploadServelt는 HttpServlet을 확장 {

    개인 정적 최종 길이의 serialVersionUID = 1L;

    공공 무효 서비스 (HttpServletRequest의 요청,

        HttpServletResponse를 응답) ServletException을, IOException가 {던졌습니다

        당신은 파일 업로드를 저장 한 위치 디렉토리를 얻을 //의 WEB-INF 디렉토리에 저장된 파일을 업로드,

        // 업로드 된 파일의 안전을 보장하기 위해 외부 세계에 직접 액세스를 허용하지 않습니다

        문자열 savePath = this.getServletContext ().

                             getRealPath ( "/ WEB-INF / 업로드");

        파일 파일 = 새로운 파일 (savePath);

        당신이 존재 업로드 할 파일을 저장 한 디렉토리를 판별 //

        만약 (! file.exists () &&! file.isDirectory ()) {

             에서 System.out.println (savePath + "디렉토리는 생성 할 필요가 존재하지 않는");

             디렉토리를 생성 //

             file.mkdir ();

        }

        // 메시지 프롬프트

        문자열 메시지 = "";

        {시도

             // 아파치 파일 업로드 컴포넌트 파일 업로드 프로세스 단계를 사용 :

             1 // 공장을 만들기 DiskFileItemFactory

             DiskFileItemFactory 공장 = 새로운 DiskFileItemFactory ();

             // 2, 파일 업로드 파서를 만들

             ServletFileUpload 업로드 = 새로운 ServletFileUpload (공장);

             중국 깨진 업로드 파일 이름을 해결 //

             upload.setHeaderEncoding ( "UTF-8");

             // 3까지 제출 된 데이터는 데이터가 업로드 양식입니다 여부를 확인하는 방법

             만약 (! ServletFileUpload.isMultipartContent (요청)) {

                  // 전통적인 방법으로 데이터를 얻을

                  반환;

             }

             // 4, ServletFileUpload 파서 업로드 데이터,

             //은 해상도 결과가 목록 <FileItem> 모음입니다 반환

             // 각 양식 FileItem 폼 엔트리에 대응

             목록 <FileItem> = upload.parseRequest리스트 (요청);

             {(목록 FileItem 항목)에 대한

                  // fileitem는 일반 데이터 입력에 캡슐화되어있는 경우

                  경우 (item.isFormField ()) {

                        문자열 이름 = item.getFieldName ();

                        // 일반 중국어 데이터 입력 쓰레기 문제를 해결하기

                        문자열 값 = item.getString ( "UTF-8");

                        에서 System.out.println (이름 + "="+ 값);

                  } 그밖에 {// 패키지는 fileitem 업로드하는 경우

                        // 파일의 이름을 업로드 할 수,

                        문자열 파일명 = item.getName ();

                        에서 System.out.println (이름);

                        경우 (파일 이름 == null의 || filename.trim (). 등호 ( "")) {

                        잇다;

                        }

                         // 핸들은 파일 이름의 일부만 남겨두고, 파일 이름의 파일 업로드 부분에 대한 경로를 얻을 수 있습니다

                         파일명 = filename.substring

                                          (filename.lastIndexOf ( "\\ ') + 1);

                         // 스트림에 입력 업로드 된 파일의 항목을 가져 오기

                         에서의 InputStream item.getInputStream = ();

                         파일 출력 스트림을 작성합니다 //

                         =을 FileOutputStream에

                                    새로운 FileOutputStream에 (savePath + "\\"+ 파일 이름);

                         버퍼를 생성 //

                         바이트 버퍼 [] = 새로운 바이트 [1024];

                         // 데이터 입력 스트림 식별자로부터 판독되었는지의 여부를 판단

                         INT LEN = 0;

                         // 버퍼로 루프 입력 스트림 어떤

                         (렌 = in.read (완충액))> 0이되는 데이터가 존재한다는 것을 의미

                         반면 (LEN (= in.read (완충액))> 0) {

                         out.write (버퍼 0 렌);

                         }

                         입력 스트림을 닫고 //

                         넣다();

                         출력 스트림을 닫고 //

                         out.close ();

                         업로드 된 파일을 처리 할 때 // 임시 파일이 생성, 삭제

                         item.delete ();

                        메시지는 "파일 업로드!";

                  }

             }

        } 캐치 (예외 전자) {

             메시지 = "파일 업로드 실패!";

             e.printStackTrace ();

        }

        request.setAttribute ( "메시지", 메시지);

        request.getRequestDispatcher ( "/ message.jsp") 전방 (요청, 응답).;

     }

    }

● web.xml 파일에 UploadServelt은 등록.

    <? XML 버전 = "1.0"인코딩 = "UTF-8"?>

    <웹 응용 프로그램의 xmlns : XSI = "http://www.w3.org/2001/XMLSchema-instance"

    의 xmlns = "http://xmlns.jcp.org/xml/ns/javaee"

    XSI :의 schemaLocation = "http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"

    버전 = "3.1">

    <서블릿>

        <서블릿 이름>에서 UploadServelt </ 서블릿 이름>

        <서블릿 클래스> com.xdl.servlet.UploadServlet </ 서블릿 클래스>

    </ 서블릿>

    <서블릿 매핑>

        <서블릿 이름>에서 UploadServelt </ 서블릿 이름>

        <URL 패턴> / 업로드 </ URL 패턴>

    </ 서블릿 매핑>

</ 웹 응용 프로그램>

Tomcat 서버 시작 동작 21, 22, 23 및도 24을 초래한다.

a161af66c7d446988cf2eb7ec9aa8ef8.png

 21 개 업로드 된 파일

 

3b9d0f2020254f32aa65cbdaac1b5b98.png

22 개 성공적인 업로드 파일

 

3fdafd5d22ea4d93914aca163ddcc8ba.png

23 콘솔 업로드 할 파일의 이름을 인쇄

 

f48c3bce9860452a8cb6e27dc12f705a.png

(24) 서버는 클라이언트 파일 업로드를 수신

 

파일 업로드 정보

위의 코드가 성공적으로 위의 지정된 디렉토리 서버에 파일을 업로드 할 수 있지만, 많은 작은 세부 사항 파일 업로드 기능이 관심을 지불 할 필요가 있지만, A는 몇 가지 아래에 특별한주의가 필요합니다

● 서버 보안을 보장하기 위해, 업로드 파일은 WEB-INF 디렉토리에 넣어 같은 직접 외부 세계에 액세스 할 수있는 디렉토리에 배치해야합니다.

● 업로드 된 파일의 고유 한 파일 이름을 생성하는 현상을 포함하는 문서를 방지합니다.

●는 디렉토리 아래에 너무 많은 파일을 방지 저장소를 파괴하기 위해 해시 알고리즘을 사용합니다.

● 최대 업로드 파일을 제한합니다.

● 당신이받을 때 접미사의 적법성을 결정하기 위해, 파일 이름을 업로드, 업로드 파일 형식을 제한합니다.

●  针对上述提出的5点细节问题,我们来改进一下UploadServlet,改进后的代码如下:

package com.xdl.servlet;

import java.io.File;

import java.io.FileOutputStream;

import java.io.IOException;

import java.io.InputStream;

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.ProgressListener;

import org.apache.commons.fileupload.disk.DiskFileItemFactory;

import org.apache.commons.fileupload.servlet.ServletFileUpload;

public class UploadServlet extends HttpServlet {

    private static final long serialVersionUID = 1L;

    public void service(HttpServletRequest request,

         HttpServletResponse response) throws ServletException, IOException {

        // 得到上传文件的保存目录,将上传的文件存放于WEB-INF目录下,

        // 不允许外界直接访问,保证上传文件的安全

        String savePath = this.getServletContext().getRealPath("/WEB-INF/upload");

        // 上传时生成的临时文件保存目录

        String tempPath = this.getServletContext().getRealPath("/WEB-INF/temp");

        File tmpFile = new File(tempPath);

        if (!tmpFile.exists()) {

             // 创建临时目录

             tmpFile.mkdir();

        }

        // 消息提示

        String message = "";

        try {

             // 使用Apache文件上传组件处理文件上传步骤:

             // 1、创建一个DiskFileItemFactory工厂

             DiskFileItemFactory factory = new DiskFileItemFactory();

             // 设置工厂的缓冲区的大小,当上传的文件大小超过缓冲区的大小时,

             //就会生成一个临时文件存放到指定的临时目录当中。

             factory.setSizeThreshold(1024 * 100);

             // 设置缓冲区的大小为100KB,如果不指定,那么缓冲区的大小默认是10KB

             // 设置上传时生成的临时文件的保存目录

             factory.setRepository(tmpFile);

             // 2、创建一个文件上传解析器

             ServletFileUpload upload = new ServletFileUpload(factory);

             // 监听文件上传进度

             upload.setProgressListener(new ProgressListener() {

                  public void update(long pBytesRead, long pContentLength,

                             int arg2) {

                    System.out.println("文件大小为:" + pContentLength

                                 + ",当前已处理:" + pBytesRead);

                  }

             });

             // 解决上传文件名的中文乱码

             upload.setHeaderEncoding("UTF-8");

             // 3、判断提交上来的数据是否是上传表单的数据

             if (!ServletFileUpload.isMultipartContent(request)) {

                  // 按照传统方式获取数据

                  return;

             }

             // 设置上传单个文件的大小的最大值,目前是设置为1024*1024字节,也就是1MB

             upload.setFileSizeMax(1024 * 1024);

             // 设置上传文件总量的最大值

             upload.setSizeMax(1024 * 1024 * 10);

             // 4、使用ServletFileUpload解析器解析上传数据,解析结果返回的是一个

             // List<FileItem>集合,每一个FileItem对应一个Form表单的输入项

             List<FileItem> list = upload.parseRequest(request);

             for (FileItem item : list) {

                  // 如果fileitem中封装的是普通输入项的数据

                  if (item.isFormField()) {

                     String name = item.getFieldName();

                      // 解决普通输入项的数据的中文乱码问题

                      String value = item.getString("UTF-8");

                      System.out.println(name + "=" + value);

                  } else {// 如果fileitem中封装的是上传文件

                        // 得到上传的文件名称

                      String filename = item.getName();

                      System.out.println(filename);

                      if (filename == null || filename.trim().equals("")) {

                        continue;

                       }

                      // 处理获取到的上传文件的文件名的路径部分,只保留文件名部分

                      filename = filename.substring(

                                 filename.lastIndexOf("\\") + 1);

                       // 得到上传文件的扩展名

                       String fileExtName =

                               filename.substring(filename.

                               lastIndexOf(".") + 1);

                      // 如果需要限制上传的文件类型,那么可以通过文件的扩展名来判断上

                      // 传的文件类型是否合法

                      System.out.println("上传的文件的扩展名是:" + fileExtName);

                      // 获取item中的上传文件的输入流

                       InputStream in = item.getInputStream();

                       // 得到文件保存的名称

                       String saveFilename = makeFileName(filename);

                       // 得到文件的保存目录

                       String realSavePath = makePath(saveFilename, savePath);

                      // 创建一个文件输出流

                      FileOutputStream out = new FileOutputStream

                                         (realSavePath + "\\" + saveFilename);

                      // 创建一个缓冲区

                       byte buffer[] = new byte[1024];

                      // 判断输入流中的数据是否已经读完的标识

                      int len = 0;

                       // 循环将输入流读入到缓冲区当中

                       while ((len = in.read(buffer)) > 0) {

                         out.write(buffer, 0, len);

                      }

                      // 关闭输入流

                      in.close();

                      // 关闭输出流

                      out.close();

                      // 删除处理文件上传时生成的临时文件

                      // item.delete();

                      message = "文件上传成功!";

                  }

             }

        } 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();

        }

        request.setAttribute("message", message);

        request.getRequestDispatcher("/message.jsp").

                 forward(request, response);

    }

    private String makeFileName(String filename) {

        // 为防止文件覆盖的现象发生,要为上传文件产生一个唯一的文件名

        return UUID.randomUUID().toString() + "_" + filename;

    }

    /**

     * 为防止一个目录下面出现太多文件,要使用hash算法打散存储

     */

    private String makePath(String filename, String savePath) {

        // 得到文件名的hashCode的值,得到的就是filename这个字符串对象在内存中的地址

        int hashcode = filename.hashCode();

        int dir1 = hashcode & 0xf;

        int dir2 = (hashcode & 0xf0) >> 4;

        // 构造新的保存目录

        String dir = savePath + "\\" + dir1 + "\\" + dir2;

        // 파일이 두 파일은 또한 디렉토리를 표시 나타낼 수

        파일 파일 = 새로운 파일 (디렉토리);

        // 디렉토리가 존재하지 않는 경우

        만약 (! file.exists ()) {

             디렉토리를 생성 //

             file.mkdirs ();

        }

        디렉토리를 반환;

    }

}

5시 작은 세부 사항에 대한 개선은 위에 명시된 다음에는 더 완벽 할 경우에도, 우리는 업로드 기능을 파일.

추천

출처www.cnblogs.com/itxdl/p/10961955.html