<!--
/***************************************************************************************************************************
 * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *  
 *  http://www.apache.org/licenses/LICENSE-2.0
 *  
 * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations under the License.
 ***************************************************************************************************************************/
 -->

Handling Multi-Part Form Posts

<p>
	The Juneau framework does not natively support multipart form posts.  
	However, it can be done in conjunction with the Apache Commons File Upload library or through the Servlet 3.0 API directly.
</p>	
<p>
	The following is an example that uses the File Upload library to allow files to be uploaded as multipart form posts.
</p>
<h5 class='figure'>Example:</h5>
<p class='bpcode w800'>
	<ja>@Rest</ja>(
		path=<js>"/tempDir"</js>
	)
	<jk>public class</jk> TempDirResource <jk>extends</jk> DirectoryResource {
	
		<jd>/**
		 * [POST /upload] - Upload a file as a multipart form post.
		 * Shows how to use the Apache Commons ServletFileUpload class for handling multi-part form posts.
		 */</jd>
		<ja>@RestMethod</ja>(name=<jsf>POST</jsf>, path=<js>"/upload"</js>, matchers=TempDirResource.MultipartFormDataMatcher.<jk>class</jk>)
		<jk>public</jk> Redirect uploadFile(RestRequest req) <jk>throws</jk> Exception {
			ServletFileUpload upload = <jk>new</jk> ServletFileUpload();
			FileItemIterator iter = upload.getItemIterator(req);
			<jk>while</jk> (iter.hasNext()) {
				FileItemStream item = iter.next();
				<jk>if</jk> (item.getFieldName().equals(<js>"contents"</js>)) { 
					File f = <jk>new</jk> File(getRootDir(), item.getName());
					IOPipe.<jsm>create</jsm>(item.openStream(), <jk>new</jk> FileOutputStream(f)).closeOut().run();
				}
			}
			<jk>return new</jk> Redirect(); <jc>// Redirect to the servlet root.</jc>
		}
	
		<jd>/** Causes a 404 if POST isn't multipart/form-data */</jd>
		<jk>public static class</jk> MultipartFormDataMatcher <jk>extends</jk> RestMatcher {
		
			<ja>@Override</ja> <jc>/* RestMatcher */</jc>
			<jk>public boolean</jk> matches(RestRequest req) {
				String contentType = req.getContentType();
				<jk>return</jk> contentType != <jk>null</jk> &amp;&amp; contentType.startsWith(<js>"multipart/form-data"</js>); 
			}
		}
</p>
<p>
	The following shows using the <l>HttpServletRequest.getParts()</l> method to retrieve multi-part form posts when using Jetty.
	This example is pulled from the PetStore application.
</p>
<p class='bpcode w800'>
	<ja>@RestMethod</ja>(
		...
	)
	<jk>public</jk> SeeOtherRoot uploadFile(RestRequest req) <jk>throws</jk> Exception {
    	
		<jc>// Required for Jetty.</jc>
		MultipartConfigElement mce = <jk>new</jk> MultipartConfigElement((String)<jk>null</jk>);
		req.setAttribute(<js>"org.eclipse.jetty.multipartConfig"</js>, mce);  
       
		String id = UUID.<jsm>randomUUID</jsm>().toString();
		BufferedImage img = <jk>null</jk>;
		<jk>for</jk> (Part part : req.getParts()) {
			<jk>switch</jk> (part.getName()) {
				<jk>case</jk> <js>"id"</js>:
					id = IOUtils.<jsm>read</jsm>(part.getInputStream());
					<jk>break</jk>;
				<jk>case</jk> <js>"file"</js>:
					img = ImageIO.<jsm>read</jsm>(part.getInputStream());
			}
		}
		addPhoto(id, img);
		<jk>return new</jk> SeeOtherRoot(); <jc>// Redirect to the servlet root.</jc>
	}
</p>

