[TOP] [HOME] [AGILE] [OBJECT] [PROGRAMMING] [JAVA] [LINUX] [OKINAWA] [BBS] [DIARY]

File Upload

目次

ファイルアップロードサーブレット

サーブレットでファイルのアップロードをしたいと思い、とりあえずインターネットを調査していたら このページに行き着きました。

Servlet界隈では知る人ぞ知る原田洋子さんのぺーじですね。なーんだ、これでもうファイルアップロードできたも同然じゃん! となめきっていた私は、ちょっとこの後痛い目にあってしまいました。

痛い目って何かというと、単純に複数のファイルアップロードができない!ってただそれだけのことで、しょうがないので、おそれおおくも、原田さんのファイルアップロードサーブレットを改良することにしました。

と言うわけで、ここで公開しているファイルアップロードサーブレットは、全面的に原田さんのソースをパクっているので、詳しい解説は、 原田さんのページを参照して下さい。:-)

Servlet周りのソース

まずは、出発点のサーブレットのソースファイル。

package com.homeunix.doi.servlet;

/**
 * ファイルアップロードサーブレット。
 * @author <A href="mailto:t-doi_AT_bg.wakwak.com">Toshihiko DOI</A>
 * Copyright(C) 2003 Toshihiko DOI. All rights reserved. 
 */
import java.io.PrintWriter;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.Vector;

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletContext;
import javax.servlet.ServletInputStream;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.homeunix.doi.upload.ContentsWriter;
import com.homeunix.doi.upload.MimeTypesInspector;
import com.homeunix.doi.upload.MultiPartParser;
import com.homeunix.doi.upload.UploadPropertyBean;

public class FileUploadServlet extends HttpServlet {
	private ServletContext context = null;
	private int maxSize = 1024 * 1024 * 1; // 1MB
	private MimeTypesInspector inspector = null;
	private String outfilename = null;
	private String nextPage = null;
	private String errorPage = null;

	public void init() throws ServletException {
		context = getServletContext();

		String mimeTypesFile = getInitParameter("mimeTypesFile");
		if (mimeTypesFile == null) {
			mimeTypesFile = context.getRealPath("/conf/mime.types");
		}
		try {
			inspector = MimeTypesInspector.getInstance(mimeTypesFile);
		}
		catch (FileNotFoundException e) {
			throw new ServletException(e.getMessage(), e);
		}
		catch (IOException e) {
			throw new ServletException(e.getMessage(), e);
		}
		outfilename = getInitParameter("outfilename");
		if (outfilename == null) {
			outfilename = "/data/uploadfile";
		}
		nextPage = getInitParameter("nextPage");
		if (nextPage == null) {
			nextPage = "/samples/UploadFile.jsp";
		}
		errorPage = getInitParameter("errorPage");
		if (errorPage == null) {
			errorPage = "/samples/UploadError.jsp";
		}
	}

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

		String contentType = request.getHeader("Content-Type");
		int contentLength = request.getIntHeader("Content-Length");
		if (contentLength > maxSize) {
			RequestDispatcher dispatcher =
				context.getRequestDispatcher(errorPage);
			dispatcher.forward(request, response);
		}
		else {
			ServletInputStream istream = request.getInputStream();
			MultiPartParser parser =
				new MultiPartParser(contentType, contentLength, istream);
			istream.close();
			ContentsWriter writer;
			synchronized (this) {
				writer =
					new ContentsWriter(context, outfilename, parser, inspector);
			}
			writer.write();
			UploadPropertyBean uploadPropertyBean =
				writer.getUploadPropertyBean();
			request.setAttribute("uploadPropertyBean", uploadPropertyBean);
			RequestDispatcher dispatcher =
				context.getRequestDispatcher(nextPage);
			dispatcher.forward(request, response);
		}
	}
}

MultiPartなRequestの解析を行うクラスのソースファイル。

package com.homeunix.doi.upload;

import java.util.*;
import java.io.DataInputStream;
import java.io.InputStream;
import java.io.IOException;
import java.util.Enumeration;
import javax.servlet.ServletInputStream;

/**
 * MutiPart送信データ解析クラス。
 * @author <A href="mailto:t-doi_AT_bg.wakwak.com">Toshihiko DOI</A>
 * Copyright(C) 2003 Toshihiko DOI. All rights reserved. 
 */
public class MultiPartParser {
	private static String boundaryKey = "boundary=";
	private static int separatorSize = 2;
	private String boundary = null;
	private String endBoundary = null;
	private Vector eachParts = new Vector();
	private String contentType = null;

	/**
	 * 個々のパート取り出し。
	 * @return 分割した個々のパートの配列を返す。
	 */
	public Vector getEachParts() {
		return eachParts;
	}

	/**
	 * コンストラクタ。
	 * @param String contentType コンテンツタイプ。
	 * @param int contentLength コンテンツの文字列長。
	 * @param ServletInputStream istream 読み込みもとストリーム。
	 */
	public MultiPartParser(
		String contentType,
		int contentLength,
		ServletInputStream istream)
		throws IOException {
		retrieveBoundary(contentType);
		retrieveParts(contentLength, istream);
	}

	/**
	 * バウンダリ文字列の検索。
	 * @param String contentType コンテンツタイプ。
	 */
	private void retrieveBoundary(String contentType) {
		contentType = contentType.toLowerCase();
		int pos = contentType.indexOf(boundaryKey) + boundaryKey.length();
		this.boundary = "--" + contentType.substring(pos);
		this.endBoundary = "--" + contentType.substring(pos) + "--";
	}

	/**
	 * 受け取りデータを個々のPartにパース(分解)する。
	 * @param int contentLength コンテンツ長。
	 * @param ServletInputStream istream データ読み込みもとStream
	 */
	private void retrieveParts(int contentLength, ServletInputStream istream)
		throws IOException {

		byte[] buf = new byte[8 * 1024];
		byte[] content;
		ArrayList contentList = new ArrayList();
		int ret;
		int readbytes = 0;
		int paramsLength = 0;
		int eachContentLength = 0;
		boolean contentFlag = false;
		String line;
		Part eachPart = null;
		DataInputStream dataInStream = new DataInputStream(istream);
		while ((ret = istream.readLine(buf, 0, buf.length)) > -1) {
			content = new byte[ret];
			System.arraycopy(buf, 0, content, 0, ret);
			line = new String(content);
			if (line.indexOf(boundary) >= 0) {
				readbytes += ret;
				if (eachPart != null) {
					// コンテンツのPartへの設定(書き出し)
					int contentSize = eachContentLength;
					if (eachPart.isBinary()) {
						contentSize = contentSize - 2;
						eachPart.setContentLength(contentSize);
					}
					else {
						eachPart.setContentLength(contentSize);
					}
					byte contentArray[] = new byte[contentSize];
					for (int i = 0; i < contentSize; i++) {
						contentArray[i] = ((Byte)contentList.get(i)).byteValue();
					}
					eachPart.setContent(contentArray);
					eachPart.setParamsLength(paramsLength);
					eachParts.add(eachPart);
				}
				eachPart = new Part();
				contentFlag = false;
				paramsLength = 0;
				eachContentLength = 0;
			}
			else if ((line.length() == separatorSize) && (contentFlag == false)) {
				// セパレータを見つけたら、以降をコンテンツとして扱う。
				readbytes += ret;
				contentFlag = true;
				contentList = new ArrayList();
			}
			else if (!contentFlag) {
				// コンテンツフラグがtrueではないのでパラメータ。
				readbytes += ret;
				paramsLength += ret;
				eachPart.setParams(line);
			}
			else if (contentFlag) {
				readbytes += ret;
				eachContentLength += ret;
				for (int i = 0; i < ret; i++) {
					contentList.add(new Byte(buf[i]));
				}
			}
		}
		dataInStream.close();
	}

	private int getBufSize(int size) {
		int b = size / 1024;
		return ((b + 1) * 1024);
	}

	/**
	 * 取得パラメータを返す。
	 * @return Hashtable 取得パラメータ。
	 */	
	public Hashtable getParams() {
		Hashtable params = new Hashtable();	
		Iterator it = eachParts.iterator();
		Part part;
		while (it.hasNext()) {
			part = (Part)it.next();
			params.putAll(part.getParams());
		}
		return params;
	}

}

MultiPartを分割した個々のパートを表すクラス。

package com.homeunix.doi.upload;
import java.io.ByteArrayOutputStream;
import java.io.UnsupportedEncodingException;
import java.util.Hashtable;
import java.util.StringTokenizer;

/**
 * マルチパート送信の個々のパートを表すクラス。
 * @author <A href="mailto:t-doi_AT_bg.wakwak.com">Toshihiko DOI</A>
 * Copyright(C) 2003 Toshihiko DOI. All rights reserved. 
 */
public class Part {
	private static String dataType = "Content-Disposition: form-data; ";
	private static String mimeType = "Content-Type: ";
	private boolean binary = false;
	private int paramsLength = 0;
	private int contentLength = 0;
	private int writebytes = 0;
	private String key = null;
	private Hashtable params = new Hashtable();
	private ByteArrayOutputStream ostream = new ByteArrayOutputStream();

	/**
	 * 送られてきたHTTP Parameterを表すHashtableを取得する。
	 * @return Hashtable HTTP Parameterを表すHashtable。
	 */
	public Hashtable getParams() {
		return params;
	}

	/**
	 * コンテンツがあるかどうかの判定。
	 * @return コンテンツがある場合は、<code>true</code>,それ以外は<code>false</code>。
	 */
	public boolean hasContents() {
		return contentLength <= 0 ? false : true;
	}

	/**
	 * このパートが持っているコンテンツがバイナリコンテンツかどうかの判定。
	 * @return 持っているコンテンツがバイナリコンテンツの場合は、<code>true</code>,それ以外は<code>false</code>。
	 */	
	public boolean isBinary() {
		return binary;
	}

	/**
	 * パラメータの設定。
	 * @param String paramString 設定するパラメータ文字列。
	 */
	protected void setParams(String paramString) {
		params.put("Content-Type", "text/plain");
		if (paramString.startsWith(mimeType)) {
			params.put(
				"Content-Type",
				trimln(substring(paramString, mimeType)));
			return;
		}
		String param = substring(paramString, dataType);
		StringTokenizer st = new StringTokenizer(param, ";");
		int count = st.countTokens();
		if (count < 1)
			return;
		StringTokenizer st2;
		String key, value;
		if (count < 2) {
			binary = false;
		}
		else {
			binary = true;
		}
		for (int i = 0; i < count; i++) {
			String token = st.nextToken();
			token = token.trim();
			st2 = new StringTokenizer(token, "=");
			if (st2.countTokens() == 2) {
				key = st2.nextToken();
				value = trim(st2.nextToken());
				if ("name".equals(key)) {
					this.key = value;
				}
				if (this.key != null) {
					params.put(this.key, value);
				}
			}
		}
	}

	/**
	 * パラメータ文字列長の設定。
	 * @param int paramLength パラメータ文字列長。
	 */
	protected void setParamsLength(int paramsLength) {
		this.paramsLength = paramsLength;
	}

	/**
	 * パラメター文字列長の取得。
	 * @return int パラメータ文字列長。
	 */
	protected int getParamsLength() {
		return paramsLength;
	}

	/**
	 * コンテンツ長の設定。
	 * @param int contentLength コンテンツ長。
	 */
	protected void setContentLength(int contentLength) {
		this.contentLength = contentLength;
	}

	/**
	 * コンテンツ長の取得。
	 * @return int コンテンツ長。
	 */
	protected int getContentLength() {
		return contentLength;
	}

	private String substring(String str, String key) {
		if (str.indexOf(key) == 0) {
			return str.substring(key.length());
		}
		return str;
	}

	private String trim(String str) {
		if (str.endsWith("\n")) {
			return str.substring(1, str.length() - 3);
		}
		else {
			return str.substring(1, str.length() - 1);
		}
	}

	private String trimln(String str) {
		if (str.endsWith("\n")) {
			return str.substring(0, str.length() - 2);
		}
		return str;
	}

	/**
	 * コンテンツの設定。
	 * @param byte[] buf コンテンツ。
	 */
	protected void setContent(byte[] buf) throws UnsupportedEncodingException {
		if (binary) {
			ostream.write(buf, 0, buf.length);
			writebytes += buf.length;
		}
		else {
			String value = new String(buf);
			params.put(key, trimln(value));
		}
	}

	/**
	 * バイナリコンテンツの取得。
	 * @return byte[] バイナリコンテンツのバイト配列。
	 */
	public byte[] getBinaryContent() {
		return ostream.toByteArray();
	}

	/**
	 * コンストラクタ。
	 */
	protected Part() {
	}
}

入力値をJavaBeansに設定するクラス。

package com.homeunix.doi.upload;

/**
 * 受け取ったデータをJavaBeansに設定する。
 * @author <A href="mailto:t-doi_AT_bg.wakwak.com">Toshihiko DOI</A>
 * Copyright(C) 2003 Toshihiko DOI. All rights reserved. 
 */

import java.io.File;
import java.io.FileOutputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.Vector;

import javax.servlet.ServletContext;

public class ContentsWriter {
	private ServletContext context;
	private String outfilename;
	private MultiPartParser parser;
	private String binaryname;
	private MimeTypesInspector inspector;
	private UploadPropertyBean bean;

	public UploadPropertyBean getUploadPropertyBean() {
		return bean;
	}

	public void write() {
		Hashtable params = parser.getParams();
		if (params.containsKey("Content-Type")) {
			bean.setContentType((String) params.get("Content-Type"));
		}
		if (params.containsKey("encoding")) {
			bean.setEncoding((String) params.get("encoding"));
		}
		if (params.containsKey("username")) {
			bean.setUsername((String) params.get("username"));
		}
		if (params.containsKey("comment")) {
			bean.setComment((String) params.get("comment"));
		}
		writeAttachedFile();
	}


	// 添付ファイルの書き込み
	private void writeAttachedFile() {
		Iterator it = parser.getEachParts().iterator();
		Hashtable params = parser.getParams();
		Part part = null;
		int count = 1;
		while (it.hasNext()) {
			part = (Part) it.next();
			if (part.isBinary() && part.hasContents()) {
				Hashtable tb = part.getParams();
				Enumeration keys = tb.keys();
				binaryname = outfilename + count;
				while(keys.hasMoreElements()) {
					String key = (String)keys.nextElement();
					if (key.startsWith("uploadfile")) {
						bean.addUploadfile((String)tb.get(key));
						String contentType = (String)tb.get("Content-Type");
						String extension = 
					    inspector.getAttribute(contentType).getExtension();
						binaryname = binaryname + "." +extension;
						bean.addBinaryname(binaryname);
					}
				}
				writeBinary(
					part,
					binaryname);
					count++;
			}
		}
	}

	// ファイルの書き出し
	private void writeBinary(
		Part part,
		String outfilename) {
		Hashtable params = part.getParams();
		// ディレクトリの存在チェック。
		String realPath =
			context.getRealPath(outfilename);

		FileOutputStream ostream = null;
		try {
			ostream = new FileOutputStream(realPath);
			ostream.write(part.getBinaryContent());
		}
		catch (Exception e) {
			e.printStackTrace();
			// ignore ... 
		}
		finally {
			if (ostream != null) {
				try {
					ostream.close();
				}
				catch (Exception e) {
					// ignore ...	
				}
			}
		}
	}

	public ContentsWriter(
		ServletContext context,
		String outfilename,
		MultiPartParser parser,
		MimeTypesInspector inspector)
		throws FileNotFoundException, IOException {
		this.context = context;
		this.outfilename = outfilename;
		this.parser = parser;
		this.inspector = inspector;
		bean = new UploadPropertyBean();
	}
}

Content-typeから拡張子を求めるクラス。

package com.homeunix.doi.upload;

/**
 * A class to get a file extension and type from the Apache 
 * configuresion -  "mime.types" .
 *
 * @auther Yoko Kamei Harada, Copyright &#169; 2001
 * @version 1.0, 2001/09/05
 * 
 */

import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.InputStreamReader;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.Hashtable;
import java.util.StringTokenizer;

public class MimeTypesInspector {
    private static MimeTypesInspector inspector = null;
    private static String comment = "#";
    private Hashtable mimeTable = new Hashtable();

    public static MimeTypesInspector getInstance(String typeFilePath)
	throws FileNotFoundException,
	       IOException {
	if (inspector == null) {
	    inspector = new MimeTypesInspector(typeFilePath);
	}
	return inspector;
    }

    Attribute getAttribute(String mimeType) {
	String[] exts = (String[])mimeTable.get(mimeType);
	boolean binary = true;
	if (mimeType.startsWith("text")) binary = false;
	if (exts != null) return new Attribute(exts[0], binary);
	else return null;
    }

    private MimeTypesInspector(String typeFilePath) 
	throws FileNotFoundException,
	       IOException {

	FileInputStream istream = 
	    new FileInputStream(typeFilePath);
	InputStreamReader ireader = 
	    new InputStreamReader(istream);
	BufferedReader reader = new BufferedReader(ireader);
	String line, key, values;
	StringTokenizer lineSt, valuesSt;
	int tokens;
	while((line = reader.readLine()) != null) {
	    if ((lineSt = getValidToken(line)) != null) {
		key = lineSt.nextToken();
		values = lineSt.nextToken();
		valuesSt = new StringTokenizer(values, " ");
		tokens = valuesSt.countTokens();
		String[] exts = new String[tokens];
		for (int i=0; i<tokens; i++) {
		    exts[i] = valuesSt.nextToken();
		}
		mimeTable.put(key, exts);
	    }
	}
    }

    private StringTokenizer getValidToken(String line) {
	if (line.startsWith(comment)) return null;
	//StringTokenizer st = new StringTokenizer(line, " ");
	StringTokenizer st = new StringTokenizer(line, "\t");
	if (st.countTokens() < 2) return null;
	return st;
    }

    class Attribute {
	private String extension = null;
	private boolean binary = true;

	String getExtension() {
	    return extension;
	}

	boolean isBinary() {
	    return binary;
	}

	private Attribute(String extension, boolean binary) {
	    this.extension = extension;
	    this.binary = binary;
	}
    }
}

ServletからJSPにデータを渡すためのJavaBeans。

package com.homeunix.doi.upload;

/**
 * Servlet -> JSPのデータ渡し用JavaBeans
 * @author <A href="mailto:t-doi_AT_bg.wakwak.com">Toshihiko DOI</A>
 * Copyright(C) 2003 Toshihiko DOI. All rights reserved. 
 */

import java.io.Serializable;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;

public class UploadPropertyBean implements Serializable {
	private String contentType = null;
	private String encoding = null;
	private String username = null;
	private String comment = null;
	private ArrayList uploadfile = new ArrayList();
	private ArrayList binaryname = new ArrayList();

	void setContentType(String contentType) {
		this.contentType = contentType;
	}

	public String getContentType() {
		return contentType;
	}

	void setEncoding(String encoding) {
		this.encoding = encoding;
	}

	String getEncoding() {
		return encoding;
	}

	void setUsername(String username) {
		this.username = username;

	}

	public String getUsername() throws UnsupportedEncodingException {
		return normalize(new String(username.getBytes("ISO-8859-1"), encoding));
	}

	void setComment(String comment) {
		this.comment = comment;

	}

	public String getComment() throws UnsupportedEncodingException {
		return normalize(new String(comment.getBytes("ISO-8859-1"), encoding));
	}

	void addUploadfile(String uploadfile) {
		this.uploadfile.add(uploadfile);
	}

	public String[] getUploadfile() throws UnsupportedEncodingException {
		String[] uploadfileOrg = new String[uploadfile.size()];
		for (int i = 0; i < uploadfile.size(); i++) {
			uploadfileOrg[i] = getOriginalName((String)uploadfile.get(i));
		}
		return uploadfileOrg;
	}

	private String getOriginalName(String uploadfile) throws UnsupportedEncodingException {
		String original =
			new String(uploadfile.getBytes("ISO-8859-1"), encoding);
		int index = original.lastIndexOf("/");
		if (index > 0)
			return original.substring(index + 1);
		index = original.lastIndexOf("\\");
		if (index > 0)
			return original.substring(index + 1);
		return original;
	}

	void addBinaryname(String binaryname) {
		this.binaryname.add(binaryname);
	}

	public String[] getBinaryname() {
		String[] binaryNameArray = new String[binaryname.size()];
		return (String[])binaryname.toArray(binaryNameArray);
	}

	private String normalize(String s) {
		if (s == null)
			return "";

		StringBuffer ret = new StringBuffer();
		int len = s.length();
		for (int i = 0; i < len; i++) {
			char ch = s.charAt(i);
			switch (ch) {
				case '<' :
					ret.append("&#060;");
					break;
				case '>' :
					ret.append("&#062;");
					break;
				case '&' :
					ret.append("&#038;");
					break;
				case '"' :
					ret.append("&#034;");
					break;
				case '\'' :
					ret.append("&#039;");
					break;
				case ',' :
					ret.append("&#044;");
					break;
				case ';' :
					ret.append("&#059;");
					break;
				case '~' :
					ret.append("&#126;");
					break;
				case '%' :
					ret.append("&#037;");
					break;
				case '*' :
					ret.append("&#042;");
					break;
				case '\\' :
					ret.append("&#092;");
					break;
				case ' ' :
					ret.append("&#160;");
					break;
					/*
					    case '\t':
					        ret.append("&#009;");
					        break;
					*/
				default :
					ret.append(ch);
			}
		}
		return new String(ret);
	}

	public UploadPropertyBean() {
	}
}

JSP

ファイルをアップロードする画面のJSP

<!-- 
    RFC 1867 Form-based File Upload Sample

    Author: Yoko Kamei Harada
    Date:          2001.09.05
-->
<html lang="ja">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-2022-jp">
<title>Form Based File Upload Sample (1)</title>
</head>
<%@ page session="false"
         contentType="text/html; charset=iso-2022-jp" %>
<%
    String contextRoot = request.getContextPath();
%>
<body bgcolor="#f0ffff" text="703070">
<blockquote>
<a href="./FormBasedFileUpload.en.jsp">[English]</a>
<br /><br />
<b>$B%U%!%$%k%"%C%W%m!<%I%5%s%W%k(B</b><br />
<br />
<blockquote>
$B!V(BRFC1867 Form-based File Upload in HTML$B!W$K$h$k%U%!%$%k%"%C%W%m!<%I$N(B
$B%5%s%W%k$G$9!#(B<br />
$B%U%!%$%k%5%$%:$,Bg$-$9$.$k$H%"%C%W%m!<%I$G$-$^$;$s!#(B
$B%W%m%0%i%`$G(B 1MB $B$r;XDj$7$F$$$^$9$,!"$=$NA0$K(B Apache $B$,5qH](B
$B$9$k$h$&$G$9!#(B<br />
<br />
$B%"%C%W%m!<%I=PMh$k%U%!%$%k$N<oN`$O2hA|!"%Q%o!<%]%$%s%H!"%o!<%I!"(B
$B%(%/%;%k!"%F%-%9%H$J$I$G$9!#F|K\8l$N%U%!%$%kL>$G$bBg>fIW$G$9!#(B<br /><br />
$B$?$@$7!"(BNetscape 4.x $B$G$O%Q%o!<%]%$%s%H!"%o!<%I!"%(%/%;%k$N%"%C%W%m!<%I$K(B
$B<:GT$7$^$9!#(BNetscape 6.x, IE 5.x $B$J$iBg>fIW$G$9!#(B
<br /><br />
<b>
$B!z!z!z(B<br />
<font color="#f00080">
$B%"%C%W%m!<%I$7$?%U%!%$%k$OC/$+$i$b8+$($F$7$^$$$^$9!#(B
$BC/$,8+$F$b9=$o$J$$%U%!%$%k$G$*;n$7$/$@$5$$!#(B</font>
<br />
$B!z!z!z(B
</b>
</blockquote>
<hr width="80%" />
<form action="<%= contextRoot %>/servlet/com.homeunix.doi.servlet.FileUploadServlet"
      enctype="multipart/form-data"
      method="POST">
<input type="hidden" name="encoding" value="JISAutoDetect">
<center><table border="0">
<tr>
<td align="right" nowrap>$B$*L>A0(B: </td>
<td><input type="text" name="username" size="20" maxlength="20"></td>
</tr>
<tr>
<td align="right" nowrap>$B%3%a%s%H(B: </td>
<td><input type="text" name="comment" size="40" maxlength="50"></td>
</tr>
<tr>
<td align="right" nowrap>$B%U%!%$%k(B1: </td>
<td><input type="file" size="40" name="uploadfile1"></td>
</tr>
<tr>
<td align="right" nowrap>$B%U%!%$%k(B2: </td>
<td><input type="file" size="40" name="uploadfile2"></td>
</tr>
<tr>
<td align="right" nowrap>$B%U%!%$%k(B3: </td>
<td><input type="file" size="40" name="uploadfile3"></td>
</tr>
<tr>
<td colspan="2" align="center">
<input type="submit" value="Upload">
</td>
</tr>
</table></center>
</form>
<hr width="80%" />
<blockquote>
</body>
</html>

アップロード結果表示画面のJSP

<!-- 
    RFC 1867 Form-based File Upload Sample

    Author: Yoko Kamei Harada
    Date:          2001.09.05
-->
<html lang="ja">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-2022-jp">
<title>Form Based File Upload Sample (2)</title>
</head>
<%@ page session="false"
         contentType="text/html; charset=iso-2022-jp" %>
<%
    String contextRoot = request.getContextPath();
%>
<jsp:useBean id="uploadPropertyBean"
             type="com.homeunix.doi.upload.UploadPropertyBean"
             scope="request" />
<body bgcolor="#f0ffff" text="703070">
<blockquote>
+++ $B$3$N%U%!%$%k$,%"%C%W%m!<%I$5$l$^$7$?(B +++<br />
<br />
<table border="0">
<tr>
<td align="right" nowrap>$B$*L>A0(B: </td>
<td><jsp:getProperty name="uploadPropertyBean" property="username" /></td>
</tr>
<tr>
<td align="right" nowrap>$B%3%a%s%H(B: </td>
<td><jsp:getProperty name="uploadPropertyBean" property="comment" /></td>
</tr>
<tr>
<td align="right" valign="top" nowrap>$B%U%!%$%kL>(B: </td>
<td>
<%
String[] uploadFile = uploadPropertyBean.getUploadfile();
String[] binaryName = uploadPropertyBean.getBinaryname();
for (int i=0; i < uploadFile.length; i++) {
    out.println("<a href=" + contextRoot + binaryName[i] + ">");
    out.println(uploadFile[i]);
    out.println("</a><br>");
}
%>
</td>
</tr>
</table>
<br /><br />
$B%"%C%W%m!<%I$N$*;n$7$O(B
<a href="<%= contextRoot %>/samples/FormBasedFileUpload.jsp">
$B$3$3$+$i(B</a> $B!#(B
<blockquote>
</body>
</html>

エラー表示画面のJSP

<!-- 
    RFC 1867 Form-based File Upload Sample

    Author: Yoko Kamei Harada
    Date:          2001.09.05
-->
<html lang="ja">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-2022-jp">
<title>Form Based File Upload Sample - Error</title>
</head>
<%@ page session="false"
         contentType="text/html; charset=iso-2022-jp" %>
<%
    String contextRoot = request.getContextPath();
%>
<body bgcolor="#f0ffff" text="703070">
<blockquote>
<b>$B$3$N%U%!%$%k$O%"%C%W%m!<%I$G$-$^$;$s!#(B</b><br />
$B%U%!%$%k%5%$%:$O(B 1MB $B0J2<$K$7$F$/$@$5$$!#(B
<br /><br />
$B%"%C%W%m!<%I$N$*;n$7$O(B
<a href="<%= contextRoot %>/samples/FormBasedFileUpload.jsp">
$B$3$3$+$i(B</a> $B!#(B
<blockquote>
</body>
</html>

動作風景

http://サーブレットをインストールしたマシン/アプリケーション名/samples/FormBasedFileUpload.jsp にアクセスすると、下記の画面が表示されるので、アップロードしたいファイルを入力します。

[upload1]

uploadボタンをクリックすると、ファイルが正常にアップロードされた場合は以下のような画面が表示されます。

[upload2]

ファイル名をクリックすると、アップロードされたファイルを参照することができます。

[upload3]

ダウンロード

ダウンロードはこちらから

更新履歴

ぜひ、感想をお送りください

あなたのご意見・感想をお送りください。

あなたの名前: メール:
(お名前・メールは、いずれも未記入でかまいません)

今年は西暦何年ですか?

何かの理由でうまく送れない場合にはメール でお願いします。