Web系開発メモ

Java, C#, HTML, CSS, JavaScript のことなどを書いてます。

Servlet ファイルをアップロードする方法

ブラウザからアップロードしたファイルを、サーブレットで保存する方法を書いていきます。

バージョン

サーブレットのバージョンは以下の通りです。

動作確認用プロダクト

動作確認のために、以下の製品を使用しました。

目次

  1. サーブレットの作成
  2. HTMLの作成
  3. ディレクトリ階層の作成
  4. pom.xml の作成
  5. 動作確認

1. サーブレットの作成

アップロードされたファイルを、所定のディレクトリに保存するクラスを作成します。

org/example/upload/FileUploadServlet.java

package org.example.upload;

import java.io.File;
import java.io.IOException;
import java.util.concurrent.atomic.AtomicInteger;

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

@SuppressWarnings("serial")
@WebServlet("/upload/file")
@MultipartConfig(
  fileSizeThreshold = 1024 * 1024,  // 1MB
  maxFileSize= 1024 * 1024 * 10,  // 10MB
  maxRequestSize = 1024 * 1024 * 50  // 50MB
)
public class FileUploadServlet extends HttpServlet {
  // ファイル通番
  private static final AtomicInteger id = new AtomicInteger();
  // ファイル保存先
  private static final File uploadDir = new File("C:/tmp");
  public void init() throws ServletException {
    // サーブレット初期化時に保存先を作成
    uploadDir.mkdir();
  }

  public void doPost(HttpServletRequest req, HttpServletResponse res)
    throws ServletException, IOException
  {
    // リクエストのファイルを取得
    Part part = req.getPart("file");
    // 保存用のファイル名を作成("通番_送信ファイル名")
    StringBuilder saveName = new StringBuilder();
    saveName.append(id.incrementAndGet());
    saveName.append("_");
    saveName.append(part.getSubmittedFileName());
    // 保存用のファイルを作成
    File saveFile = new File(
      uploadDir, saveName.toString()
    );
    // ファイルを保存
    part.write(saveFile.getAbsolutePath());
    // レスポンスを返却
    respond(res);
  }
  public void respond(HttpServletResponse res) throws IOException {
    res.setContentType("text/html");
    res.setCharacterEncoding("utf-8");
    res.getWriter().println(
      "<html><body><p>File saved.</p></body></html>"
    );
  }
}

保存用のファイル名は「通番_送信ファイル名」になります。Part クラスのメソッドを使って、ブラウザからアップロードされたファイル名を取得しています。

part.getSubmittedFileName()

2. HTMLの作成

動作確認をする場合、アップロード用の HTML を作成します。

webapp/upload.html

<!DOCTYPE html>
<html>
<head><meta charset="utf-8"></head>
<body>
<form method="POST" enctype="multipart/form-data" action="/upload/file">
  <p><input type="file" name="file"></p>
  <p><input type="submit" value="送信"></p>
</form>
</body>
</html>

form の enctype を「multipart/form-data」にして、ファイルをアップロードできるようにしています。

また、form の action を「/upload/file」にして、リクエストをサーブレットに向けています。

3. ディレクトリ階層の作成

以下のコマンドでプロジェクト sample-servletディレクトリ階層を作成します。

mkdir sample-servlet
cd sample-servlet
mkdir src\main\java
mkdir src\main\webapp\WEB-INF

作成したら、src/main/java 配下にサーブレットのコードを置きます。HTML は src/main/webapp に置きます。

4. pom.xml の作成

フォルダ sample-servletpom.xml を作成します。

pom.xml

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>

  <groupId>org.example</groupId>
  <artifactId>sample-servlet</artifactId>
  <version>1.0.0</version>
  <packaging>war</packaging>

  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
    <maven.compiler.source>17</maven.compiler.source>
    <maven.compiler.target>17</maven.compiler.target>
  </properties>

  <dependencies>
    <dependency>
      <groupId>jakarta.servlet</groupId>
      <artifactId>jakarta.servlet-api</artifactId>
      <version>5.0.0</version>
      <scope>provided</scope>
    </dependency>
  </dependencies>

  <build>
    <finalName>${project.artifactId}</finalName>
    <plugins>
      <plugin>
        <artifactId>maven-war-plugin</artifactId>
        <version>3.4.0</version>
      </plugin>
      <plugin>
        <groupId>org.eclipse.jetty</groupId>
        <artifactId>jetty-maven-plugin</artifactId>
        <version>11.0.15</version>
        <configuration>
          <scan>1</scan>
        </configuration>
      </plugin>
    </plugins>
  </build>
</project>

サーブレットコンテナを起動できるように、build で Jetty Plugin を定義しています。

5. 動作確認

以下のコマンドでコンテナを起動します。

sample-servlet> mvn jetty:run

起動後にブラウザで以下の URL を開きます。

http://localhost:8080/upload.html

画面が開いたら、ファイルを選択して送信します。

処理が完了すると、C:/tmp にファイルが保存されます。