{"id":1765,"date":"2011-03-21T07:39:13","date_gmt":"2011-03-21T12:39:13","guid":{"rendered":"http:\/\/www.andygibson.net\/blog\/?p=1765"},"modified":"2011-03-16T14:50:38","modified_gmt":"2011-03-16T19:50:38","slug":"simple-restful-services-in-glassfish-pt-2","status":"publish","type":"post","link":"https:\/\/www.andygibson.net\/blog\/tutorial\/simple-restful-services-in-glassfish-pt-2\/","title":{"rendered":"Simple RESTful services in Glassfish Pt 2"},"content":{"rendered":"<p>In part 2 of this article, we are going to create a data driven web service that will return JSON and XML to the client, and then use jQuery to add a new item to the database and display it in our page.<br \/>\n<!--more--><br \/>\nIn part 1, we looked at creating simple web services and now we&#8217;re going to look at making something more practical and interesting. We&#8217;ll start from where we left off with the source code as it was at the end of the part 1 which you can download from here (<a href=\"http:\/\/www.andygibson.net\/blog\/wp-content\/uploads\/2011\/02\/restwebdemo_pt1.zip\">restwebdemo_pt1<\/a>) if you want to follow along. If not, the final source can be downloaded from here (<a href='http:\/\/www.andygibson.net\/blog\/wp-content\/uploads\/2011\/03\/restwebdemo_pt2.zip'>restwebdemo_pt2<\/a>).<\/p>\n<ol>\n<li>First off, we&#8217;re going to change the entity manager that is available for injection to be request scoped. To do this, open up <code>DataRepositoryProducer.java<\/code> and change the <code>@ConversationScoped<\/code> annotation on the <code>getEntityManager()<\/code> method to be <code>@RequestScoped<\/code>.  The reason for this is documented here in <a href=\"http:\/\/www.andygibson.net\/blog\/article\/a-little-less-conversation\/\">A Little Less Conversation<\/a>.<\/li>\n<li>Next we are going to create a simple dao for Course objects, and the only reason to do this is to demonstrate the integration of CDI and the ability to layer your code. Create a new class called <code>CourseDao<\/code> with the following code.\n<pre class=\"brush: java; title: ; notranslate\" title=\"\">\r\npackage org.fluttercode.restwebdemo.bean;\r\n\r\n@Stateless\r\n@LocalBean\r\npublic class CourseDao {\r\n\r\n\t@Inject @DataRepository\r\n\tprivate EntityManager entityManager;\r\n\t\r\n\tpublic void save(Course course) {\r\n\t\tentityManager.persist(course);\r\n\t}\r\n\t\r\n\tpublic Course update(Course course) {\r\n\t\treturn entityManager.merge(course);\r\n\t}\r\n\t\r\n\tpublic Course find(Long id) {\r\n\t\treturn entityManager.find(Course.class, id);\r\n\t}\r\n}\r\n<\/pre>\n<p>This just injects an entityManager and uses it to locate, save and update Course objects.\n<\/li>\n<li>Now create a new <code>CourseService<\/code> bean that will handle the web services. To start with we want to make it a stateless EJB and inject the course Dao. We are going start by re-implementing the method to return the course name for the given id.\n<pre class=\"brush: java; title: ; notranslate\" title=\"\">\r\n\t@Path(&quot;courseName\/{id}&quot;)\r\n\t@GET\r\n\tpublic String getCourseName(@PathParam(&quot;id&quot;) Long id) {\r\n\t\tCourse course = courseDao.find(id);\r\n\t\tif (course == null) {\r\n\t\t\treturn &quot;Course not found&quot;;\r\n\t\t} else {\r\n\t\t\treturn course.getTitle();\r\n\t\t}\r\n\t}\r\n<\/pre>\n<\/ol>\n<p>To see this method in action, deploy the application and go to <a href=\"http:\/\/localhost:8080\/restwebdemo\/rest\/course\/courseName\/126\">http:\/\/localhost:8080\/restwebdemo\/rest\/course\/courseName\/126<\/a>. Now we know everything is working and hooked up together, we can look at adding some new functionality. <\/p>\n<p>Let&#8217;s start by returning a course with a given id from the service. This is fairly simple given what we already know. The only thing to determine now is what format to return the object as and to convert it to that type. Luckily, Java EE already provides JAXB which can take an object graph and convert it to XML for us as long as we annotate the classes with the annotations to let the JAXB implementation know how to convert it. The same annotations can be used by the body writer that handles JSON.<\/p>\n<p>First we&#8217;ll annotate the <code>Course<\/code> class and make a couple of changes that we need to. Next we&#8217;ll create methods to return a <code>Cource<\/code> object from the service in XML or JSON format.<\/p>\n<ol>\n<li>Open the <code>Course<\/code> class and add the following annotations to the class.\n<pre class=\"brush: java; title: ; notranslate\" title=\"\">\r\n@Entity\r\n@XmlRootElement\r\n@XmlAccessorType(XmlAccessType.FIELD)\r\npublic class Course extends BaseEntity {\r\n   ...\r\n   ...\r\n}\r\n<\/pre>\n<p>This tells the JAXB processor that this class can be serialized and to access the values using fields in the class. This also means that any other annotations we want to add to control the serialization needs to be applied to the fields.\n<\/li>\n<p>This is a simple example, so we don&#8217;t want to serialize the <code>teacher<\/code> or <code>enrolled<\/code> properties which we can do by marking them with the <code>@XmlTransient<\/code> attributes. Also, remove the <code>@NotNull<\/code> annotation from the <code>teacher<\/code> attribute as we will need it blank later. The following code shows the fields with both the JAXB and JPA annotations. JAXB (like JPA) uses default conventions for fields that don&#8217;t have annotations : <\/p>\n<pre class=\"brush: java; title: ; notranslate\" title=\"\">\r\n\t@Column(length = 32, nullable = false)\r\n\t@Size(max = 32)\r\n\t@NotEmpty(message = &quot;title is required&quot;)\r\n\tprivate String title;\r\n\r\n\t@Column(length = 8, nullable = false)\r\n\t@Size(max = 8  )\r\n\t@NotEmpty(message = &quot;code is required&quot;)\r\n\tprivate String code;\r\n\r\n\t@ManyToOne(fetch = FetchType.LAZY)\r\n\t@XmlTransient\r\n\tprivate Teacher teacher;\r\n\r\n\t@ManyToMany(mappedBy = &quot;enrolled&quot;)\r\n\t@XmlTransient\r\n\tprivate List&lt;Student&gt; students = new ArrayList&lt;Student&gt;();\r\n<\/pre>\n<p>We are just using a simple JAXB model for the sake of the example which is why we aren&#8217;t including the <code>Teacher<\/code> and <code>Student<\/code> classes.\n<\/li>\n<li>Now in our <code>CourseService<\/code> class we will create methods to return the course entity and we will create one for JSON and one for XML.\n<pre class=\"brush: java; title: ; notranslate\" title=\"\">\r\n\t@Path(&quot;find\/{id}\/xml&quot;)\r\n\t@GET\r\n\t@Produces(MediaType.APPLICATION_XML)\r\n\tpublic Course getCourseAsXml(@PathParam(&quot;id&quot;) Long id) {\r\n\t\treturn courseDao.find(id);\r\n\t}\r\n\t\r\n\t@Path(&quot;find\/{id}\/json&quot;)\r\n\t@GET\r\n\t@Produces(MediaType.APPLICATION_JSON)\r\n\tpublic Course getCourseAsJson(@PathParam(&quot;id&quot;) Long id) {\r\n\t\treturn courseDao.find(id);\r\n\t}\r\n<\/pre>\n<\/li>\n<p><small>(note : At this point, I had to switch to using Hibernate as the JPA provider since JAXB didn&#8217;t like the interface EclipseLink used for proxying the properties. You can do this using the Glassfish update tool).<\/small><br \/>\nIf you redeploy the application and browse to <a href=\"http:\/\/localhost:8080\/restwebdemo\/rest\/course\/find\/1\/json\">http:\/\/localhost:8080\/restwebdemo\/rest\/course\/find\/1\/json<\/a> you should be prompted to save a file, or it will display the text, but the content should be something like : <\/p>\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">\r\n{&quot;createdOn&quot;:&quot;2010-08-27T16:36:57.015-04:00&quot;,\r\n  &quot;id&quot;:&quot;1&quot;,\r\n  &quot;modifiedOn&quot;:&quot;2010-08-27T16:36:57.015-04:00&quot;,\r\n  &quot;title&quot;:&quot;Computing for Beginners&quot;,\r\n   &quot;code&quot;:&quot;CS101&quot;}\r\n<\/pre>\n<p>or if you go to <a href=\"http:\/\/localhost:8080\/restwebdemo\/rest\/course\/find\/1\/xml\">http:\/\/localhost:8080\/restwebdemo\/rest\/course\/find\/1\/xml<\/a> you will get an XML version :<\/p>\n<pre class=\"brush: xml; title: ; notranslate\" title=\"\">\r\n&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;yes&quot;?&gt;\r\n&lt;course&gt;\r\n\t&lt;createdOn&gt;2010-08-27T16:36:57.015-04:00&lt;\/createdOn&gt;\r\n\t&lt;id&gt;1&lt;\/id&gt;\r\n\t&lt;modifiedOn&gt;2010-08-27T16:36:57.015-04:00&lt;\/modifiedOn&gt;\r\n\t&lt;title&gt;Computing for Beginners&lt;\/title&gt;\r\n\t&lt;code&gt;CS101&lt;\/code&gt;\r\n&lt;\/course&gt;\r\n<\/pre>\n<p>Now we can grab objects from our web service, we should look at creating objects from the service. We add a new method that takes the title and code values, creates a new <code>Course<\/code> with those values and saves it using the <code>courseDao<\/code>.<\/p>\n<pre class=\"brush: java; title: ; notranslate\" title=\"\">\r\n\t@Path(&quot;create&quot;)\r\n\t@PUT\r\n\t@Produces(MediaType.APPLICATION_JSON)\r\n\tpublic Course createCourse(@FormParam(&quot;title&quot;) String title,@FormParam(&quot;code&quot;) String code) {\r\n\t\tCourse course = new Course();\r\n\t\tcourse.setTitle(title);\r\n\t\tcourse.setCode(code);\t\t\r\n\t\tcourseDao.save(course);\t\t\r\n\t\treturn course;\r\n\t}\r\n<\/pre>\n<p>Here I&#8217;ve used the <code>FormParam<\/code> annotations to plug form values into the method call. You&#8217;ll notice that using REST conventions, the method to create a course uses the PUT type of request. Now let&#8217;s create a page to enter a title and code and create the course. Notice that our method returns the created course so we can return the course back to the user. This is probably not ideal, but suits for the purposes of demonstration. Now lets create a new HTML page to allow for data entry and calling the web service to create the Course.<\/p>\n<pre class=\"brush: xml; title: ; notranslate\" title=\"\">\r\n&lt;html&gt;\r\n&lt;head&gt;\r\n&lt;title&gt;Insert title here&lt;\/title&gt;\r\n&lt;script type=&quot;text\/javascript&quot;\r\n\tsrc=&quot;http:\/\/localhost:8080\/restwebdemo\/jquery-1.4.min.js&quot;&gt;\r\n&lt;\/script&gt;\r\n&lt;\/head&gt;\r\n&lt;body&gt;\r\n&lt;div id=&quot;message&quot;\r\n\tstyle=&quot;display: none; background: #d0d0f0; padding: 12px&quot;&gt;Message Div&lt;\/div&gt;\r\n&lt;form action=&quot;rest\/course\/create&quot; method=&quot;POST&quot;&gt;\r\n\t\r\n    &lt;fieldset&gt;\r\n    \t&lt;legend&gt;Create Course&lt;\/legend&gt;\r\n    \t&lt;p&gt;\r\n\t        Title&lt;br \/&gt;\r\n    \t    &lt;input id=&quot;title&quot; \/&gt;&lt;br \/&gt;\r\n    \t&lt;\/p&gt;\r\n    \t&lt;p&gt;\r\n        \tCode&lt;br \/&gt;\r\n        \t&lt;input id=&quot;code&quot; \/&gt;&lt;br \/&gt;\r\n    \t&lt;\/p&gt;\r\n    \t&lt;input type=&quot;submit&quot; id=&quot;submit&quot; \/&gt;\r\n\t&lt;\/fieldset&gt;\r\n&lt;\/form&gt;\r\n&lt;\/body&gt;\r\n\r\n&lt;script type=&quot;text\/javascript&quot;&gt;\r\n\r\n\/\/jquery pieces\r\n$(document).ready(function() {\r\n\t\t\r\n    \/\/change the submit button behaviouus.\r\n    $('#submit').click(function () {   \t\t\r\n\t\tvar title = $(&quot;input#title&quot;).val();\r\n\t\tvar code = $(&quot;input#code&quot;).val();\r\n\r\n\t\tparams = &quot;title=&quot;+title+&quot;&amp;code=&quot;+code;\r\n\t\t\/\/alert(&quot;posting form : &quot;+data);\t\t\r\n        $.ajax({  \r\n               type: &quot;PUT&quot;,  \r\n               url: &quot;rest\/course\/create&quot;,  \r\n               data: params,  \r\n               success: function(result) {\r\n        \t\t   showMessage(&quot;Created Course &quot;+result.title+&quot; with id &quot;+result.id+&quot; on &quot;+result.createdOn);\r\n               }  \r\n        });  \r\n\t\treturn false;\t\t\t\t\r\n    });\r\n});\r\n\r\nfunction showMessage(msg) {\r\n\t  $('#message').html(msg);\r\n\t  $('#message').fadeIn('fast');\r\n\t   $('#message').delay(3000).fadeOut('slow');\r\n}\r\n&lt;\/script&gt;\r\n&lt;\/html&gt;\r\n<\/pre>\n<p>This looks a lot code, but not really. We import jquery to help us post our form, and we create our form with the two fields. We use JQuery to add an event handler so when you click submit, it packages up the form, calls our web service with a PUT type of request and grabs the returned object as a JSON object, and displays a message using the values from the new instance obtained from the server. To verify that your course has been created, go to the <a href=\"http:\/\/localhost:8080\/restwebdemo\/home.jsf\">front page<\/a> and you should see it listed.<\/p>\n<p>That about wraps it up for this post, the source code can be downloaded from (<a href='http:\/\/www.andygibson.net\/blog\/wp-content\/uploads\/2011\/03\/restwebdemo_pt2.zip'>restwebdemo_pt2<\/a>), just unzip it, use <code>mvn clean package<\/code> and deploy the war to glassfish and use the URLs mentioned in the article.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>In part 2 of this article, we are going to create a data driven web service that will return JSON and XML to the client, and then use jQuery to add a new item to the database and display it in our page.<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_monsterinsights_skip_tracking":false,"_monsterinsights_sitenote_active":false,"_monsterinsights_sitenote_note":"","_monsterinsights_sitenote_category":0},"categories":[64],"tags":[49,52,6,72,50,67,106,104,103],"_links":{"self":[{"href":"https:\/\/www.andygibson.net\/blog\/wp-json\/wp\/v2\/posts\/1765"}],"collection":[{"href":"https:\/\/www.andygibson.net\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.andygibson.net\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.andygibson.net\/blog\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/www.andygibson.net\/blog\/wp-json\/wp\/v2\/comments?post=1765"}],"version-history":[{"count":5,"href":"https:\/\/www.andygibson.net\/blog\/wp-json\/wp\/v2\/posts\/1765\/revisions"}],"predecessor-version":[{"id":1770,"href":"https:\/\/www.andygibson.net\/blog\/wp-json\/wp\/v2\/posts\/1765\/revisions\/1770"}],"wp:attachment":[{"href":"https:\/\/www.andygibson.net\/blog\/wp-json\/wp\/v2\/media?parent=1765"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.andygibson.net\/blog\/wp-json\/wp\/v2\/categories?post=1765"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.andygibson.net\/blog\/wp-json\/wp\/v2\/tags?post=1765"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}