<!--
/***************************************************************************************************************************
 * 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.
 ***************************************************************************************************************************/
 -->

Custom Serializers and Parsers

<p>
	A very easy-to-use API is provided for defining your own serializers and parsers at both the servlet and 
	method levels.
</p>
<p>
	The following examples show a custom serializer and parser defined at the method level.
	It's the <l>PhotosResource</l> class pulled from the Samples project.
	It shows an example of defining a serializer and parser to handle images.
</p>
<p class='bpcode w800'>
	<jd>/**
	 * Sample resource that allows images to be uploaded and retrieved.
	 */</jd>
	<ja>@Rest</ja>(
		path=<js>"/photos"</js>,
		messages=<js>"nls/PhotosResource"</js>,
		title=<js>"Photo REST service"</js>,
		description=<js>"Use a tool like Poster to upload and retrieve jpeg and png images."</js>,
		htmldoc=<ja>@HtmlDoc</ja>(
			navlinks={
				<js>"options: ?method=OPTIONS"</js>
			}
		)
	)
	<jk>public class</jk> PhotosResource <jk>extends</jk> BasicRestServlet {
	
		<jc>// Our cache of photos</jc>
		<jk>private</jk> Map&lt;Integer,Photo&gt; photos = <jk>new</jk> TreeMap&lt;Integer,Photo&gt;();
		
		<jd>/** Bean class for storing photos */</jd>
		<jk>public static class</jk> Photo {
			<jk>private int</jk> <jf>id</jf>;
			BufferedImage <jf>image</jf>;
			
			Photo(int id, BufferedImage image) {
				<jk>this</jk>.<jf>id</jf> = id;
				<jk>this</jk>.<jf>image</jf> = image;
			}
			
			<jk>public</jk> URI getURI() <jk>throws</jk> URISyntaxException {
				<jk>return new</jk> URI(<js>"photos/"</js>+<jf>id</jf>);
			}
			
			<jk>public int</jk> getID() {
				<jk>return</jk> <jf>id</jf>;
			}
		}
		
		<jd>/** GET request handler for list of all photos */</jd>
		<ja>@RestMethod</ja>(name=<jsf>GET</jsf>, path=<js>"/"</js>)
		<jk>public</jk> Collection&lt;Photo&gt; getAllPhotos(RestRequest req, RestResponse res) <jk>throws</jk> Exception {
			res.setPageTitle(<js>"Photo REST service"</js>);
			res.setPageText(<js>"Use a tool like Poster to upload and retrieve jpeg and png images."</js>);
			<jk>return</jk> photos.values();
		}
		
		<jd>/** GET request handler for single photo */</jd>
		<ja>@RestMethod</ja>(name=<jsf>GET</jsf>, path=<js>"/{id}"</js>, serializers=ImageSerializer.<jk>class</jk>)
		<jk>public</jk> BufferedImage getPhoto(RestRequest req, <ja>@Path</ja>(<js>"id"</js>) int id) <jk>throws</jk> Exception {
			Photo p = photos.get(id);
			if (p == <jk>null</jk>)
				<jk>throw new</jk> RestException(<jsf>SC_NOT_FOUND</jsf>, <js>"Photo not found"</js>);
			<jk>return</jk> p.image;
		}
		
		<jd>/** PUT request handler */</jd>
		<ja>@RestMethod</ja>(name=<jsf>PUT</jsf>, path=<js>"/{id}"</js>, parsers=ImageParser.<jk>class</jk>)
		<jk>public</jk> String addPhoto(RestRequest req, <ja>@Path</ja>(<js>"id"</js>) <jk>int</jk> id, <ja>@Body</ja> BufferedImage image) <jk>throws</jk> Exception {
			photos.put(id, <jk>new</jk> Photo(id, image));
			<jk>return</jk> <js>"OK"</js>;
		}
		
		<jd>/** POST request handler */</jd>
		<ja>@RestMethod</ja>(name=<jsf>POST</jsf>, path=<js>"/"</js>, parsers=ImageParser.<jk>class</jk>)
		<jk>public</jk> Photo setPhoto(RestRequest req, <ja>@Body</ja> BufferedImage image) <jk>throws</jk> Exception {
			<jk>int</jk> id = photos.size();
			Photo p = <jk>new</jk> Photo(id, image);
			photos.put(id, p);
			<jk>return</jk> p;
		}
		
		<jd>/** DELETE request handler */</jd>
		<ja>@RestMethod</ja>(name=<jsf>DELETE</jsf>, path=<js>"/{id}"</js>)
		<jk>public</jk> String deletePhoto(RestRequest req, <ja>@Path</ja>(<js>"id"</js>) <jk>int</jk> id) <jk>throws</jk> Exception {
			Photo p = photos.remove(id);
			if (p == <jk>null</jk>)
				<jk>throw new</jk> RestException(<jsf>SC_NOT_FOUND</jsf>, <js>"Photo not found"</js>);
			<jk>return</jk> <js>"OK"</js>;
		}
	
		<jd>/** OPTIONS request handler */</jd>
		<ja>@RestMethod</ja>(name=<jsf>OPTIONS</jsf>, path=<js>"/*"</js>)
		<jk>public</jk> Swagger getOptions(RestRequest req) {
			<jk>return</jk> req.getSwagger();
		}

		<jd>/** Serializer for converting images to byte streams */</jd>
		<ja>@Produces</ja>(<js>"image/png,image/jpeg"</js>)
		<jk>public static class</jk> ImageSerializer <jk>extends</jk> OutputStreamSerializer {
		
			<ja>@Override</ja> <jc>/* Serializer */</jc>
			<jk>public void</jk> serialize(Object o, OutputStream out, SerializerSession session) <jk>throws</jk> IOException, SerializeException {
				RenderedImage image = (RenderedImage)o;
				String mediaType = ctx.getMediaType();
				ImageIO.<jsm>write</jsm>(image, mediaType.substring(mediaType.indexOf(<js>'/'</js>)+1), out);
			}	
		}
		
		<jd>/** Parser for converting byte streams to images */</jd>
		<ja>@Consumes</ja>(<js>"image/png,image/jpeg"</js>)
		<jk>public static class</jk> ImageParser <jk>extends</jk> InputStreamParser {
		
			<ja>@Override</ja> <jc>/* Parser */</jc>
			<jk>public</jk> &lt;T&gt; T parse(InputStream in, ClassMeta&lt;T&gt; type, ParserSession session) <jk>throws</jk> ParseException, IOException {
				BufferedImage image = ImageIO.<jsm>read</jsm>(in);
				<jk>return</jk> (T)image;
			}
		}
	}
</p>
