Java Servlet ファイルアップロードの基本

管理人のわかりにくいコードよりも、以下に説明されているのが、一番シンプルでわかりやすいかと思い、リンクを貼っておきます。

Qiitaのリンク : https://qiita.com/ohke/items/bec00a69d3f538aab06b

[ 説明・感想 ]

  1. アノテーションを使っているので、web.xmlの記述がなくすっきりしている (最近はこれが普通か)
  2. 送信用ページでのクライアントのファイル名が使われ、サーバー内の隠蔽されたパスに保存されてるが、実際は違う名前で、別に設定されたパスに保存されることが多いと思います。
  3. サーバー内である場合、再配備の時に消えてしまうので、永続的利用を前提とした場合、上 2) が現実的
  4. あくまで、説明用としてご紹介して下さってるサンプルに、けちつけるのは控えます。
  5. JSP側で、ファイルサイズの制限をJavascriptで設定するのが、大容量アップロードを未然回避する為、重要と思いますが、servlet3の maxFileSize で制御出来るので、二重防御、将来的Javascript仕様変更の影響を受けず無難。
  6. マルチファイルの場合は、request.getParts()で配列でとれるので、ループして保存出来ます。

JAVA 本番環境リリース時変更をなくす (プロキシサーバー)

開発環境がプロキシなし, 実行環境がプロキシありの場合、そのままでは動かないので、違う設定する必要ありますが、最小限に済ます方法です。
プロキシの設定は、httpclient, seleniumのconnect, jsoupのconnect, curlのシェル実行とかで多用するので、どこに居ても開発がはかどります。

1) web.xmlに使うか使わないかを設定


   <!-- Use proxy or not for curl command -->
  <context-param>
    <param-name>IsUseProxy</param-name> <param-value>0</param-value>
  </context-param>

2) 判別と、使う場合のcurlコマンドに使う引数を、静的設定用クラスに定義


  /**
   * プロキシ利用フラグ
   */
  public static boolean isUseProxy = false;
  /**
   * curl用プロキシ引数
   */
  public static final String ARG_PROXY_CURL = "--proxy http://10.70.1.80:8080";

3) JSPでの利用例


  // クレジットバランス用 //
  ServletContext cntxt = getServletContext();
  String crblcURL = cntxt.getInitParameter("CreditBalanceURL");
 
  crblc.setIsUseProxy(DBini.isUseProxy);

  crblc.setUrl(crblcURL);
  String crrest = crblc.getCreditBalance();
  pageContext.setAttribute("crrest", crrest);

        // == ツールバー == //
        var htmlds = 'From ' + "${dtpcsumsel}" +
                '<span style="margin-left:12px;">' + '${crrest}' + '</span>';
        $('#t_pcsum').prepend(htmlds); // 後でリフレッシュボタンを付けてるのでprepend

  /**
   * curlでクレジットバランス取得
   *
   * @return 文字列
   */
  public String getCreditBalance() {

    int res = 0;
    String proxy = this.isUseProxy ? DBini.ARG_PROXY_CURL: "";

    // コマンド文字列作成 //
    String curcmd = "curl -k --connect-timeout 5 " + proxy + " " + url;
    System.out.println(curcmd);

    String restxt = "";
    try {

      Runtime runtime = Runtime.getRuntime();
      Process p = runtime.exec(curcmd);
      InputStream is = p.getInputStream();

      // レスポンス取得 //
      int nread;
      byte[] rbuf = new byte[500];
      while ((nread = is.read(rbuf)) > 0) {
      }
      restxt = new String(rbuf, "US-ASCII");

    }
    catch (Exception e) {
      e.printStackTrace();
    }
    System.out.println(restxt);

    String blctxt = "";
    if (restxt != null) {
      int crblcstpos = restxt.indexOf("CREDIT_BALANCE=\"");
      int lastchgpos = restxt.indexOf("\" LAST_CHARGED");
      if (crblcstpos != -1 && lastchgpos != -1) {
        blctxt = restxt.substring(crblcstpos + 16, lastchgpos);
      }
      if (blctxt.indexOf("Connection timed out") > -1) {
        blctxt = "TimedOut";
      }
      if (blctxt.equals("")) {
        blctxt = "No Response";
      }
      return blctxt;
    }
    // エラー //
    else {     
      return "Error";
    }
  }

4) Servletでの利用例


    // コマンド //
    String curlcmd = "curl -k " + (DBini.isUseProxy ? DBini.ARG_PROXY_CURL: "")
            + (isSimple ? DBini.vesselPositionURLSimple : DBini.vesselPositionURL) + imo;
    System.out.println(curlcmd);

    // 開始時間取得 //
    long startTime = System.currentTimeMillis();

    VesselPosition vsp = new VesselPosition(DBini.tmNowFmt());

    String restxt = "";
    try {

      Runtime runtime = Runtime.getRuntime();
      Process p = runtime.exec(curlcmd);
      InputStream is = p.getInputStream();

      // レスポンス取得 //
      int nread;
      byte[] rbuf = new byte[2048];
      while ((nread = is.read(rbuf)) > 0) {
      }
      restxt = new String(rbuf, "US-ASCII");

    }
    catch (Exception e) {
      e.printStackTrace();
      vsp.setResmsg(this.FAIL_MESSAFE);
    }

JAVA 本番環境リリース時変更をなくす (ファイルアップロード)

開発環境がWindows, 実行環境がLinuxの場合、そのままでは動かないので、違う設定する必要ありますが、最小限に済ます方法です。

1) web.xmlの記述で、URIを違えた2種類の設定を入れる (アノテーションでも出来ると思うが慣れてないので)


  <!-- ***** Excel Goods master upload **** -->
  <!-- Windows -->
  <servlet>
    <servlet-name>ExcelCheckWin</servlet-name>
    <servlet-class>dnksg.svlt.mstupld.ExcelCheck</servlet-class>
    <multipart-config>
      <max-file-size>-1</max-file-size>
      <max-request-size>-1</max-request-size>
      <file-size-threshold>0</file-size-threshold>
      <location>D:\\#NBTest\\dnksgDocumentTmp</location>
    </multipart-config>
    <init-param>
      <param-name>UploadPath</param-name>
      <param-value>D:\\#NBTest\\dnksgDocumentTmp\\</param-value>
    </init-param>
  </servlet>
  
  <!-- Linux -->
  <servlet>
    <servlet-name>ExcelCheckLin</servlet-name>
    <servlet-class>dnksg.svlt.mstupld.ExcelCheck</servlet-class>
    <multipart-config>
      <max-file-size>-1</max-file-size>
      <max-request-size>-1</max-request-size>
      <file-size-threshold>0</file-size-threshold>
      <location>/home/dnksgDocumentTmp</location>
    </multipart-config>
    <init-param>
      <param-name>UploadPath</param-name>
      <param-value>/home/dnksgDocumentTmp/</param-value>
    </init-param>
  </servlet> 
  
  <!-- Windows -->
  <servlet-mapping>
    <servlet-name>ExcelCheckWin</servlet-name>
    <url-pattern>/ExcelCheckWin</url-pattern>
  </servlet-mapping>
  
  <!-- Linux -->    
  <servlet-mapping>  
    <servlet-name>ExcelCheckLin</servlet-name>
    <url-pattern>/ExcelCheckLin</url-pattern>
  </servlet-mapping>  

2) JSPでファイルセパレータからWindows or Linuxを判別して、pageContextにセット


// Linux or Windows //
  boolean isLin = System.getProperty("file.separator").equals("/");
  pageContext.setAttribute("LW", isLin ? "Lin" : "Win");

3) 2)をJavascriptのconstな変数にセット


    <script type="text/javascript">

      const LW = '${LW}';

4) dropzone.js の 送信先URL末尾で 3)を使う


 // 送信先URL //
  const UPLOAD_URLS = ['ImageUpload', 'FileUploadMulti', 'FileUploadMulti', 'AmazonDocUpload'];
$('#' + itm).dropzone({
      url: UPLOAD_URLS[j] + LW + "?dropzone=1&userid=" + ID_USER + UPLOAD_KIND_PARAMS[j],
[商品価格に関しましては、リンクが作成された時点と現時点で情報が変更されている場合がございます。]

Tomcatハンドブック
価格:5170円(税込、送料無料) (2023/1/11時点)