| <!-- |
| /*************************************************************************************************************************** |
| * 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<Integer,Photo> photos = <jk>new</jk> TreeMap<Integer,Photo>(); |
| |
| <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<Photo> 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> <T> T parse(InputStream in, ClassMeta<T> type, ParserSession session) <jk>throws</jk> ParseException, IOException { |
| BufferedImage image = ImageIO.<jsm>read</jsm>(in); |
| <jk>return</jk> (T)image; |
| } |
| } |
| } |
| </p> |