文档章节

Multipart Form File Upload

gxchan
 gxchan
发布于 2015/06/09 23:32
字数 1449
阅读 16
收藏 0

主要类:


/**
 * <code>MultiPartFormOutputStream</code> is used to write
 * "multipart/form-data" to a <code>java.net.URLConnection</code> for POSTing.
 * This is primarily for file uploading to HTTP servers.
 * 
 * @since JDK1.3
 */
public class MultiPartFormOutputStream
{
	/**
	 * The line end characters.
	 */
	private static final String NEWLINE = "\r\n";

	/**
	 * The boundary prefix.
	 */
	private static final String PREFIX = "--";

	/**
	 * The output stream to write to.
	 */
	private DataOutputStream out = null;

	/**
	 * The multipart boundary string.
	 */
	private String boundary = null;

	/**
	 * Creates a new <code>MultiPartFormOutputStream</code> object using the
	 * specified output stream and boundary. The boundary is required to be
	 * created before using this method, as described in the description for the
	 * <code>getContentType(String)</code> method. The boundary is only
	 * checked for <code>null</code> or empty string, but it is recommended to
	 * be at least 6 characters. (Or use the static createBoundary() method to
	 * create one.)
	 * 
	 * @param os
	 *            the output stream
	 * @param boundary
	 *            the boundary
	 * @see #createBoundary()
	 * @see #getContentType(String)
	 */
	public MultiPartFormOutputStream(OutputStream os, String boundary)
	{
		if (os == null)
		{
			throw new IllegalArgumentException("Output stream is required.");
		}
		if (boundary == null || boundary.length() == 0)
		{
			throw new IllegalArgumentException("Boundary stream is required.");
		}
		this.out = new DataOutputStream(os);
		this.boundary = boundary;
	}

	/**
	 * Writes an boolean field value.
	 * 
	 * @param name
	 *            the field name (required)
	 * @param value
	 *            the field value
	 * @throws java.io.IOException
	 *             on input/output errors
	 */
	@SuppressLint("UseValueOf")
	public void writeField(String name, boolean value) throws java.io.IOException
	{
		writeField(name, new Boolean(value).toString());
	}

	/**
	 * Writes an double field value.
	 * 
	 * @param name
	 *            the field name (required)
	 * @param value
	 *            the field value
	 * @throws java.io.IOException
	 *             on input/output errors
	 */
	public void writeField(String name, double value) throws java.io.IOException
	{
		writeField(name, Double.toString(value));
	}

	/**
	 * Writes an float field value.
	 * 
	 * @param name
	 *            the field name (required)
	 * @param value
	 *            the field value
	 * @throws java.io.IOException
	 *             on input/output errors
	 */
	public void writeField(String name, float value) throws java.io.IOException
	{
		writeField(name, Float.toString(value));
	}

	/**
	 * Writes an long field value.
	 * 
	 * @param name
	 *            the field name (required)
	 * @param value
	 *            the field value
	 * @throws java.io.IOException
	 *             on input/output errors
	 */
	public void writeField(String name, long value) throws java.io.IOException
	{
		writeField(name, Long.toString(value));
	}

	/**
	 * Writes an int field value.
	 * 
	 * @param name
	 *            the field name (required)
	 * @param value
	 *            the field value
	 * @throws java.io.IOException
	 *             on input/output errors
	 */
	public void writeField(String name, int value) throws java.io.IOException
	{
		writeField(name, Integer.toString(value));
	}

	/**
	 * Writes an short field value.
	 * 
	 * @param name
	 *            the field name (required)
	 * @param value
	 *            the field value
	 * @throws java.io.IOException
	 *             on input/output errors
	 */
	public void writeField(String name, short value) throws java.io.IOException
	{
		writeField(name, Short.toString(value));
	}

	/**
	 * Writes an char field value.
	 * 
	 * @param name
	 *            the field name (required)
	 * @param value
	 *            the field value
	 * @throws java.io.IOException
	 *             on input/output errors
	 */
	@SuppressLint("UseValueOf")
	public void writeField(String name, char value) throws java.io.IOException
	{
		writeField(name, new Character(value).toString());
	}

	/**
	 * Writes an string field value. If the value is null, an empty string is
	 * sent ("").
	 * 
	 * @param name
	 *            the field name (required)
	 * @param value
	 *            the field value
	 * @throws java.io.IOException
	 *             on input/output errors
	 */
	public void writeField(String name, String value) throws java.io.IOException
	{
		if (name == null)
		{
			throw new IllegalArgumentException("Name cannot be null or empty.");
		}
		if (value == null)
		{
			value = "";
		}
		/*
		 * --boundary\r\n Content-Disposition: form-data; name="<fieldName>"\r\n
		 * \r\n <value>\r\n
		 */
		// write boundary
		out.writeBytes(PREFIX);
		out.writeBytes(boundary);
		out.writeBytes(NEWLINE);
		// write content header
		out.writeBytes("Content-Disposition: form-data; name=\"" + name + "\"");
		out.writeBytes(NEWLINE);
		out.writeBytes(NEWLINE);
		// write content
		out.writeBytes(new String(value.getBytes("UTF-8"), "ISO-8859-1"));
		out.writeBytes(NEWLINE);
		out.flush();
	}

	/**
	 * Writes a file's contents. If the file is null, does not exists, or is a
	 * directory, a <code>java.lang.IllegalArgumentException</code> will be
	 * thrown.
	 * 
	 * @param name
	 *            the field name
	 * @param mimeType
	 *            the file content type (optional, recommended)
	 * @param file
	 *            the file (the file must exist)
	 * @throws java.io.IOException
	 *             on input/output errors
	 */
	public void writeFile(String name, String mimeType, File file) throws java.io.IOException
	{
		if (file == null)
		{
			throw new IllegalArgumentException("File cannot be null.");
		}
		if (!file.exists())
		{
			throw new IllegalArgumentException("File does not exist.");
		}
		if (file.isDirectory())
		{
			throw new IllegalArgumentException("File cannot be a directory.");
		}
		writeFile(name, mimeType, file.getCanonicalPath(), new FileInputStream(file));
	}

	/**
	 * Writes a input stream's contents. If the input stream is null, a
	 * <code>java.lang.IllegalArgumentException</code> will be thrown.
	 * 
	 * @param name
	 *            the field name
	 * @param mimeType
	 *            the file content type (optional, recommended)
	 * @param fileName
	 *            the file name (required)
	 * @param is
	 *            the input stream
	 * @throws java.io.IOException
	 *             on input/output errors
	 */
	public void writeFile(String name, String mimeType, String fileName, InputStream is)
			throws java.io.IOException
	{
		if (is == null)
		{
			throw new IllegalArgumentException("Input stream cannot be null.");
		}
		if (fileName == null || fileName.length() == 0)
		{
			throw new IllegalArgumentException("File name cannot be null or empty.");
		}
		/*
		 * --boundary\r\n Content-Disposition: form-data; name="<fieldName>";
		 * filename="<filename>"\r\n Content-Type: <mime-type>\r\n \r\n
		 * <file-data>\r\n
		 */
		// write boundary
		out.writeBytes(PREFIX);
		out.writeBytes(boundary);
		out.writeBytes(NEWLINE);
		// write content header
		out.writeBytes("Content-Disposition: form-data; name=\"" + name + "\"; filename=\""
				+ new String(fileName.getBytes("UTF-8"), "ISO-8859-1") + "\"");
		out.writeBytes(NEWLINE);
		if (mimeType != null)
		{
			out.writeBytes("Content-Type: " + mimeType);
			out.writeBytes(NEWLINE);
		}
		out.writeBytes(NEWLINE);
		// write content
		byte[] data = new byte[1024];
		int r = 0;
		while ((r = is.read(data, 0, data.length)) != -1)
		{
			out.write(data, 0, r);
		}
		// close input stream, but ignore any possible exception for it
		try
		{
			is.close();
		}
		catch (Exception e)
		{
		}
		out.writeBytes(NEWLINE);
		out.flush();
	}

	/**
	 * Writes the given bytes. The bytes are assumed to be the contents of a
	 * file, and will be sent as such. If the data is null, a
	 * <code>java.lang.IllegalArgumentException</code> will be thrown.
	 * 
	 * @param name
	 *            the field name
	 * @param mimeType
	 *            the file content type (optional, recommended)
	 * @param fileName
	 *            the file name (required)
	 * @param data
	 *            the file data
	 * @throws java.io.IOException
	 *             on input/output errors
	 */
	public void writeFile(String name, String mimeType, String fileName, byte[] data)
			throws java.io.IOException
	{
		if (data == null)
		{
			throw new IllegalArgumentException("Data cannot be null.");
		}
		if (fileName == null || fileName.length() == 0)
		{
			throw new IllegalArgumentException("File name cannot be null or empty.");
		}
		/*
		 * --boundary\r\n Content-Disposition: form-data; name="<fieldName>";
		 * filename="<filename>"\r\n Content-Type: <mime-type>\r\n \r\n
		 * <file-data>\r\n
		 */
		// write boundary
		out.writeBytes(PREFIX);
		out.writeBytes(boundary);
		out.writeBytes(NEWLINE);
		// write content header
		out.writeBytes("Content-Disposition: form-data; name=\"" + name + "\"; filename=\""
				+ new String(fileName.getBytes("UTF-8"), "ISO-8859-1") + "\"");
		out.writeBytes(NEWLINE);
		if (mimeType != null)
		{
			out.writeBytes("Content-Type: " + mimeType);
			out.writeBytes(NEWLINE);
		}
		out.writeBytes(NEWLINE);
		// write content
		out.write(data, 0, data.length);
		out.writeBytes(NEWLINE);
		out.flush();
	}

	/**
	 * Flushes the stream. Actually, this method does nothing, as the only write
	 * methods are highly specialized and automatically flush.
	 * 
	 * @throws java.io.IOException
	 *             on input/output errors
	 */
	public void flush() throws java.io.IOException
	{
		// out.flush();
	}

	/**
	 * Closes the stream. <br />
	 * <br />
	 * <b>NOTE:</b> This method <b>MUST</b> be called to finalize the
	 * multipart stream.
	 * 
	 * @throws java.io.IOException
	 *             on input/output errors
	 */
	public void close() throws java.io.IOException
	{
		// write final boundary
		out.writeBytes(PREFIX);
		out.writeBytes(boundary);
		out.writeBytes(PREFIX);
		out.writeBytes(NEWLINE);
		out.flush();
		out.close();
	}

	/**
	 * Gets the multipart boundary string being used by this stream.
	 * 
	 * @return the boundary
	 */
	public String getBoundary()
	{
		return this.boundary;
	}

	/**
	 * Creates a new <code>java.net.URLConnection</code> object from the
	 * specified <code>java.net.URL</code>. This is a convenience method
	 * which will set the <code>doInput</code>, <code>doOutput</code>,
	 * <code>useCaches</code> and <code>defaultUseCaches</code> fields to
	 * the appropriate settings in the correct order.
	 * 
	 * @return a <code>java.net.URLConnection</code> object for the URL
	 * @throws java.io.IOException
	 *             on input/output errors
	 */
	public static URLConnection createConnection(URL url) throws java.io.IOException
	{
		URLConnection urlConn = url.openConnection();
		if (urlConn instanceof HttpURLConnection)
		{
			HttpURLConnection httpConn = (HttpURLConnection)urlConn;
			httpConn.setRequestMethod("POST");
		}
		urlConn.setDoInput(true);
		urlConn.setDoOutput(true);
		urlConn.setUseCaches(false);
		urlConn.setDefaultUseCaches(false);
		return urlConn;
	}

	/**
	 * Creates a multipart boundary string by concatenating 20 hyphens (-) and
	 * the hexadecimal (base-16) representation of the current time in
	 * milliseconds.
	 * 
	 * @return a multipart boundary string
	 * @see #getContentType(String)
	 */
	public static String createBoundary()
	{
		return "--------------------" + Long.toString(System.currentTimeMillis(), 16);
	}

	/**
	 * Gets the content type string suitable for the
	 * <code>java.net.URLConnection</code> which includes the multipart
	 * boundary string. <br />
	 * <br />
	 * This method is static because, due to the nature of the
	 * <code>java.net.URLConnection</code> class, once the output stream for
	 * the connection is acquired, it's too late to set the content type (or any
	 * other request parameter). So one has to create a multipart boundary
	 * string first before using this class, such as with the
	 * <code>createBoundary()</code> method.
	 * 
	 * @param boundary
	 *            the boundary string
	 * @return the content type string
	 * @see #createBoundary()
	 */
	public static String getContentType(String boundary)
	{
		return "multipart/form-data; boundary=" + boundary;
	}
}

测试代码:

public static void main(String[] args) throws Exception {
		String boundary = MultiPartFormOutputStream.createBoundary();
		InputStream is = null;
		ByteArrayOutputStream baos = null;
		try {
			String url = "http://localhost:8080/test";
			HttpURLConnection conn = (HttpURLConnection)MultiPartFormOutputStream.createConnection(new URL(url));
			conn.addRequestProperty("Content-Type", MultiPartFormOutputStream.getContentType(boundary));
			MultiPartFormOutputStream s = new MultiPartFormOutputStream(conn.getOutputStream(), boundary);
			s.writeField("id", 3L);
			s.writeField("content", "测试内容22abc");
			s.writeFile("file", null, new File("/Users/test/image.png"));
			s.close();
			
			int responseCode = conn.getResponseCode();
			if (responseCode != 200) {
                throw new Exception(String.format("Received the response code %d from the URL %s", responseCode, url));
            }
            // Read the response
            is = conn.getInputStream();
            baos = new ByteArrayOutputStream();
            byte[] bytes = new byte[1024];
            int bytesRead;
            while((bytesRead = is.read(bytes)) != -1) {
                baos.write(bytes, 0, bytesRead);
            }
            byte[] bytesReceived = baos.toByteArray();
            String response = new String(bytesReceived);
            System.out.println(response);
			
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			baos.close();
            is.close();
		}


© 著作权归作者所有

gxchan
粉丝 2
博文 6
码字总数 1934
作品 0
广州
高级程序员
私信 提问
php文件上传后的画面切换问题

UPLOAD.HTML文件: 文件上传 Filename: File: Upload: Type: Size: Temp file: Stored in: UPLOAD.PHP文件: assign('title',"文件上传"); $smt->display('upload.htm'); exit; } if($do=="d......

福星高照
2012/09/21
259
2
Spring Boot基础教程12-web应用开发-文件上传

一、Spring Boot 默认使用springMVC包装好的解析器进行上传 二、添加代码 文件: @Controller @RequestMapping(value = "/file")...

芝麻绿豆
2017/04/06
205
0
Spring Boot基础-web应用开发-文件上传

一、Spring Boot 默认使用springMVC包装好的解析器进行上传 二、添加代码 文件: @Controller @RequestMapping(value = "/file")...

登录404
2016/10/31
3.5K
0
Apache Commons fileUpload实现文件上传

找了好久,才找到的,很实用 将Apache的commons-fileupload.jar放在应用程序的WEB-INFlib下,即可使用。下面举例介绍如何使用它的文件上传功能。 所使用的fileUpload版本为1.2,环境为Eclip...

wumingyue
2012/08/29
201
0
010,spring boot 文件上传

1,application中配置 文件上传 的 限制大小等 相关配置: spring.http.multipart.max-file-size=2Mb spring.http.multipart.max-request-size=10Mb 2,前端 代码: <form method="POST" en......

岸芷汀兰
2016/12/04
89
0

没有更多内容

加载失败,请刷新页面

加载更多

SpringBoot中 集成 redisTemplate 对 Redis 的操作(二)

SpringBoot中 集成 redisTemplate 对 Redis 的操作(二) List 类型的操作 1、 向列表左侧添加数据 Long leftPush = redisTemplate.opsForList().leftPush("name", name); 2、 向列表右......

TcWong
今天
7
0
排序––快速排序(二)

根据排序––快速排序(一)的描述,现准备写一个快速排序的主体框架: 1、首先需要设置一个枢轴元素即setPivot(int i); 2、然后需要与枢轴元素进行比较即int comparePivot(int j); 3、最后...

FAT_mt
昨天
4
0
mysql概览

学习知识,首先要有一个总体的认识。以下为mysql概览 1-架构图 2-Detail csdn |简书 | 头条 | SegmentFault 思否 | 掘金 | 开源中国 |

程序员深夜写bug
昨天
10
0
golang微服务框架go-micro 入门笔记2.2 micro工具之微应用利器micro web

micro web micro 功能非常强大,本文将详细阐述micro web 命令行的功能 阅读本文前你可能需要进行如下知识储备 golang分布式微服务框架go-micro 入门笔记1:搭建go-micro环境, golang微服务框架...

非正式解决方案
昨天
9
0
前端——使用base64编码在页面嵌入图片

因为页面中插入一个图片都要写明图片的路径——相对路径或者绝对路径。而除了具体的网站图片的图片地址,如果是在自己电脑文件夹里的图片,当我们的HTML文件在别人电脑上打开的时候图片则由于...

被毒打的程序猿
昨天
9
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部