{"id":29,"date":"2017-12-25T13:04:00","date_gmt":"2017-12-25T13:04:00","guid":{"rendered":""},"modified":"2019-03-12T20:10:16","modified_gmt":"2019-03-12T20:10:16","slug":"quick-and-dirty-java-service-template","status":"publish","type":"post","link":"https:\/\/ntlx.org\/de\/2017\/12\/quick-and-dirty-java-service-template.html","title":{"rendered":"Quick and Dirty Java Service Template"},"content":{"rendered":"<p>To get a java service running, you don&#8217;t always need to start a tomcat and deploy a war file, as described in an <a href=\"http:\/\/localhost:8001\/?p=36\">earlier blog post<\/a>. Even if tomcat gives you a number of benefits, such as user management and database connection handling, sometimes you do not need this and just want to start up a small http server to provide a bit of functionality.<\/p>\n<h2>The template contents<\/h2>\n<p>To get such projects started as fast as possible, I created the quick and dirty java service template, where I collected stuff I find most useful to implement a new java service:<\/p>\n<p>It uses the&nbsp;<a href=\"https:\/\/javaee.github.io\/grizzly\/\">grizzly http server<\/a>&nbsp;to provide the web server, which makes starting an http server running java code as easy as executing a jar file.<br \/>Often, communication between a web page and a java backend works easiest by sending a JSON document. This is why we include the <a href=\"https:\/\/github.com\/google\/gson\">gson<\/a> JSON parser in the template.<br \/>In addition to some java code, we will also package static content, such as html files or images to the jar package. All this can be accessed via the same URL after starting the jar file.<\/p>\n<p>Checkout the service template at&nbsp;<a href=\"https:\/\/github.com\/NautiluX\/JavaServiceTemplate\">https:\/\/github.com\/NautiluX\/JavaServiceTemplate<\/a>.<\/p>\n<h2>Start up<\/h2>\n<p>To build and run the server, we use mvn. So compilation and start can be done using the following two maven commands:<\/p>\n<p><span style=\"font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;\">mvn clean install<\/span><br \/><span style=\"font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;\"><br \/><\/span><span style=\"font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;\">mvn exec:java<\/span><\/p>\n<p>now we can access our small server at <span style=\"font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;\">localhost:5678<\/span>.<\/p>\n<h2>Customize<\/h2>\n<p>Now for some more details to show you where to put server code and static content.<br \/>The project is set up using maven. That means all our java code can be found in <span style=\"font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;\">src\/main\/java<\/span>. When we start the server, by executing<span style=\"font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;\"> mvn exec:java<\/span>, the class <span style=\"font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;\">org.ntlx.server.Main<\/span> will be executed, which creates the http server.<br \/><span style=\"font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;\"><br \/><\/span><\/p>\n<div><span style=\"font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace; font-size: x-small;\"><span>package<\/span> org.ntlx.server;<\/span><\/div>\n<div><span style=\"font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace; font-size: x-small;\"><br \/><\/span><\/div>\n<div><span style=\"font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace; font-size: x-small;\"><span>import<\/span> com.sun.jersey.api.container.grizzly2.GrizzlyServerFactory;<\/span><\/div>\n<div><span style=\"font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace; font-size: x-small;\"><span>import<\/span> com.sun.jersey.api.core.*;<\/span><\/div>\n<div><span style=\"font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace; font-size: x-small;\"><br \/><\/span><\/div>\n<div><span style=\"font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace; font-size: x-small;\"><span>import<\/span> java.io.IOException;<\/span><\/div>\n<div><span style=\"font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace; font-size: x-small;\"><br \/><\/span><\/div>\n<div><span style=\"font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace; font-size: x-small;\"><span>import<\/span> org.glassfish.grizzly.http.server.*;<\/span><\/div>\n<div><span style=\"font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace; font-size: x-small;\"><br \/><\/span><\/div>\n<div><span style=\"font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace; font-size: x-small;\">public<span> <\/span>class<span> Main {<\/span><\/span><\/div>\n<div><span style=\"font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace; font-size: x-small;\"><br \/><\/span><\/div>\n<div><span style=\"font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace; font-size: x-small;\"><span>&nbsp; <\/span><span>public<\/span> <span>static<\/span> <span>void<\/span> main(String args[])<\/span><\/div>\n<div><span style=\"font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace; font-size: x-small;\"><span>&nbsp; &nbsp; &nbsp; <\/span><span>throws<\/span> IllegalArgumentException, NullPointerException, IOException {<\/span><\/div>\n<div><span style=\"font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace; font-size: x-small;\"><span>&nbsp; &nbsp; <\/span>Main main = <span>new<\/span> Main();<\/span><\/div>\n<div><span style=\"font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace; font-size: x-small;\"><span>&nbsp; &nbsp; <\/span>main.startServer();<\/span><\/div>\n<div><span style=\"font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace; font-size: x-small;\"><span>&nbsp; <\/span>}<\/span><\/div>\n<div><span style=\"font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace; font-size: x-small;\"><br \/><\/span><\/div>\n<div><span style=\"font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace; font-size: x-small;\"><span>&nbsp; <\/span><span>public<\/span> <span>void<\/span> startServer() <span>throws<\/span> IllegalArgumentException, NullPointerException, IOException {<\/span><\/div>\n<div><span style=\"font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace; font-size: x-small;\"><span>&nbsp; &nbsp; <\/span>ResourceConfig rc = <span>new<\/span> PackagesResourceConfig(<span>&#8220;org.ntlx.service&#8221;<\/span>);<\/span><\/div>\n<div><span style=\"font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace; font-size: x-small;\"><span>&nbsp; &nbsp; <\/span>HttpServer myServer = GrizzlyServerFactory.createHttpServer(<span>&#8220;http:\/\/0.0.0.0:9876\/calc\/&#8221;<\/span>, rc);<\/span><\/div>\n<div><span style=\"font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace; font-size: x-small;\"><span>&nbsp; &nbsp; <\/span>HttpHandler httpHandler = <span>new<\/span> CLStaticHttpHandler(HttpServer.<span>class<\/span>.getClassLoader(), <span>&#8220;\/ui\/&#8221;<\/span>);<\/span><\/div>\n<div><span style=\"font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace; font-size: x-small;\"><span>&nbsp; &nbsp; <\/span>myServer.getServerConfiguration().addHttpHandler(httpHandler, <span>&#8220;\/&#8221;<\/span>);<\/span><\/div>\n<div><span style=\"font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace; font-size: x-small;\"><span>&nbsp; &nbsp; <\/span><span>try<\/span> {<\/span><\/div>\n<div><span style=\"font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace; font-size: x-small;\"><span>&nbsp; &nbsp; &nbsp; <\/span>myServer.start();<\/span><\/div>\n<div><span style=\"font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace; font-size: x-small;\"><span>&nbsp; &nbsp; &nbsp; <\/span>Thread.currentThread().join();<\/span><\/div>\n<div><span style=\"font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace; font-size: x-small;\"><span>&nbsp; &nbsp; <\/span>} <span>catch<\/span> (Exception e) {<\/span><\/div>\n<div><span style=\"font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace; font-size: x-small;\"><span>&nbsp; &nbsp; &nbsp; <\/span>System.err.println(e);<\/span><\/div>\n<div><span style=\"font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace; font-size: x-small;\"><span>&nbsp; &nbsp; <\/span>} <span>finally<\/span> {<\/span><\/div>\n<div><span style=\"font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace; font-size: x-small;\"><span>&nbsp; &nbsp; &nbsp; <\/span>myServer.stop();<\/span><\/div>\n<div><span style=\"font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace; font-size: x-small;\"><span>&nbsp; &nbsp; <\/span>}<\/span><\/div>\n<div><span style=\"font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace; font-size: x-small;\"><span>&nbsp; <\/span>}<\/span><\/div>\n<p><\/p>\n<div><span style=\"font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace; font-size: x-small;\">}<\/span><\/div>\n<p>The http server is listening on port 9876 and is searching for service endpoints in the package <span style=\"font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;\">org.ntlx.service<\/span>.<\/p>\n<h3>GET endpoint<\/h3>\n<div>To implement the code for our service, we take a look at the example implementation of the service template. We want our GET endpoint as heartbeat to check if the backend is up and running. Therefore we want it to just return<\/div>\n<div><span style=\"font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace; font-size: x-small;\">{<\/span><\/div>\n<div><span style=\"font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace; font-size: x-small;\">&nbsp; &nbsp; &#8220;getCall&#8221;: &#8220;succeeded&#8221;<\/span><\/div>\n<div><span style=\"font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace; font-size: x-small;\">}<\/span><\/div>\n<div>The code for this simple get endpoint can be found in the class <span style=\"font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;\">org.ntlx.service.SumService<\/span> in the function dummyGet:<\/div>\n<div><span style=\"font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace; font-size: x-small;\"><br \/><\/span><\/div>\n<div><\/p>\n<div><span style=\"font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace; font-size: x-small;\"><span>package<\/span> org.ntlx.service;<\/span><\/div>\n<div><span style=\"font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace; font-size: x-small;\"><br \/><\/span><\/div>\n<div><span style=\"font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace; font-size: x-small;\"><span>import<\/span> com.google.gson.*;<\/span><\/div>\n<div><span style=\"font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace; font-size: x-small;\"><span>import<\/span> javax.ws.rs.*;<\/span><\/div>\n<div><span style=\"font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace; font-size: x-small;\"><br \/><\/span><\/div>\n<div><span style=\"font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace; font-size: x-small;\">@Path<span>(<\/span><span>&#8220;sum&#8221;<\/span><span>)<\/span><\/span><\/div>\n<div><span style=\"font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace; font-size: x-small;\"><span>public<\/span> <span>class<\/span> SumService {<\/span><\/div>\n<div><span style=\"font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace; font-size: x-small;\"><br \/><\/span><\/div>\n<div><span style=\"font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace; font-size: x-small;\"><span><span>&nbsp; <\/span><\/span>@GET<\/span><\/div>\n<div><span style=\"font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace; font-size: x-small;\"><span><span>&nbsp; <\/span><\/span><span>@Produces<\/span><span>(MediaType.<\/span>APPLICATION_JSON<span>)<\/span><\/span><\/div>\n<div><span style=\"font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace; font-size: x-small;\"><span>&nbsp; <\/span><span>public<\/span> String dummyGet() {<\/span><\/div>\n<div><span style=\"font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace; font-size: x-small;\"><span>&nbsp; &nbsp; <\/span>JsonObject <span>result<\/span> = <span>new<\/span> JsonObject();<\/span><\/div>\n<div><span style=\"font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace; font-size: x-small;\"><span>&nbsp; &nbsp; <\/span><span>result<\/span>.addProperty(<span>&#8220;getCall&#8221;<\/span>, <span>&#8220;succeeded&#8221;<\/span>);<\/span><\/div>\n<div><span style=\"font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace; font-size: x-small;\"><span>&nbsp; &nbsp; <\/span><span>return<\/span> <span>result<\/span>.toString();<\/span><\/div>\n<div><span style=\"font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace; font-size: x-small;\"><span>&nbsp; <\/span>}<\/span><\/div>\n<div><span style=\"font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace; font-size: x-small;\"><br \/><\/span><\/div>\n<div><span style=\"color: black; font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace; font-size: x-small;\">&nbsp; &#8230;<\/span><\/div>\n<div>                                <\/div>\n<div><span style=\"font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace; font-size: x-small;\">}<\/span><\/div>\n<div><\/div>\n<\/div>\n<div>We tell the http service, that we want requests that come in to the path \/sum to be handled by this class. With the annotation <span style=\"font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;\">@GET<\/span> we tell it, that this function shall be called by GET http requests. With the <span style=\"font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;\">@Produces<\/span> annotation we get the http response header <span style=\"font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;\">application\/json<\/span>. To create this simple json string, we use the Gson library.<\/p>\n<\/div>\n<h3>POST\/PUT\/&#8230;<\/h3>\n<div>To create endpoints for other type of requests, we can do the same as for get. Lets have a look at the backend for our summing service, which should sum a list of numbers coming in as JSON.<\/div>\n<div><\/div>\n<div><\/p>\n<div><span style=\"font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace; font-size: x-small;\"><span>&nbsp;&nbsp;<\/span>@POST<\/span><\/div>\n<div><span style=\"font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace; font-size: x-small;\"><span>&nbsp; <\/span><span>@Produces<\/span><span>(MediaType.<\/span>APPLICATION_JSON<span>)<\/span><\/span><\/div>\n<div><span style=\"font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace; font-size: x-small;\"><span>&nbsp; <\/span><span>public<\/span> String dummyPost(<span>String<\/span> <span>body<\/span>) {<\/span><\/div>\n<div><span style=\"font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace; font-size: x-small;\"><span>&nbsp; &nbsp; <\/span>CalculatorInput <span>input<\/span> = <span>new<\/span> Gson().fromJson(<span>body<\/span>, CalculatorInput.<span>class<\/span>);<\/span><\/div>\n<div><span style=\"font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace; font-size: x-small;\"><span>&nbsp; &nbsp; <\/span>JsonObject <span>result<\/span> = <span>new<\/span> JsonObject();<\/span><\/div>\n<div><span style=\"font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace; font-size: x-small;\"><span>&nbsp; &nbsp; <\/span><span>result<\/span>.addProperty(<span>&#8220;result&#8221;<\/span>, <span>input<\/span>.calculateSum());<\/span><\/div>\n<div><span style=\"font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace; font-size: x-small;\"><span>&nbsp; &nbsp; <\/span><span>return<\/span> <span>result<\/span>.toString();<\/span><\/div>\n<div><span style=\"font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace; font-size: x-small;\"><span>&nbsp; <\/span>}<\/span><\/div>\n<div><\/div>\n<\/div>\n<p>We tell the server we are listening for POST calls (the same could be done for POST, PUT, DELETE, etc.). We add a String parameter to the function, which will be filled up with the request body of the incoming POST call. To get the input, we again use GSON to instantiate an object of the <span style=\"font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;\">CalculatorInput<\/span> class, which executes our &#8211; very complex &#8211; workload in the function call <span style=\"font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;\">calculateSum()<\/span>.<\/p>\n<h3>Static Content<\/h3>\n<div>Static content &#8211; like html files &#8211; must be located in the class path, so the http server can find it. That means we have to rebuild the jar file any time we want to change our static content. We told the http server where to search for it (<span style=\"font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;\">\/ui\/<\/span>) and where to place it (<span style=\"font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;\">\/<\/span>). That means we can put our static content into the folder <span style=\"font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;\">src\/main\/resources\/ui<\/span><span style=\"font-family: inherit;\">, and they will be included in our jar file automatically and found by the http server under the path \/. That&#8217;s why we are routed to the file created as <\/span><span style=\"font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;\">src\/main\/resources\/ui\/index.html<\/span><span style=\"font-family: inherit;\">&nbsp;when we visit <\/span><span style=\"font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;\">localhost:9876<\/span><span style=\"font-family: inherit;\"> after starting the server.<\/span><\/div>","protected":false},"excerpt":{"rendered":"To get a java service running, you don&#8217;t always need to start a tomcat and deploy a war file, as described in an earlier blog post. Even if tomcat gives you a number of benefits, such as user management and database connection handling, sometimes you do not need this and just want to start up&#8230; <a class=\"view-article\" href=\"https:\/\/ntlx.org\/de\/2017\/12\/quick-and-dirty-java-service-template.html\">Artikel ansehen<\/a>","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[],"tags":[24,5,23],"_links":{"self":[{"href":"https:\/\/ntlx.org\/de\/wp-json\/wp\/v2\/posts\/29"}],"collection":[{"href":"https:\/\/ntlx.org\/de\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/ntlx.org\/de\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/ntlx.org\/de\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/ntlx.org\/de\/wp-json\/wp\/v2\/comments?post=29"}],"version-history":[{"count":1,"href":"https:\/\/ntlx.org\/de\/wp-json\/wp\/v2\/posts\/29\/revisions"}],"predecessor-version":[{"id":50,"href":"https:\/\/ntlx.org\/de\/wp-json\/wp\/v2\/posts\/29\/revisions\/50"}],"wp:attachment":[{"href":"https:\/\/ntlx.org\/de\/wp-json\/wp\/v2\/media?parent=29"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/ntlx.org\/de\/wp-json\/wp\/v2\/categories?post=29"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/ntlx.org\/de\/wp-json\/wp\/v2\/tags?post=29"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}