{"id":2201,"date":"2017-04-26T21:48:10","date_gmt":"2017-04-26T21:48:10","guid":{"rendered":"http:\/\/blog.paranoidprofessor.com\/?p=2201"},"modified":"2017-04-26T21:48:10","modified_gmt":"2017-04-26T21:48:10","slug":"restful-services-in-java-360-degree-of-restful-server","status":"publish","type":"post","link":"https:\/\/blog.paranoidprofessor.com\/index.php\/2017\/04\/26\/restful-services-in-java-360-degree-of-restful-server\/","title":{"rendered":"Restful services in Java &#8211; 360 degree of restful server"},"content":{"rendered":"<p>This is the blog final entry for a restful service web server. \u00a0I have attempted to create more than your typical &#8220;foo&#8221; &#8220;bar&#8221; type example program. My final blog on restful services will be a fairly complete service that could be used to provide price data supplied by several &#8220;banks&#8221; on various exchanges.<\/p>\n<p>The data can be \u00a0pseudo randomly generated to be later\u00a0retrieved and displayed by web browser using java script to fetch, extract and display the data from a JSON formatted string.<\/p>\n<p>A real production server would save server\u00a0data in a more permanent manner such as a database or even perhaps files if the data lent itself to that. I didn&#8217;t feel like creating database so I have skipped over this step by adding a restful service for generating some data which is stored in memory. This is just a &#8220;temporary&#8221; server that is available for testing and not for real permanence.<\/p>\n<p>This example server has the following methods.<\/p>\n<ul>\n<li>generate<\/li>\n<li>count<\/li>\n<li>(index).xml<\/li>\n<li>(index).json<\/li>\n<li>(index).text<\/li>\n<li>fetch<\/li>\n<li>addOne<\/li>\n<li>retrieve<\/li>\n<li>retrieveall<\/li>\n<\/ul>\n<p>The generate method is perhaps the most important of these for testing. Simply call this restful service in the beginning to generate twenty items by default or pass in a specific count to generate that many test items.<\/p>\n<p>The generated data is put into a simple hash with the key to the hash being the simple index.<\/p>\n<p>To look at the data that is in the hash the count, (index).xml, (index).json or (index).text.<\/p>\n<p>The fetch method is actually the other main method specifically for a web client. This web service will retrieve an array of market prices in JSON format.<\/p>\n<p>In a few days I will be providing a html client that will use this server and retrieve the data in the JSON format and display that to the web page.<\/p>\n<h2>PriceServer.java<\/h2>\n<pre>package com.acmesoft;\r\n\r\nimport java.io.File;\r\nimport java.io.FileWriter;\r\nimport java.io.IOException;\r\n\r\nimport java.math.BigDecimal;\r\nimport java.net.URI;\r\nimport java.net.URISyntaxException;\r\nimport java.util.HashMap;\r\nimport java.util.Iterator;\r\n\r\nimport javax.ws.rs.Consumes;\r\nimport javax.ws.rs.DefaultValue;\r\nimport javax.ws.rs.GET;\r\nimport javax.ws.rs.POST;\r\nimport javax.ws.rs.Path;\r\nimport javax.ws.rs.PathParam;\r\nimport javax.ws.rs.Produces;\r\nimport javax.ws.rs.QueryParam;\r\nimport javax.ws.rs.core.Context;\r\nimport javax.ws.rs.core.MediaType;\r\nimport javax.ws.rs.core.Response;\r\nimport javax.ws.rs.core.UriInfo;\r\nimport javax.ws.rs.WebApplicationException;\r\n\r\n@Path(\"\/price\")\r\npublic class PriceServer\r\n{\r\n\t\/\/ should really be a database\r\n\tprivate static HashMap&lt;Integer,MarketPrice&gt; pricedatabase = new HashMap&lt;Integer,MarketPrice&gt;();\r\n\tprivate static int databasecount = 0;\r\n\r\n\t\/\/\r\n\t\/\/ index is the actual 0 - n-1 of the map.\r\n\t\/\/\r\n\tprivate String rangeAsXML(int start, int stop)\r\n\t{\r\n\t\tString retval = \"<!--?xml version=\\\"1.0\\\"?-->\";\r\n\t\tretval += \"\";\r\n\r\n\t\tfor (int idx = start; idx &lt;= stop; idx++)\r\n\t\t{\r\n\t\t\tMarketPrice item = null;\r\n\t\t\titem = pricedatabase.get(idx);\r\n\r\n\t\t\tif (item != null)\r\n\t\t\t\tretval += item.xmlString();\r\n\t\t}\r\n\r\n\t\tretval += \"\";\r\n\r\n\t\treturn retval;\r\n\t}\r\n\r\n\t\/\/\r\n\t\/\/ index is the actual 0 - n-1 of the map.\r\n\t\/\/\r\n\tprivate String rangeAsJSON(int start, int stop)\r\n\t{\r\n\t\tString retval = \"{ \\\"records\\\": [\";\r\n\r\n\t\tfor (int idx = start; idx &lt;= stop; idx++)\r\n\t\t{\r\n\t\t\tMarketPrice item = null;\r\n\t\t\titem = pricedatabase.get(idx);\r\n\r\n\t\t\tif (item != null)\r\n\t\t\t{\r\n\t\t\t\tif (idx != start)\r\n\t\t\t\t\tretval += \", \";\r\n\t\t\t\tretval += item.JSONString();\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\tretval += \"] }\";\r\n\r\n\t\treturn retval;\r\n\t}\r\n\r\n\t\/\/ initialize the price cache, this is pretty much only for debugging\r\n\t\/\/ \r\n\t\/\/ this will generate 20 items by default\r\n\t\/\/ http:\/\/localhost:8080\/ThirdRestful\/price\/generate\r\n\t\/\/\r\n\t\/\/ this will generate 100 items instead \r\n\t\/\/ http:\/\/localhost:8080\/ThirdRestful\/price\/generate?count=100\r\n\t@GET\r\n\t@Path(\"\/generate\")\r\n\t@Produces( {MediaType.APPLICATION_XML})\r\n\tpublic Response generate(@Context UriInfo ui, @DefaultValue(\"20\") @QueryParam(\"count\") int debugcount) throws URISyntaxException\r\n\t{\r\n\t\tString path = ui.getAbsolutePath().toString() ;\r\n\t\tURI uri = new URI(path);\r\n\r\n\t\tMarketPrice newprice = null;\r\n\t\tfor (int idx = 0; idx &lt; debugcount; idx++)\r\n\t\t{\r\n\t\t\tswitch (idx % 5)\r\n\t\t\t{\r\n\t\t\tcase 0:\r\n\t\t\t\tnewprice = new MarketPrice(\"EUR\/USD\", \"DBK\", new BigDecimal(1.056), \"DTB\");\r\n\t\t\t\tbreak;\r\n\t\t\tcase 1:\r\n\t\t\t\tnewprice = new MarketPrice(\"GBP\/EUR\", \"BCY\", new BigDecimal(1.179), \"LIFFE\");\r\n\t\t\t\tbreak;\r\n\t\t\tcase 2:\r\n\t\t\t\tnewprice = new MarketPrice(\"USD\/MXN\", \"C\", new BigDecimal(19.1), \"CME\");\r\n\t\t\t\tbreak;\r\n\t\t\tcase 3:\r\n\t\t\t\tnewprice = new MarketPrice(\"EUR\/USD\", \"0UB\", new BigDecimal(1.059), \"SOFFEX\");\r\n\t\t\t\tbreak;\r\n\t\t\tcase 4:\r\n\t\t\t\tnewprice = new MarketPrice(\"VEF\/USD\", \"JPM\", new BigDecimal(0.1001), \"NYSE\");\r\n\t\t\t\tbreak;\r\n\t\t\t}\r\n\t\t\tnewprice.setId(databasecount);\r\n\t\t\tpricedatabase.put(databasecount, newprice);\r\n\t\t\tdatabasecount++;\r\n\t\t}\r\n\r\n\t\t\/\/return Response.created(uri).contentLocation(uri).status(Response.Status.OK).build(); \r\n\t\treturn Response.created(uri).contentLocation(uri).status(Response.Status.OK).entity(\"\" + databasecount +\"\").build(); \r\n\t}\r\n\r\n\t\/\/ get the count of items\r\n\t\/\/ \r\n\t\/\/ http:\/\/localhost:8080\/ThirdRestful\/price\/count\r\n\t@GET\r\n\t@Path(\"\/count\")\r\n\t@Produces( {MediaType.APPLICATION_XML})\r\n\tpublic Response count(@Context UriInfo ui) throws URISyntaxException\r\n\t{\r\n\t\tString retval = \"\" + databasecount + \"\";\r\n\t\tString path = ui.getAbsolutePath().toString() ;\r\n\t\tURI uri = new URI(path);\r\n\r\n\t\treturn Response.created(uri).contentLocation(uri).status(Response.Status.OK).entity(retval).build();\r\n\t}\r\n\r\n\r\n\t\/\/ add a new price record\r\n\t\/\/ \r\n\t\/\/ http:\/\/localhost:8181\/ThirdRestful\/price\/addOne \r\n\t@POST\r\n\t@Path(\"\/addOne\")\r\n\t@Produces( {MediaType.APPLICATION_XML})\r\n\tpublic Response addOne(\t@Context UriInfo ui, MarketPrice item) throws URISyntaxException\r\n\t{\r\n\t\tString path = ui.getAbsolutePath().toString() ;\r\n\t\tURI uri = new URI(path);\r\n\t\treturn Response.created(uri).contentLocation(uri).status(Response.Status.OK).build(); \r\n\r\n\t}\r\n\r\n\t\/\/ returns a selection of records in xml format.\r\n\t\/\/ \r\n\t\/\/ http:\/\/localhost:8080\/ThirdRestful\/price\/retrieve\r\n\t@GET\r\n\t@Path(\"\/retrieve\")\r\n\t@Produces( {MediaType.APPLICATION_XML})\r\n\tpublic Response retrieve(\t@Context UriInfo ui,\r\n\t\t\t@DefaultValue(\"0\") @QueryParam(\"start\") int start, \r\n\t\t\t@DefaultValue(\"10\") @QueryParam(\"count\") int count) throws URISyntaxException\r\n\t{\r\n\t\tString retval = \"\";\r\n\t\tString path = ui.getAbsolutePath().toString();\r\n\t\tURI uri = new URI(path);\r\n\r\n\t\tif (databasecount == 0)\r\n\t\t\treturn Response.created(uri).contentLocation(uri).status(Response.Status.REQUESTED_RANGE_NOT_SATISFIABLE).build();\r\n\t\telse\r\n\t\t{\r\n\t\t\tint end = start + count - 1;\r\n\t\t\tif (end &gt; databasecount-1)\r\n\t\t\t\treturn Response.created(uri).contentLocation(uri).status(Response.Status.REQUESTED_RANGE_NOT_SATISFIABLE).build();\r\n\t\t\tretval = rangeAsXML(start,end);\r\n\t\t}\r\n\t\treturn Response.created(uri).contentLocation(uri).status(Response.Status.OK).entity(retval).build(); \r\n\t}\r\n\r\n\t\/\/ returns a selection of records in xml format.\r\n\t\/\/ \r\n\t\/\/ this will return 10 items starting with the first\r\n\t\/\/ http:\/\/localhost:8080\/ThirdRestful\/price\/fetch\r\n\t\/\/\r\n\t\/\/ start with index one for three items\r\n\t\/\/ http:\/\/localhost:8080\/ThirdRestful\/price\/fetch?start=1&amp;count=3\r\n\r\n\t@GET\r\n\t@Path(\"\/fetch\")\r\n\t@Produces( {MediaType.APPLICATION_JSON})\r\n\tpublic Response fetch(\t@Context UriInfo ui,\r\n\t\t\t@DefaultValue(\"0\") @QueryParam(\"start\") int start, \r\n\t\t\t@DefaultValue(\"10\") @QueryParam(\"count\") int count) throws URISyntaxException\r\n\t{\r\n\t\tString retval = \"\";\r\n\t\tString path = ui.getAbsolutePath().toString();\r\n\t\tURI uri = new URI(path);\r\n\r\n\t\tif (databasecount == 0)\r\n\t\t\treturn Response.created(uri).contentLocation(uri).status(Response.Status.REQUESTED_RANGE_NOT_SATISFIABLE).build();\r\n\t\telse\r\n\t\t{\r\n\t\t\tint end = start + count - 1;\r\n\t\t\tif (end &gt; databasecount-1)\r\n\t\t\t\treturn Response.created(uri).contentLocation(uri).status(Response.Status.REQUESTED_RANGE_NOT_SATISFIABLE).build();\r\n\t\t\tretval = rangeAsJSON(start,end);\r\n\t\t}\r\n\t\treturn Response.created(uri).contentLocation(uri).status(Response.Status.OK).entity(retval).build(); \r\n\t}\r\n\r\n\r\n\t\/\/ returns all records in xml format.\r\n\t\/\/ \r\n\t\/\/ http:\/\/localhost:8080\/ThirdRestful\/price\/retrieveall \r\n\t@GET\r\n\t@Path(\"\/retrieveall\")\r\n\t@Produces( {MediaType.APPLICATION_XML})\r\n\tpublic Response showall(@Context UriInfo ui) throws URISyntaxException\r\n\t{\r\n\t\tString retval = \"\";\r\n\t\tString path = ui.getAbsolutePath().toString() ;\r\n\t\tURI uri = new URI(path);\r\n\r\n\t\tretval = rangeAsXML(0,databasecount-1);\r\n\t\treturn Response.created(uri).contentLocation(uri).status(Response.Status.OK).entity(retval).build();\r\n\t}\r\n\r\n\r\n\r\n\t\/\/ returns single record in xml format.\r\n\t\/\/ \r\n\t\/\/ http:\/\/localhost:8080\/ThirdRestful\/price\/34.xml\r\n\t@GET\r\n\t@Path(\"{idx}.xml\")\r\n\t@Produces( {MediaType.APPLICATION_XML})\r\n\tpublic Response getIndexXml(@Context UriInfo ui, @PathParam(\"idx\") int idx)  throws URISyntaxException\r\n\t{\r\n\t\tMarketPrice retval = null;\r\n\t\tString path = ui.getAbsolutePath().toString() ;\r\n\t\tURI uri = new URI(path);\r\n\r\n\t\tif (idx &gt;= 0 &amp;&amp; idx &lt; databasecount) \r\n                { \r\n                        retval = pricedatabase.get(idx); \r\n                        return Response.created(uri).contentLocation(uri).status(Response.Status.OK).entity(retval).build(); \r\n                } \r\n                else \r\n                        return Response.created(uri).contentLocation(uri).status(Response.Status.REQUESTED_RANGE_NOT_SATISFIABLE).build(); \r\n        } \r\n\r\n        \/\/ returns single record in json format. \r\n        \/\/ \r\n        \/\/ http:\/\/localhost:8080\/ThirdRestful\/price\/34.json \r\n        @GET @Path(\"{idx}.json\") \r\n        @Produces( {MediaType.APPLICATION_JSON}) \r\n        public Response getIndexJSON(@Context UriInfo ui, @PathParam(\"idx\") int idx) throws URISyntaxException \r\n        { \r\n                MarketPrice item = null; \r\n                String retval = \"\"; \r\n                String path = ui.getAbsolutePath().toString() ; \r\n                URI uri = new URI(path); \r\n                if (idx &gt;= 0 &amp;&amp; idx &lt; databasecount) \r\n                { \r\n                        item = pricedatabase.get(idx); \r\n                        retval = item.JSONString(); \r\n                        return Response.created(uri).contentLocation(uri).status(Response.Status.OK).entity(retval).build(); \r\n                } \r\n                else \r\n                        return Response.created(uri).contentLocation(uri).status(Response.Status.REQUESTED_RANGE_NOT_SATISFIABLE).build(); \r\n         } \r\n\r\n         \/\/ returns single record in json format. \r\n         \/\/ \r\n         \/\/ http:\/\/localhost:8080\/ThirdRestful\/price\/34.text \r\n         @GET @Path(\"{idx}.text\") \r\n         @Produces( {MediaType.TEXT_PLAIN}) \r\n         public Response getIndexTEXT(@Context UriInfo ui, @PathParam(\"idx\") int idx) throws URISyntaxException \r\n         {\r\n                MarketPrice item = null; \r\n                String retval = \"\"; \r\n                String path = ui.getAbsolutePath().toString() ; \r\n                URI uri = new URI(path); \r\n                if (idx &gt;= 0 &amp;&amp; idx &lt; databasecount)\r\n\t\t{\r\n\t\t\titem = pricedatabase.get(idx);\r\n\t\t\tretval = item.toString();\r\n\t\t\treturn Response.created(uri).contentLocation(uri).status(Response.Status.OK).entity(retval).build();\r\n\t\t}\r\n\t\telse\r\n\t\t\treturn Response.created(uri).contentLocation(uri).status(Response.Status.REQUESTED_RANGE_NOT_SATISFIABLE).build();\r\n\t}\r\n\r\n\r\n}\r\n<\/pre>\n<h2>MarketPrice.java<\/h2>\n<pre>package com.acmesoft;\r\n\r\nimport java.io.StringWriter;\r\nimport java.math.BigDecimal;\r\nimport java.text.DateFormat;\r\nimport java.text.SimpleDateFormat;\r\nimport java.util.Date;\r\n\r\nimport javax.xml.bind.JAXBContext;\r\nimport javax.xml.bind.JAXBException;\r\nimport javax.xml.bind.Marshaller;\r\nimport javax.xml.bind.PropertyException;\r\nimport javax.xml.bind.annotation.XmlAccessorType;\r\nimport javax.xml.bind.annotation.XmlElement;\r\nimport javax.xml.bind.annotation.XmlRootElement;\r\n\r\nimport com.google.gson.Gson;\r\n\r\nimport javax.xml.bind.annotation.XmlAccessType;;\r\n\r\n@XmlRootElement(name=\"marketPrice\")\r\n@XmlAccessorType(XmlAccessType.FIELD)\r\npublic class MarketPrice \r\n{\r\n\t@XmlElement\r\n\tprivate int id;\r\n\t@XmlElement\r\n\tprivate String symbol;\t\t\/\/ EUR\/USD\r\n\t@XmlElement\r\n\tprivate String bank;\t\t\/\/ DBK\r\n\t@XmlElement\r\n\tprivate BigDecimal price;\t\/\/ 1.1222\r\n\t@XmlElement\r\n\tprivate String exchange;\t\/\/ DTB, NYSE, CBOT\r\n\t@XmlElement\r\n\tprivate Date quoteDateTime;\t\/\/ 2015-01-01 14:32:45.032\r\n\r\n\r\n\tpublic MarketPrice()\r\n\t{\r\n\t\tid = -1;\r\n\t\tthis.symbol= \"\";\r\n\t\tthis.bank = \"\";\r\n\t\tthis.price = new BigDecimal(0.0);\r\n\t\tthis.exchange = \"\";\r\n\t\tthis.quoteDateTime = new Date();\r\n\t}\r\n\r\n\r\n\tpublic MarketPrice(String symbol, String bank, BigDecimal price, String exchange)\r\n\t{\r\n\t\tDateFormat dateFormat = new SimpleDateFormat(\"yyyy\/MM\/dd HH:mm:ss\");\r\n\r\n\t\tthis.symbol= symbol;\r\n\t\tthis.bank = bank;\r\n\t\tthis.price = price;\r\n\t\tthis.exchange = exchange;\r\n\t\tthis.quoteDateTime = new Date();\r\n\t\tString debugDate = dateFormat.format(quoteDateTime);\r\n\r\n\t\tid = -1;\r\n\t}\r\n\r\n\tpublic MarketPrice(String symbol, String bank, BigDecimal price, String exchange, Date quoteDateTime)\r\n\t{\r\n\t\tthis.symbol= symbol;\r\n\t\tthis.bank = bank;\r\n\t\tthis.price = price;\r\n\t\tthis.exchange = exchange;\r\n\t\tthis.quoteDateTime = quoteDateTime;\r\n\t\tid = -1;\r\n\t}\r\n\r\n\tpublic void setId(int value)\r\n\t{\r\n\t\tid = value;\r\n\t}\r\n\tpublic int getId()\r\n\t{\r\n\t\treturn id;\r\n\t}\r\n\r\n\tpublic void setSymbol(String value)\r\n\t{\r\n\t\tsymbol = value;\r\n\t}\r\n\tpublic String getSymbol()\r\n\t{\r\n\t\treturn symbol;\r\n\t}\r\n\r\n\tpublic void setBank(String value)\r\n\t{\r\n\t\tbank = value;\r\n\t}\r\n\tpublic String getBank()\r\n\t{\r\n\t\treturn bank;\r\n\t}\r\n\r\n\tpublic void setPrice(BigDecimal value)\r\n\t{\r\n\t\tprice = value;\r\n\t}\r\n\tpublic void setPrice(double value)\r\n\t{\r\n\t\tprice = new BigDecimal(value);\r\n\t}\r\n\tpublic BigDecimal getPrice()\r\n\t{\r\n\t\treturn price;\r\n\t}\r\n\r\n\tpublic void setExchange(String value)\r\n\t{\r\n\t\texchange = value;\r\n\t}\r\n\tpublic String getExchange()\r\n\t{\r\n\t\treturn exchange;\r\n\t}\r\n\r\n\tpublic Date getQuoteDateTime()\r\n\t{\r\n\t\treturn quoteDateTime;\r\n\t}\r\n\r\n\tpublic void setQuoteDateTime(Date value)\r\n\t{\r\n\t\tquoteDateTime = value;\r\n\t}\r\n\r\n\r\n\tpublic String toString()\r\n\t{\r\n\t\tString retval = getCSVData();\r\n\r\n\t\treturn retval;\r\n\t}\r\n\r\n\tpublic String xmlString()\r\n\t{ \r\n\t\tString retval = toXmlString();\r\n\t\tretval = retval.substring(retval.indexOf(\"\\n\"));\r\n\r\n\t\treturn retval;\r\n\t}\r\n\r\n\tpublic String JSONString()\r\n\t{ \r\n\t\tGson gson = new Gson();\r\n\t\tString JSONstr = gson.toJson(this);\r\n\t\treturn JSONstr;  \r\n\t}\r\n\r\n\tpublic String toXmlString()\r\n\t{\r\n\t\tJAXBContext ctx = null;\r\n\t\tMarshaller maxMarshaller = null;\r\n\r\n\t\ttry {\r\n\t\t\tctx = JAXBContext.newInstance(MarketPrice.class);\r\n\t\t} catch (JAXBException e) {\r\n\t\t\t\/\/ TODO Auto-generated catch block\r\n\t\t\te.printStackTrace();\r\n\t\t}\r\n\r\n\t\ttry {\r\n\t\t\tmaxMarshaller = ctx.createMarshaller();\r\n\t\t} catch (JAXBException e1) {\r\n\t\t\t\/\/ TODO Auto-generated catch block\r\n\t\t\te1.printStackTrace();\r\n\t\t}\r\n\r\n\t\ttry {\r\n\t\t\tmaxMarshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);\r\n\t\t} catch (PropertyException e1) {\r\n\t\t\t\/\/ TODO Auto-generated catch block\r\n\t\t\te1.printStackTrace();\r\n\t\t}\r\n\r\n\t\tStringWriter writer = new StringWriter();\r\n\t\ttry {\r\n\t\t\tmaxMarshaller.marshal(this,writer);\r\n\t\t} catch (JAXBException e) {\r\n\t\t\t\/\/ TODO Auto-generated catch block\r\n\t\t\te.printStackTrace();\r\n\t\t}\r\n\r\n\t\tString xmlPrice = writer.toString();\r\n\r\n\t\treturn xmlPrice;\r\n\t}\r\n\r\n\tprivate String convertToTime(long milliseconds)\r\n\t{\r\n\t\tDate date = new Date(milliseconds);\r\n\t\tDateFormat dateformat = new SimpleDateFormat(\"HH:mm:ss.SSS\");\r\n\t\treturn dateformat.format(date);\r\n\t}\r\n\tpublic String getCSVHeader()\r\n\t{\r\n\t\tString delim = com.acmesoft.Constants.FIELDDELIM;\r\n\t\tString retval;\r\n\r\n\t\tretval = \"Id\" + delim + \"Symbol\" + delim + \"Price\" + delim + \"Bank\" + delim + \"Exchange\" + delim + \"QuoteDate\" ;\r\n\r\n\t\treturn retval;\r\n\t}\r\n\tpublic String getCSVData()\r\n\t{\r\n\t\tString delim = com.acmesoft.Constants.FIELDDELIM;\r\n\t\tString retval;\r\n\r\n\t\tretval = id + delim + symbol + delim + price + delim + bank + delim + exchange + delim + quoteDateTime ;\r\n\r\n\t\treturn retval;\r\n\t}\r\n}\r\n<\/pre>\n<h2>PriceCount.java<\/h2>\n<pre>package com.acmesoft;\r\n\r\nimport javax.xml.bind.annotation.XmlAccessType;\r\nimport javax.xml.bind.annotation.XmlAccessorType;\r\nimport javax.xml.bind.annotation.XmlElement;\r\nimport javax.xml.bind.annotation.XmlRootElement;\r\n\r\n@XmlRootElement(name=\"marketPrice\")\r\n@XmlAccessorType(XmlAccessType.FIELD)\r\npublic class PriceCount\r\n{\r\n        @XmlElement\r\n        private int count;\r\n\r\n        public PriceCount()\r\n        {\r\n\r\n        }\r\n        public PriceCount(int val)\r\n        {\r\n                count = val;\r\n        }\r\n\r\n        public int getCount()\r\n        {\r\n                return count;\r\n        }\r\n\r\n        public void setCount(int val)\r\n        {\r\n                count = val;\r\n        }\r\n}\r\n<\/pre>\n<h2>Constants.java<\/h2>\n<pre>package com.acmesoft;\r\n\r\npublic class Constants {\r\n\tfinal public static String FIELDDELIM = \",\";\r\n\tfinal public static int OK = 200;\r\n\tfinal public static String DATETIMEFORMAT = \"yyyy-MM-ddHH:mm:ss.SSS\";\r\n}\r\n<\/pre>\n","protected":false},"excerpt":{"rendered":"<p>This is the blog final entry for a restful service web server. \u00a0I have attempted to create more than your typical &#8220;foo&#8221; &#8220;bar&#8221; type example program. My final blog on restful services will be a fairly complete service that could &hellip; <a href=\"https:\/\/blog.paranoidprofessor.com\/index.php\/2017\/04\/26\/restful-services-in-java-360-degree-of-restful-server\/\">Continue reading <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[20],"tags":[12,36,88],"_links":{"self":[{"href":"https:\/\/blog.paranoidprofessor.com\/index.php\/wp-json\/wp\/v2\/posts\/2201"}],"collection":[{"href":"https:\/\/blog.paranoidprofessor.com\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.paranoidprofessor.com\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.paranoidprofessor.com\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.paranoidprofessor.com\/index.php\/wp-json\/wp\/v2\/comments?post=2201"}],"version-history":[{"count":12,"href":"https:\/\/blog.paranoidprofessor.com\/index.php\/wp-json\/wp\/v2\/posts\/2201\/revisions"}],"predecessor-version":[{"id":3442,"href":"https:\/\/blog.paranoidprofessor.com\/index.php\/wp-json\/wp\/v2\/posts\/2201\/revisions\/3442"}],"wp:attachment":[{"href":"https:\/\/blog.paranoidprofessor.com\/index.php\/wp-json\/wp\/v2\/media?parent=2201"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.paranoidprofessor.com\/index.php\/wp-json\/wp\/v2\/categories?post=2201"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.paranoidprofessor.com\/index.php\/wp-json\/wp\/v2\/tags?post=2201"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}