欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Servlet3.0實現(xiàn)文件上傳的方法

 更新時間:2017年03月27日 14:15:32   作者:Lucky_Light  
本篇文章主要介紹了Servlet實現(xiàn)文件上傳的方法,所謂文件上傳就是將本地的文件發(fā)送到服務(wù)器中保存。有興趣的可以了解一下。

Servlet 實現(xiàn)文件上傳

所謂文件上傳就是將本地的文件發(fā)送到服務(wù)器中保存。例如我們向百度網(wǎng)盤中上傳本地的資源或者我們將寫好的博客上傳到服務(wù)器等等就是典型的文件上傳。

Servlet 3.0

上次完成文件下載功能使用的是 Servlet 2.5,但是想要完成文件上傳,那么繼續(xù)使用 Servlet 2.5 肯定不是一個好的選擇,因此我們使用 Servlet 3.0 來完成文件上傳。下面我來簡單介紹一下 Servlet 3.0 的新特性:

1、新增的注解支持

該版本新增了若干注解,用于簡化 Servlet、過濾器(Filter)和監(jiān)聽器(Listener)的聲明,這使得 web.xml 部署描述文件從該版本開始不再是必選的了。

2、HttpServletRequest 對文件上傳的支持

此前,對于處理上傳文件的操作一直是讓開發(fā)者頭疼的問題,因為 Servlet 本身沒有對此提供直接的支持,需要使用第三方框架來實現(xiàn),而且使用起來也不夠簡單。如今這都成為了歷史,Servlet 3.0 已經(jīng)提供了這個功能,而且使用也非常簡單。
Servlet 3.0 的新特性當(dāng)然肯定不止這些,但是其他的新特性在這里我們暫時還用不到,也就不做過多了解了。

必要條件

想要完成文件上傳,肯定不是這么簡單,它對瀏覽器端和服務(wù)器端都有許多的要求。

對瀏覽器的要求

  1. 一個文件的大小一般肯定不止 1 KB,既然這樣,那么要上傳一個文件肯定不能使用 get 方式了,所以上傳文件時必須采用 post 方式。
  2. 2.表單中必須有一個文件上傳項 <input type="file"> ,而且必須有 name 屬性。
  3. 必須設(shè)置表單的 enctype 屬性值為 multipart/form-data。

對服務(wù)器的要求:

  1. 當(dāng)然,我們肯定得使用 Servlet 3.0。
  2. Servlet 3.0 中接收普通上傳組件(除了文件上傳組件)通過 request.getParameter(String)接收,而文件上傳組件通過 request.getPart(String)接收。
  3. Servlet 3.0 要求服務(wù)器必須是 Tomcat7 及其以上。

準(zhǔn)備工作

工欲善其事,必先利其器。

1、首先,打開 Eclipse,新建一個 Dynamic Web Project。

2、鍵入項目名,選擇運行時環(huán)境為 Apache Tomcat v7.0,選擇 Servlet 版本為 3.0,然后點擊 Finished。

3、在項目的 WebContent 目錄下,新建一個文件夾 upload,用來存放上傳過來的文件。

4、在 WebContent 目錄下新建一個 index.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
 pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
 <head>
   <meta charset="UTF-8">
   <title>上傳</title>
 </head>

 <body>
   <form action="${pageContext.request.contextPath}/UploadServlet" method="post" enctype="multipart/form-data">
     <label>選擇一個文件:</label>
     <input type="file" name="file"><br>
     <input type="submit" value="上傳"><br>
   </form>
 </body>
</html>

5、使用 Tomcat 將次項目發(fā)布,并在瀏覽器中預(yù)覽。

將服務(wù)器啟動,然后在瀏覽器中輸入:http://localhost:8080/upload

好吧!樣子有點丑,希望不要介意!如果出現(xiàn)以上界面,那么,準(zhǔn)備工作就完成了!

完成案例

首先,新建一個 Servlet,在 Servlet 3.0 我們不必再為配置 web.xml 而煩惱了,只要要在 Servlet 的類名上面一行添加一個注解:

@WebServlet("/UploadServlet")

這個注解就相當(dāng)與 Servlet 2.5 中的:

<servlet>
  <servlet-name>UploadServlet</servlet-name>
  <servlet-class>club.luckylight.upload.UploadServlet</servlet-class>
</servlet>
<servlet-mapping>
  <servlet-name>UploadServlet</servlet-name>
  <url-pattern>/UploadServlet</url-pattern>
</servlet-mapping>

這樣比較,使用注解不是簡便了很多。

然后,我們還需要添加另一個注解:

@MultipartConfig

該注解主要是為了輔助 Servlet 3.0 中 HttpServletRequest 提供的對上傳文件的支持。該注解標(biāo)注在 Servlet 上面,以表示該 Servlet 希望處理的請求的 MIME類型 是 multipart/form-data

接下來,我們就需要根據(jù)上傳組件的 name 屬性獲取它了。這里我們使用 Path request.getPart(String) 方法。

Part part = request.getPart("file");

然后,我們就需要根據(jù) part 獲取頭信息,然后根據(jù)頭信息獲取文件的路徑。

在瀏覽器抓包,獲取頭信息為:

據(jù)此,我們可以獲取文件名或者文件路徑。

String header = part.getHeader("content-disposition");
String path = header.substring(header.indexOf("filename=") + 10, header.length() - 1);

由于獲取的有可能是文件名,也有可能是文件路徑,為此,有必要編寫一個工具類,用來獲取文件的真實名稱。

/**
 * 根據(jù)文件的路徑獲取文件真實名稱
 * 
 * @param path
 *      文件的路徑
 * @return 文件名稱
 */
public static String getRealName(String path) {
  int index = path.lastIndexOf("\\");

  if (index == -1) {
    index = path.lastIndexOf("/");
  }

  return path.substring(index + 1);
}

然后,調(diào)用這個方法,獲得文件名。

String name = UploadUtils.getRealName(path);

接下來,我們有必要,給每個文件分配一個存放目錄,因此我又編寫了一個方法,用來生成一個目錄。

/**
 * 根據(jù)文件名返回一個目錄
 * 
 * @param name
 *      文件名稱
 * @return 目錄
 */
public static String getDir(String name) {
  int i = name.hashCode();
  String hex = Integer.toHexString(i);
  int j = hex.length();

  for (int k = 0; k < 8 - j; k++) {
    hex = "0" + hex;
  }

  return "/" + hex.charAt(0) + "/" + hex.charAt(1);
}

到此,萬事俱備,只欠東風(fēng)。我們只需要將文件拷貝到服務(wù)器。

// 獲取文件的真實路徑
String realPath = this.getServletContext().getRealPath("/upload" + dir);
File file = new File(realPath);

if (!file.exists()) {
  file.mkdirs();
}

// 獲取輸入流
InputStream inputStream = part.getInputStream();
// 定義輸出流
FileOutputStream outputStream = new FileOutputStream(new File(file, name));

// 從輸入流中讀入數(shù)據(jù)并寫到輸出字節(jié)流中
int len = -1;
byte[] bytes = new byte[1024];
while ((len = inputStream.read(bytes)) != -1) {
  outputStream.write(bytes, 0, len);
}

// 關(guān)閉資源
outputStream.close();
inputStream.close();

// 刪除臨時文件
part.delete();

下面來測試一下:

然后,在 Tomcat webapps -> 項目名 -> upload 中就可以找到上傳成功的文件了!

最后,我們打開音樂來試驗下是否真的上傳成功了?

嗯!薛之謙低沉的聲音從耳機(jī)中傳來,看來確實是上傳成功了!

完整代碼

UploadServlet.java

package club.luckylight.upload;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;

import javax.servlet.ServletException;
import javax.servlet.annotation.MultipartConfig;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.Part;

import club.luckylight.util.UploadUtils;

@WebServlet("/UploadServlet")
@MultipartConfig
public class UploadServlet extends HttpServlet {

  private static final long serialVersionUID = 5661013723204858883L;

  protected void doGet(HttpServletRequest request, HttpServletResponse response)
      throws ServletException, IOException {
    // 獲取文件上傳組件
    Part part = request.getPart("file");

    // 獲取文件的路徑
    String header = part.getHeader("content-disposition");
    String path = header.substring(header.indexOf("filename=") + 10, header.length() - 1);

    // 獲取文件名
    String name = UploadUtils.getRealName(path);

    // 獲取文件的存放目錄
    String dir = UploadUtils.getDir(name);

    String realPath = this.getServletContext().getRealPath("/upload" + dir);
    File file = new File(realPath);
    if (!file.exists()) {
      file.mkdirs();
    }

    // 對拷流
    InputStream inputStream = part.getInputStream();
    FileOutputStream outputStream = new FileOutputStream(new File(file, name));
    int len = -1;
    byte[] bytes = new byte[1024];
    while ((len = inputStream.read(bytes)) != -1) {
      outputStream.write(bytes, 0, len);
    }

    // 關(guān)閉資源
    outputStream.close();
    inputStream.close();

    // 刪除臨時文件
    part.delete();

    response.setContentType("text/html;charset=utf-8");
    response.getWriter().print("文件" + name + "上傳成功!");
  }

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

}

UploadUtils.java

package club.luckylight.util;

public class UploadUtils {

  /**
   * 根據(jù)文件的路徑獲取文件真實名稱
   * 
   * @param path
   *      文件的路徑
   * @return 文件名稱
   */
  public static String getRealName(String path) {
    int index = path.lastIndexOf("\\");

    if (index == -1) {
      index = path.lastIndexOf("/");
    }

    return path.substring(index + 1);
  }

  /**
   * 根據(jù)文件名返回一個目錄
   * 
   * @param name
   *      文件名稱
   * @return 目錄
   */
  public static String getDir(String name) {
    int i = name.hashCode();
    String hex = Integer.toHexString(i);
    int j = hex.length();

    for (int k = 0; k < 8 - j; k++) {
      hex = "0" + hex;
    }

    return "/" + hex.charAt(0) + "/" + hex.charAt(1);
  }
}

總結(jié)

這樣,文件上傳案例就完成了,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • SpringBoot限制文件或圖片上傳大小的兩種配置方法

    SpringBoot限制文件或圖片上傳大小的兩種配置方法

    這篇文章主要介紹了SpringBoot限制文件或圖片上傳大小的兩種配置方法,一種是配置在啟動類中,一種是配置在application.yml或者application.properties中,需要的朋友可以參考下
    2018-03-03
  • 簡述mybatis大于小于的轉(zhuǎn)義

    簡述mybatis大于小于的轉(zhuǎn)義

    這篇文章主要介紹了mybatis大于小于的轉(zhuǎn)義以及xml中常用轉(zhuǎn)義字符,非常不錯,具有參考借鑒價值,需要的朋友可以參考下
    2016-09-09
  • MyBatis使用動態(tài)表或列代碼解析

    MyBatis使用動態(tài)表或列代碼解析

    這篇文章主要介紹了MyBatis使用動態(tài)表或列代碼解析,分享了相關(guān)代碼示例,小編覺得還是挺不錯的,具有一定借鑒價值,需要的朋友可以參考下
    2018-02-02
  • 濫用@PathVariable導(dǎo)致bug原因分析解決

    濫用@PathVariable導(dǎo)致bug原因分析解決

    這篇文章主要為大家介紹了濫用@PathVariable導(dǎo)致bug原因分析解決,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-12-12
  • SpringBoot整合SpringSecurityOauth2實現(xiàn)鑒權(quán)動態(tài)權(quán)限問題

    SpringBoot整合SpringSecurityOauth2實現(xiàn)鑒權(quán)動態(tài)權(quán)限問題

    這篇文章主要介紹了SpringBoot整合SpringSecurityOauth2實現(xiàn)鑒權(quán)-動態(tài)權(quán)限,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2022-06-06
  • Java SpringBoot在RequestBody中高效的使用枚舉參數(shù)原理案例詳解

    Java SpringBoot在RequestBody中高效的使用枚舉參數(shù)原理案例詳解

    這篇文章主要介紹了Java SpringBoot在RequestBody中高效的使用枚舉參數(shù)原理案例詳解,本篇文章通過簡要的案例,講解了該項技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下
    2021-09-09
  • Spring Boot 實例代碼之通過接口安全退出

    Spring Boot 實例代碼之通過接口安全退出

    這篇文章主要介紹了Spring Boot 實例代碼之通過接口安全退出的相關(guān)資料,需要的朋友可以參考下
    2017-09-09
  • SpringBoot?SpringSecurity?JWT實現(xiàn)系統(tǒng)安全策略詳解

    SpringBoot?SpringSecurity?JWT實現(xiàn)系統(tǒng)安全策略詳解

    Spring?Security是Spring的一個核心項目,它是一個功能強(qiáng)大且高度可定制的認(rèn)證和訪問控制框架。它提供了認(rèn)證和授權(quán)功能以及抵御常見的攻擊,它已經(jīng)成為保護(hù)基于spring的應(yīng)用程序的事實標(biāo)準(zhǔn)
    2022-11-11
  • 基于SpringMVC攔截器實現(xiàn)接口耗時監(jiān)控功能

    基于SpringMVC攔截器實現(xiàn)接口耗時監(jiān)控功能

    本文呢主要介紹了基于SpringMVC攔截器實現(xiàn)的接口耗時監(jiān)控功能,統(tǒng)計接口的耗時情況屬于一個可以復(fù)用的功能點,因此這里直接使用 SpringMVC的HandlerInterceptor攔截器來實現(xiàn),需要的朋友可以參考下
    2024-02-02
  • Spring ApplicationListener的使用詳解

    Spring ApplicationListener的使用詳解

    這篇文章主要介紹了Spring ApplicationListener的使用,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-06-06

最新評論