REST

Using JAX-RS With JAXB

<div dir&equals;"ltr" style&equals;"text-align&colon; justify&semi;">Java Architecture for <b>XML Binding &lpar;JAXB&rpar;<&sol;b> is an <b>XML-to-Java binding<&sol;b> technology that simplifies the development of web services by enabling transformations between schema and Java objects and between XML instance documents and Java object instances&period; An XML schema defines the data elements and structure of an XML document&period; You can use <b>JAXB APIs<&sol;b> and tools to establish mappings between Java classes and XML schema&period; <b>JAXB <&sol;b>technology provides the tools that enable you to convert your XML documents to and from Java objects&period;There are many tutorials and examples of using<b> JAX-RS<&sol;b> to create <b>RESTful web services&comma;<&sol;b> but most fall short of explaining how to produce and consume complex object graphs using <b>XML <&sol;b>and <b>JAXB<&sol;b>&period; This article will show how easy it can be&comma; several approaches to where you place the annotations&comma; and how you can configure them&period;<&sol;p>&NewLine;<p>Lets start with the root XML element&period; I chose to call mine <i><b>GetBooksResponse<&sol;b><&sol;i>&comma; and use it as a container for a collection of Book objects and a Student object&period; You don&&num;8217&semi;t need to follow this convention&period;<br &sol;>&NewLine;<b>GetBooksResponse&period;java<&sol;b><&sol;p>&NewLine;<pre class&equals;"highlight">package com&period;dineshonjava&period;ws&period;rest&semi; &NewLine; &NewLine;import java&period;util&period;ArrayList&semi; &NewLine;import java&period;util&period;List&semi; &NewLine; &NewLine;import javax&period;xml&period;bind&period;annotation&period;XmlElement&semi; &NewLine;import javax&period;xml&period;bind&period;annotation&period;XmlElementWrapper&semi; &NewLine;import javax&period;xml&period;bind&period;annotation&period;XmlRootElement&semi; &NewLine; &NewLine;import com&period;dineshonjava&period;ws&period;xml&period;Book&semi; &NewLine;import com&period;dineshonjava&period;ws&period;xml&period;Student&semi; &NewLine; &NewLine;&sol;&ast;&ast; &NewLine; &ast; &commat;author Dinesh Rajput &NewLine; &ast; &NewLine; &ast;&sol; &NewLine;&commat;XmlRootElement &NewLine;public class GetBooksResponse &lbrace; &NewLine; private Student student&semi; &NewLine; private List&lt&semi;Book&gt&semi; books &equals; new ArrayList&lt&semi;Book&gt&semi;&lpar;&rpar;&semi; &NewLine; &NewLine; &commat;XmlElement &NewLine; public Student getStudent&lpar;&rpar; &lbrace; &NewLine; return student&semi; &NewLine; &rcub; &NewLine; public void setStudent&lpar;Student student&rpar; &lbrace; &NewLine; this&period;student &equals; student&semi; &NewLine; &rcub; &NewLine; &NewLine; &commat;XmlElement &NewLine; &commat;XmlElementWrapper&lpar;name &equals; "books"&rpar; &NewLine; public List&lt&semi;Book&gt&semi; getBooks&lpar;&rpar; &lbrace; &NewLine; return books&semi; &NewLine; &rcub; &NewLine; public void setBooks&lpar;List&lt&semi;Book&gt&semi; books&rpar; &lbrace; &NewLine; this&period;books &equals; books&semi; &NewLine; &rcub; &NewLine; &NewLine;&rcub; &NewLine; &NewLine;<&sol;pre>&NewLine;<div id&equals;"ads-id" align&equals;"center"><&sol;div>&NewLine;<p><b>JAXB&&num;8217&semi;s<&sol;b> default naming convention is to use your class or bean getter name as-is&comma; but starting with a lower case letter&period; In this example&comma; once marshaled to XML the element names will be <b>getBooksResponse<&sol;b>&comma; <b>student<&sol;b>&comma; and <b>books<&sol;b>&period; I will show an example of how to override the default naming later in this article&period;<&sol;p>&NewLine;<p>Also notice that I placed the <b>&commat;XmlElement<&sol;b> annotations on the getter methods instead of on the private fields&period; When placed on the private fields&comma; <b>JAXB <&sol;b>will give you an error unless you add <b>&commat;XmlAccessorType&lpar;XmlAccessType&period;FIELD&rpar; <&sol;b>at the class level&period;<&sol;p>&NewLine;<p>Finally&comma; notice the <b>&commat;XmlElementWrapper<&sol;b> annotation on the List collection&period; This makes <b>JAXB <&sol;b>wrap all of the order XML elements inside of an orders XML element&period; This annotation can be used with an array instead of a List too&period;<br &sol;>&NewLine;<b>Student&period;java<&sol;b><&sol;p>&NewLine;<pre class&equals;"highlight">package com&period;dineshonjava&period;ws&period;xml&semi; &NewLine; &NewLine;import javax&period;xml&period;bind&period;annotation&period;XmlElement&semi; &NewLine;import javax&period;xml&period;bind&period;annotation&period;XmlType&semi; &NewLine; &NewLine;&sol;&ast;&ast; &NewLine; &ast; &commat;author Dinesh Rajput &NewLine; &ast; &NewLine; &ast;&sol; &NewLine;&commat;XmlType&lpar;name&equals;"students"&rpar; &NewLine;public class Student &lbrace; &NewLine; private long rollNumber&semi; &NewLine; private String name&semi; &NewLine; private String course&semi; &NewLine; &NewLine; &commat;XmlElement&lpar;name&equals;"rollNumber"&rpar; &NewLine; public long getRollNumber&lpar;&rpar; &lbrace; &NewLine; return rollNumber&semi; &NewLine; &rcub; &NewLine; public void setRollNumber&lpar;long rollNumber&rpar; &lbrace; &NewLine; this&period;rollNumber &equals; rollNumber&semi; &NewLine; &rcub; &NewLine; &commat;XmlElement&lpar;name&equals;"name"&rpar; &NewLine; public String getName&lpar;&rpar; &lbrace; &NewLine; return name&semi; &NewLine; &rcub; &NewLine; public void setName&lpar;String name&rpar; &lbrace; &NewLine; this&period;name &equals; name&semi; &NewLine; &rcub; &NewLine; &commat;XmlElement&lpar;name&equals;"course"&rpar; &NewLine; public String getCourse&lpar;&rpar; &lbrace; &NewLine; return course&semi; &NewLine; &rcub; &NewLine; public void setCourse&lpar;String course&rpar; &lbrace; &NewLine; this&period;course &equals; course&semi; &NewLine; &rcub; &NewLine;&rcub; &NewLine; &NewLine;<&sol;pre>&NewLine;<p>In the example above&comma; we use <b>&commat;XmlType<&sol;b> at the class level instead of <b>&commat;XmlRootElement<&sol;b> because it is not the root element&period; Also notice the name parameter in each of the annotations&period; This is how you override JAXB&&num;8217&semi;s default element naming&period;<&sol;p>&NewLine;<p><b>Book&period;java<&sol;b><&sol;p>&NewLine;<pre class&equals;"highlight">package com&period;dineshonjava&period;ws&period;xml&semi; &NewLine; &NewLine;import java&period;util&period;Date&semi; &NewLine; &NewLine;import javax&period;xml&period;bind&period;annotation&period;XmlAccessType&semi; &NewLine;import javax&period;xml&period;bind&period;annotation&period;XmlAccessorType&semi; &NewLine;import javax&period;xml&period;bind&period;annotation&period;XmlElement&semi; &NewLine;import javax&period;xml&period;bind&period;annotation&period;XmlElementWrapper&semi; &NewLine;import javax&period;xml&period;bind&period;annotation&period;XmlType&semi; &NewLine; &NewLine;&sol;&ast;&ast; &NewLine; &ast; &commat;author Dinesh Rajput &NewLine; &ast; &NewLine; &ast;&sol; &NewLine;&commat;XmlType&lpar;propOrder &equals; &lbrace; "publishDate"&comma; "publishNumber"&comma; "publishedBooks"&comma; "bookName" &rcub; &rpar; &NewLine;&commat;XmlAccessorType&lpar;XmlAccessType&period;FIELD&rpar; &NewLine;public class Book &lbrace; &NewLine; &commat;XmlElement &NewLine; public Date publishDate&semi; &NewLine; &NewLine; &commat;XmlElement &NewLine; public long publishNumber&semi; &NewLine; &NewLine; &commat;XmlElement &NewLine; public String bookName&semi; &NewLine; &NewLine; &commat;XmlElement &NewLine; &commat;XmlElementWrapper&lpar;name &equals; "publishedBooks"&rpar; &NewLine; public PublishedBooks&lbrack;&rsqb; publishedBooks&semi; &NewLine; &NewLine; public Date getPublishDate&lpar;&rpar; &lbrace; &NewLine; return publishDate&semi; &NewLine; &rcub; &NewLine; &NewLine; public void setPublishDate&lpar;Date publishDate&rpar; &lbrace; &NewLine; this&period;publishDate &equals; publishDate&semi; &NewLine; &rcub; &NewLine; &NewLine; public long getPublishNumber&lpar;&rpar; &lbrace; &NewLine; return publishNumber&semi; &NewLine; &rcub; &NewLine; &NewLine; public void setPublishNumber&lpar;long publishNumber&rpar; &lbrace; &NewLine; this&period;publishNumber &equals; publishNumber&semi; &NewLine; &rcub; &NewLine; &NewLine; public String getBookName&lpar;&rpar; &lbrace; &NewLine; return bookName&semi; &NewLine; &rcub; &NewLine; &NewLine; public PublishedBooks&lbrack;&rsqb; getPublishedBooks&lpar;&rpar; &lbrace; &NewLine; return publishedBooks&semi; &NewLine; &rcub; &NewLine; &NewLine; public void setPublishedBooks&lpar;PublishedBooks&lbrack;&rsqb; publishedBooks&rpar; &lbrace; &NewLine; this&period;publishedBooks &equals; publishedBooks&semi; &NewLine; &rcub; &NewLine; &NewLine; public void setBookName&lpar;String bookName&rpar; &lbrace; &NewLine; this&period;bookName &equals; bookName&semi; &NewLine; &rcub; &NewLine; &NewLine;&rcub; &NewLine; &NewLine;<&sol;pre>&NewLine;<p>In the example above I used the <b>&commat;XmlAccessorType&lpar;XmlAccessType&period;FIELD&rpar;<&sol;b> to allow me to place the <b>&commat;XmlElement<&sol;b> annotations on the private fields instead of on the getter methods&period;<&sol;p>&NewLine;<p>Also notice the <b>propOrder <&sol;b>parameter of the <b>&commat;XmlType<&sol;b> annotation&period; By default <b>JAXB <&sol;b>will <b>book <&sol;b>the elements alphabetically&period; Use the <b>propOrder <&sol;b>parameter to specify the order when marshaling to <b>XML<&sol;b>&period; The values are the bean names&comma; not the overridden names in the <b>&commat;XmlElement&lpar;name &equals; &&num;8220&semi;overridenName&&num;8221&semi;&rpar;<&sol;b> annotation&period;<&sol;p>&NewLine;<p>Finally&comma; notice the <b>&commat;XmlElementWrapper<&sol;b> used on a <b>PublishedBooks&lbrack;&rsqb;<&sol;b> array&period; It works with arrays and Lists&period;<&sol;p>&NewLine;<p><b>PublishedBooks&period;java<&sol;b><&sol;p>&NewLine;<pre class&equals;"highlight">package com&period;dineshonjava&period;ws&period;xml&semi; &NewLine; &NewLine;import javax&period;xml&period;bind&period;annotation&period;XmlElement&semi; &NewLine;import javax&period;xml&period;bind&period;annotation&period;XmlType&semi; &NewLine; &NewLine;&sol;&ast;&ast; &NewLine; &ast; &commat;author Dinesh Rajput &NewLine; &ast; &NewLine; &ast;&sol; &NewLine;&commat;XmlType&lpar;propOrder &equals; &lbrace; "bookId"&comma; "description"&comma; "quantity"&comma; "unitPrice"&comma; &NewLine; "subTotal"&comma; "tax"&comma; "total" &rcub; &rpar; &NewLine;public class PublishedBooks &lbrace; &NewLine; &NewLine; private long bookId&semi; &NewLine; private String description&semi; &NewLine; private short quantity&semi; &NewLine; private double unitPrice&semi; &NewLine; &NewLine; &commat;XmlElement &NewLine; public long getBookId&lpar;&rpar; &lbrace; &NewLine; return bookId&semi; &NewLine; &rcub; &NewLine; public void setBookId&lpar;long bookId&rpar; &lbrace; &NewLine; this&period;bookId &equals; bookId&semi; &NewLine; &rcub; &NewLine; &commat;XmlElement &NewLine; public String getDescription&lpar;&rpar; &lbrace; &NewLine; return description&semi; &NewLine; &rcub; &NewLine; public void setDescription&lpar;String description&rpar; &lbrace; &NewLine; this&period;description &equals; description&semi; &NewLine; &rcub; &NewLine; &commat;XmlElement &NewLine; public short getQuantity&lpar;&rpar; &lbrace; &NewLine; return quantity&semi; &NewLine; &rcub; &NewLine; public void setQuantity&lpar;short quantity&rpar; &lbrace; &NewLine; this&period;quantity &equals; quantity&semi; &NewLine; &rcub; &NewLine; &commat;XmlElement &NewLine; public double getUnitPrice&lpar;&rpar; &lbrace; &NewLine; return unitPrice&semi; &NewLine; &rcub; &NewLine; public void setUnitPrice&lpar;double unitPrice&rpar; &lbrace; &NewLine; this&period;unitPrice &equals; unitPrice&semi; &NewLine; &rcub; &NewLine; &NewLine; &commat;XmlElement &NewLine; public double getSubTotal&lpar;&rpar; &lbrace; &NewLine; return unitPrice &ast; quantity&semi; &NewLine; &rcub; &NewLine; &NewLine; &commat;XmlElement &NewLine; public double getTax&lpar;&rpar; &lbrace; &NewLine; return getSubTotal&lpar;&rpar; &ast; 0&period;15F&semi; &NewLine; &rcub; &NewLine; &NewLine; &commat;XmlElement &NewLine; public double getTotal&lpar;&rpar; &lbrace; &NewLine; return getSubTotal&lpar;&rpar; &plus; getTax&lpar;&rpar;&semi; &NewLine; &rcub; &NewLine;&rcub; &NewLine; &NewLine;<&sol;pre>&NewLine;<p>In the example above there are no setter methods that correspond to <b>getSubTotal<&sol;b>&comma; <b>getTax <&sol;b>and <b>getTotal<&sol;b>&period; Now lets create a<b> JAX-RS RESTful <&sol;b>web service that can return this object graph in the response&period;<br &sol;>&NewLine;<b>BookResource&period;java<&sol;b><&sol;p>&NewLine;<pre class&equals;"highlight">package com&period;dineshonjava&period;ws&period;order&semi; &NewLine; &NewLine;import java&period;util&period;Date&semi; &NewLine; &NewLine;import javax&period;ws&period;rs&period;GET&semi; &NewLine;import javax&period;ws&period;rs&period;PUT&semi; &NewLine;import javax&period;ws&period;rs&period;Path&semi; &NewLine;import javax&period;ws&period;rs&period;PathParam&semi; &NewLine;import javax&period;ws&period;rs&period;Produces&semi; &NewLine;import javax&period;ws&period;rs&period;core&period;MediaType&semi; &NewLine;import javax&period;ws&period;rs&period;core&period;Response&semi; &NewLine;import javax&period;ws&period;rs&period;core&period;Response&period;ResponseBuilder&semi; &NewLine; &NewLine;import com&period;dineshonjava&period;ws&period;error&period;BookNotFoundException&semi; &NewLine;import com&period;dineshonjava&period;ws&period;rest&period;GetBooksResponse&semi; &NewLine;import com&period;dineshonjava&period;ws&period;xml&period;Book&semi; &NewLine;import com&period;dineshonjava&period;ws&period;xml&period;PublishedBooks&semi; &NewLine;import com&period;dineshonjava&period;ws&period;xml&period;Student&semi; &NewLine; &NewLine;&sol;&ast;&ast; &NewLine; &ast; &commat;author Dinesh Rajput &NewLine; &ast; &NewLine; &ast;&sol; &NewLine;&commat;Path&lpar;"&sol;order&sol;books"&rpar; &NewLine;public class BookResource &lbrace; &NewLine; &commat;GET &NewLine; &commat;Produces&lpar;"text&sol;xml"&rpar; &NewLine; public GetBooksResponse getBooks&lpar;&rpar; &lbrace; &NewLine; &NewLine; GetBooksResponse response &equals; new GetBooksResponse&lpar;&rpar;&semi; &NewLine; Student student &equals; new Student&lpar;&rpar;&semi; &NewLine; PublishedBooks publishedBooks1&semi; &NewLine; PublishedBooks publishedBooks2&semi; &NewLine; &NewLine; &sol;&sol; student &NewLine; student&period;setRollNumber&lpar;12345&rpar;&semi; &NewLine; student&period;setName&lpar;"Dinesh Rajput"&rpar;&semi; &NewLine; student&period;setCourse&lpar;"Computer Science"&rpar;&semi; &NewLine; response&period;setStudent&lpar;student&rpar;&semi; &NewLine; &NewLine; &sol;&sol; first book &NewLine; Book book1 &equals; new Book&lpar;&rpar;&semi; &NewLine; book1&period;setPublishNumber&lpar;54321&rpar;&semi; &NewLine; book1&period;setPublishDate&lpar;new Date&lpar;&rpar;&rpar;&semi; &NewLine; book1&period;setBookName&lpar;"Java"&rpar;&semi; &NewLine; &NewLine; publishedBooks1 &equals; new PublishedBooks&lpar;&rpar;&semi; &NewLine; publishedBooks1&period;setBookId&lpar;77777&rpar;&semi; &NewLine; publishedBooks1&period;setDescription&lpar;"winning lottery ticket"&rpar;&semi; &NewLine; publishedBooks1&period;setQuantity&lpar;&lpar;short&rpar; 10&rpar;&semi; &NewLine; publishedBooks1&period;setUnitPrice&lpar;5&period;00F&rpar;&semi; &NewLine; &NewLine; publishedBooks2 &equals; new PublishedBooks&lpar;&rpar;&semi; &NewLine; publishedBooks2&period;setBookId&lpar;12121212&rpar;&semi; &NewLine; publishedBooks2&period;setDescription&lpar;"Real World Java EE Patterns Rethinking Best Practices"&rpar;&semi; &NewLine; publishedBooks2&period;setQuantity&lpar;&lpar;short&rpar; 1&rpar;&semi; &NewLine; publishedBooks2&period;setUnitPrice&lpar;40&period;40F&rpar;&semi; &NewLine; &NewLine; book1&period;setPublishedBooks&lpar;new PublishedBooks&lbrack;&rsqb; &lbrace; publishedBooks1&comma; publishedBooks2 &rcub; &rpar;&semi; &NewLine; response&period;getBooks&lpar;&rpar;&period;add&lpar;book1&rpar;&semi; &NewLine; &NewLine; &sol;&sol; second book &NewLine; Book book2 &equals; new Book&lpar;&rpar;&semi; &NewLine; book2&period;setPublishNumber&lpar;12345&rpar;&semi; &NewLine; book2&period;setPublishDate&lpar;new Date&lpar;&rpar;&rpar;&semi; &NewLine; &NewLine; publishedBooks1 &equals; new PublishedBooks&lpar;&rpar;&semi; &NewLine; publishedBooks1&period;setBookId&lpar;787878&rpar;&semi; &NewLine; publishedBooks1&period;setDescription&lpar;"JavaServer Faces 2&period;0&comma; The Complete Reference"&rpar;&semi; &NewLine; publishedBooks1&period;setQuantity&lpar;&lpar;short&rpar; 10&rpar;&semi; &NewLine; publishedBooks1&period;setUnitPrice&lpar;31&period;49F&rpar;&semi; &NewLine; &NewLine; publishedBooks2 &equals; new PublishedBooks&lpar;&rpar;&semi; &NewLine; publishedBooks2&period;setBookId&lpar;1111111&rpar;&semi; &NewLine; publishedBooks2&period;setDescription&lpar;"Beginning Java EE 6 with GlassFish 3&comma; Second Edition"&rpar;&semi; &NewLine; publishedBooks2&period;setQuantity&lpar;&lpar;short&rpar; 1&rpar;&semi; &NewLine; publishedBooks2&period;setUnitPrice&lpar;41&period;73F&rpar;&semi; &NewLine; &NewLine; book2&period;setPublishedBooks&lpar;new PublishedBooks&lbrack;&rsqb; &lbrace; publishedBooks1&comma; publishedBooks1 &rcub; &rpar;&semi; &NewLine; response&period;getBooks&lpar;&rpar;&period;add&lpar;book2&rpar;&semi; &NewLine; &NewLine; return response&semi; &NewLine; &rcub; &NewLine; &NewLine; &commat;GET &NewLine; &commat;Path&lpar;"&lbrace;publishNumber&rcub;"&rpar; &NewLine; &commat;Produces&lpar;MediaType&period;TEXT&lowbar;PLAIN&rpar; &NewLine; public Response updateOrder&lpar;&commat;PathParam&lpar;"publishNumber"&rpar; String publishNumber&rpar; throws BookNotFoundException &lbrace; &NewLine; &NewLine; ResponseBuilder response&semi; &NewLine; &NewLine; if &lpar;"12345"&period;equals&lpar;publishNumber&rpar;&rpar; &lbrace; &NewLine; response &equals; Response&period;status&lpar;Response&period;Status&period;ACCEPTED&rpar;&period;entity&lpar; "Saved changes to book '" &plus;publishNumber&plus; "'&period;"&rpar;&semi; &NewLine; &rcub; else &lbrace; &NewLine; throw new BookNotFoundException&lpar;"Publisher number '" &plus; publishNumber &plus; &NewLine; "' does not exist&period;"&rpar;&semi; &NewLine; &rcub; &NewLine; return response&period;build&lpar;&rpar;&semi; &NewLine; &rcub; &NewLine; &NewLine;&rcub; &NewLine; &NewLine;<&sol;pre>&NewLine;<p>Notice the<b> &commat;Produces&lpar;&&num;8220&semi;text&sol;xml&&num;8221&semi;&rpar;<&sol;b> annotation&comma; and that the method returns a <b>GetBooksResponse <&sol;b>object&period; Since the <b>GetBooksResponse <&sol;b>is annotated with <b>JAXB <&sol;b>annotations&comma; <b>JAX-RS <&sol;b>will automatically marshal the response to XML&period;<&sol;p>&NewLine;<p>Next lets add a method that takes part of the object graph as a request parameter&period; We&&num;8217&semi;ll start by creating an object to represent the XML root element&colon;<br &sol;>&NewLine;<b>UpdateBookRequest&period;java<&sol;b><&sol;p>&NewLine;<pre class&equals;"highlight">package com&period;dineshonjava&period;ws&period;order&semi; &NewLine; &NewLine;import javax&period;xml&period;bind&period;annotation&period;XmlElement&semi; &NewLine;import javax&period;xml&period;bind&period;annotation&period;XmlRootElement&semi; &NewLine; &NewLine;import com&period;dineshonjava&period;ws&period;xml&period;Book&semi; &NewLine; &NewLine;&sol;&ast;&ast; &NewLine; &ast; &commat;author Dinesh Rajput &NewLine; &ast; &NewLine; &ast;&sol; &NewLine;&commat;XmlRootElement &NewLine;public class UpdateBookRequest &lbrace; &NewLine; private Book book&semi; &NewLine; &NewLine; &commat;XmlElement &NewLine; public Book getBook&lpar;&rpar; &lbrace; &NewLine; return book&semi; &NewLine; &rcub; &NewLine; &NewLine; public void setBook&lpar;Book book&rpar; &lbrace; &NewLine; this&period;book &equals; book&semi; &NewLine; &rcub; &NewLine; &NewLine;&rcub; &NewLine; &NewLine;<&sol;pre>&NewLine;<p>Now lets use this object in a PUT request&colon;<&sol;p>&NewLine;<pre class&equals;"highlight">&commat;PUT &NewLine; &commat;Path&lpar;"&lbrace;publishNumber&rcub;&period;xml"&rpar; &NewLine; &commat;Produces&lpar;MediaType&period;TEXT&lowbar;PLAIN&rpar; &NewLine; public Response updateOrder&lpar;&commat;PathParam&lpar;"publishNumber"&rpar; String publishNumber&rpar; throws BookNotFoundException &lbrace; &NewLine; &NewLine; ResponseBuilder response&semi; &NewLine; &NewLine; if &lpar;"12345"&period;equals&lpar;publishNumber&rpar;&rpar; &lbrace; &NewLine; response &equals; Response&period;status&lpar;Response&period;Status&period;ACCEPTED&rpar;&period;entity&lpar; "Saved changes to book '" &plus;publishNumber&plus; "'&period;"&rpar;&semi; &NewLine; &rcub; else &lbrace; &NewLine; throw new BookNotFoundException&lpar;"Publisher number '" &plus; publishNumber &plus; &NewLine; "' does not exist&period;"&rpar;&semi; &NewLine; &rcub; &NewLine; return response&period;build&lpar;&rpar;&semi; &NewLine; &rcub; &NewLine;<&sol;pre>&NewLine;<p>Since the <b>UpdateBookRequest <&sol;b>is annotated with <b>JAXB <&sol;b>annotations&comma; <b>JAX-RS<&sol;b> will automatically unmarshal it from XML&period;<&sol;p>&NewLine;<p>This example returns a<i><b> javax&period;ws&period;rs&period;core&period;Response<&sol;b><&sol;i> built using <b><i>javax&period;ws&period;rs&period;core&period;ResponseBuilder&period;<&sol;i><&sol;b> You can use <b>ResponseBuilder <&sol;b>to set response headers&comma; the status code&comma; and many other things&period; The response body is called the entity&comma; and you can place anything in it&period; For example&comma; a String&comma; or a <b>JAXB <&sol;b>annotated object graph&period;<&sol;p>&NewLine;<p>This example also throws an <b>BookNotFoundException<&sol;b>&colon;<br &sol;>&NewLine;<b>BookNotFoundException&period;java<&sol;b><&sol;p>&NewLine;<pre class&equals;"highlight">package com&period;dineshonjava&period;ws&period;error&semi; &NewLine; &NewLine;import javax&period;ws&period;rs&period;WebApplicationException&semi; &NewLine;import javax&period;ws&period;rs&period;core&period;MediaType&semi; &NewLine;import javax&period;ws&period;rs&period;core&period;Response&semi; &NewLine;import javax&period;ws&period;rs&period;core&period;Response&period;Status&semi; &NewLine; &NewLine;&sol;&ast;&ast; &NewLine; &ast; &commat;author Dinesh Rajput &NewLine; &ast; &NewLine; &ast;&sol; &NewLine;public class BookNotFoundException extends WebApplicationException &lbrace; &NewLine; &sol;&ast;&ast; &NewLine; &ast; version &NewLine; &ast;&sol; &NewLine; private static final long serialVersionUID &equals; 1L&semi; &NewLine; &NewLine; public BookNotFoundException&lpar;String message&rpar; &lbrace; &NewLine; super&lpar;Response&period;status&lpar;Status&period;NOT&lowbar;FOUND&rpar;&period;entity&lpar;message&rpar;&period;type&lpar; &NewLine; MediaType&period;TEXT&lowbar;PLAIN&rpar;&period;build&lpar;&rpar;&rpar;&semi; &NewLine; &rcub; &NewLine;&rcub; &NewLine; &NewLine;<&sol;pre>&NewLine;<p>The custom exception extends the <b>WebApplicationException <&sol;b>in <b>JAX-RS<&sol;b>&period; There are many constructors in <b>WebApplicationException<&sol;b>&period; I chose to use the one that lets me provide the complete response data&period;<br &sol;>&NewLine;<i><b>web&period;xml<&sol;b><&sol;i><&sol;p>&NewLine;<pre class&equals;"highlight">&lt&semi;&quest;xml version&equals;"1&period;0" encoding&equals;"UTF-8"&quest;&gt&semi; &NewLine;&lt&semi;web-app xmlns&colon;xsi&equals;"http&colon;&sol;&sol;www&period;w3&period;org&sol;2001&sol;XMLSchema-instance" xmlns&equals;"http&colon;&sol;&sol;java&period;sun&period;com&sol;xml&sol;ns&sol;javaee" xmlns&colon;web&equals;"http&colon;&sol;&sol;java&period;sun&period;com&sol;xml&sol;ns&sol;javaee&sol;web-app&lowbar;2&lowbar;5&period;xsd" xsi&colon;schemaLocation&equals;"http&colon;&sol;&sol;java&period;sun&period;com&sol;xml&sol;ns&sol;javaee http&colon;&sol;&sol;java&period;sun&period;com&sol;xml&sol;ns&sol;javaee&sol;web-app&lowbar;3&lowbar;0&period;xsd" id&equals;"WebApp&lowbar;ID" version&equals;"3&period;0"&gt&semi; &NewLine; &lt&semi;display-name&gt&semi;JaxRSJaxBApps&lt&semi;&sol;display-name&gt&semi; &NewLine; &lt&semi;servlet&gt&semi; &NewLine; &lt&semi;servlet-name&gt&semi;jersey-serlvet&lt&semi;&sol;servlet-name&gt&semi; &NewLine; &lt&semi;servlet-class&gt&semi; &NewLine; com&period;sun&period;jersey&period;spi&period;container&period;servlet&period;ServletContainer &NewLine; &lt&semi;&sol;servlet-class&gt&semi; &NewLine; &lt&semi;load-on-startup&gt&semi;1&lt&semi;&sol;load-on-startup&gt&semi; &NewLine; &lt&semi;&sol;servlet&gt&semi; &NewLine; &NewLine; &lt&semi;servlet-mapping&gt&semi; &NewLine; &lt&semi;servlet-name&gt&semi;jersey-serlvet&lt&semi;&sol;servlet-name&gt&semi; &NewLine; &lt&semi;url-pattern&gt&semi;&sol;&ast;&lt&semi;&sol;url-pattern&gt&semi; &NewLine; &lt&semi;&sol;servlet-mapping&gt&semi; &NewLine;&lt&semi;&sol;web-app&gt&semi; &NewLine;<&sol;pre>&NewLine;<p><b>Directory structure for this web application<&sol;b>&period;<&sol;p>&NewLine;<div class&equals;"separator" style&equals;"clear&colon; both&semi; text-align&colon; center&semi;"><img src&equals;"https&colon;&sol;&sol;dineshonjava&period;com&sol;wp-content&sol;uploads&sol;2013&sol;06&sol;jaxrsdir&period;png" border&equals;"0" &sol;><&sol;div>&NewLine;<p><b>Now deploy this application to the tomcat server and hit the following urls&period;<&sol;b><br &sol;>&NewLine;<b><br &sol;>&NewLine;<&sol;b> <i><b>http&colon;&sol;&sol;localhost&colon;8181&sol;doj&sol;order&sol;books<&sol;b><&sol;i><&sol;p>&NewLine;<div class&equals;"separator" style&equals;"clear&colon; both&semi; text-align&colon; center&semi;"><img src&equals;"https&colon;&sol;&sol;dineshonjava&period;com&sol;wp-content&sol;uploads&sol;2013&sol;06&sol;out1jaxrs-488x1024&period;png" border&equals;"0" &sol;><&sol;div>&NewLine;<p><i><b>http&colon;&sol;&sol;localhost&colon;8181&sol;doj&sol;order&sol;books&sol;12345<&sol;b><&sol;i><&sol;p>&NewLine;<div class&equals;"separator" style&equals;"clear&colon; both&semi; text-align&colon; center&semi;"><img src&equals;"https&colon;&sol;&sol;dineshonjava&period;com&sol;wp-content&sol;uploads&sol;2013&sol;06&sol;out2jaxrs&period;png" border&equals;"0" &sol;><&sol;div>&NewLine;<p><b>Download SourceCode and Libs<&sol;b><br &sol;>&NewLine;<b><a href&equals;"https&colon;&sol;&sol;sites&period;google&period;com&sol;a&sol;dineshonjava&period;com&sol;dineshonjava&sol;dineshonjava&sol;JaxRSJaxBApps&period;zip&quest;attredirects&equals;0&amp&semi;d&equals;1" target&equals;"&lowbar;blank" rel&equals;"noopener">JaxRSJaxBApps&period;zip<&sol;a><&sol;b><&sol;p>&NewLine;<p><i><b>References<&sol;b><&sol;i><br &sol;>&NewLine;1&period;<b> <i><a href&equals;"http&colon;&sol;&sol;docs&period;oracle&period;com&sol;javaee&sol;6&sol;tutorial&sol;doc&sol;giepu&period;html" target&equals;"&lowbar;blank" rel&equals;"noopener">JAVA REST Web Services<&sol;a><&sol;i><&sol;b><br &sol;>&NewLine;2&period; <i><b><a href&equals;"http&colon;&sol;&sol;en&period;wikipedia&period;org&sol;wiki&sol;Web&lowbar;service" target&equals;"&lowbar;blank" rel&equals;"noopener">Wikipedia for REST Web Service<&sol;a><&sol;b><&sol;i><&sol;p>&NewLine;<p>&nbsp&semi;<&sol;p>&NewLine;<div style&equals;"background-color&colon; pink&semi; border-width&colon; thin&semi; text-align&colon; center&semi;"><b>&lt&semi;&lt&semi;<a href&equals;"https&colon;&sol;&sol;dineshonjava&period;com&sol;annotations-for-field-and-bean&sol;">Previous <&sol;a>&lt&semi;&lt&semi;   &vert;&vert; <a href&equals;"https&colon;&sol;&sol;dineshonjava&period;com&sol;jax-rs-web-service-tutorial&sol;">Index <&sol;a>&vert;&vert;   &gt&semi;&gt&semi;<a href&equals;"https&colon;&sol;&sol;dineshonjava&period;com&sol;jax-rs-path-uri-matching-example&sol;">Next<&sol;a> &gt&semi;&gt&semi;<&sol;b><&sol;div>&NewLine;<p>&nbsp&semi;<&sol;p>&NewLine;<&sol;div>&NewLine;<div class&equals;"wp-post-navigation"> &NewLine;&Tab;&Tab;&Tab;&Tab;&Tab;&Tab;&Tab;&Tab;&Tab; <div class&equals;"wp-post-navigation-pre"> &NewLine;&Tab;&Tab;&Tab;&Tab;&Tab;&Tab;&Tab;&Tab;&Tab; <a href&equals;"https&colon;&sol;&sol;dineshonjava&period;com&sol;annotations-for-field-and-bean&sol;">Previous<&sol;a> &NewLine;&Tab;&Tab;&Tab;&Tab;&Tab;&Tab;&Tab;&Tab;&Tab; <&sol;div> &NewLine;&Tab;&Tab;&Tab;&Tab;&Tab;&Tab;&Tab;&Tab;&Tab; <div class&equals;"wp-post-navigation-next"> &NewLine;&Tab;&Tab;&Tab;&Tab;&Tab;&Tab;&Tab;&Tab;&Tab; <a href&equals;"https&colon;&sol;&sol;dineshonjava&period;com&sol;jax-rs-path-uri-matching-example&sol;">Next<&sol;a> &NewLine;&Tab;&Tab;&Tab;&Tab;&Tab;&Tab;&Tab;&Tab;&Tab; <&sol;div> &NewLine;&Tab;&Tab;&Tab;&Tab;&Tab;&Tab;&Tab;&Tab;&Tab;<&sol;div>&NewLine;<script type&equals;"text&sol;javascript">&NewLine;jQuery&lpar;document&rpar;&period;ready&lpar;function&lpar;&dollar;&rpar; &lbrace;&NewLine; &dollar;&period;post&lpar;'https&colon;&sol;&sol;dineshonjava&period;com&sol;wp-admin&sol;admin-ajax&period;php'&comma; &lbrace;action&colon; 'mts&lowbar;view&lowbar;count'&comma; id&colon; '425'&rcub;&rpar;&semi;&NewLine;&rcub;&rpar;&semi;&NewLine;<&sol;script>

Dinesh Rajput

Dinesh Rajput is the chief editor of a website Dineshonjava, a technical blog dedicated to the Spring and Java technologies. It has a series of articles related to Java technologies. Dinesh has been a Spring enthusiast since 2008 and is a Pivotal Certified Spring Professional, an author of a book Spring 5 Design Pattern, and a blogger. He has more than 10 years of experience with different aspects of Spring and Java design and development. His core expertise lies in the latest version of Spring Framework, Spring Boot, Spring Security, creating REST APIs, Microservice Architecture, Reactive Pattern, Spring AOP, Design Patterns, Struts, Hibernate, Web Services, Spring Batch, Cassandra, MongoDB, and Web Application Design and Architecture. He is currently working as a technology manager at a leading product and web development company. He worked as a developer and tech lead at the Bennett, Coleman & Co. Ltd and was the first developer in his previous company, Paytm. Dinesh is passionate about the latest Java technologies and loves to write technical blogs related to it. He is a very active member of the Java and Spring community on different forums. When it comes to the Spring Framework and Java, Dinesh tops the list!

Share
Published by
Dinesh Rajput

Recent Posts

Strategy Design Patterns using Lambda

Strategy Design Patterns We can easily create a strategy design pattern using lambda. To implement…

4 years ago

Decorator Pattern using Lambda

Decorator Pattern A decorator pattern allows a user to add new functionality to an existing…

4 years ago

Delegating pattern using lambda

Delegating pattern In software engineering, the delegation pattern is an object-oriented design pattern that allows…

4 years ago

Spring Vs Django- Know The Difference Between The Two

Technology has emerged a lot in the last decade, and now we have artificial intelligence;…

4 years ago

TOP 20 MongoDB INTERVIEW QUESTIONS 2022

Managing a database is becoming increasingly complex now due to the vast amount of data…

4 years ago

Scheduler @Scheduled Annotation Spring Boot

Overview In this article, we will explore Spring Scheduler how we could use it by…

4 years ago