{"id":467,"date":"2015-06-15T05:00:23","date_gmt":"2015-06-15T03:00:23","guid":{"rendered":"http:\/\/setblau.com\/blog\/?p=467"},"modified":"2015-06-11T13:29:54","modified_gmt":"2015-06-11T11:29:54","slug":"servicio-rest-con-jetty-embebido-en-un-jar","status":"publish","type":"post","link":"https:\/\/setblau.com\/blog\/servicio-rest-con-jetty-embebido-en-un-jar\/","title":{"rendered":"Servicio REST con Jetty embebido en un jar"},"content":{"rendered":"<p>En algunas ocasiones, cuando la relaci\u00f3n con el departamento de sistemas no es tan buena como se desear\u00eda, es preferible minimizar las tareas a realizar por personas que no seamos nosotros&#8230; Para esos casos y aquellos en los que deseemos una aplicaci\u00f3n portable, accesible f\u00e1cilmente desde un framework javascript, potente y vers\u00e1til, podemos usar servicios REST con el contenedor de aplicaciones JETTY embebido en un \u00fanico JAR.<\/p>\n<p>El primer paso es crear un proyecto Maven, usamos Maven para no tener problemas de dependencias y generar el jar de una forma r\u00e1pida y comoda. Podemos usar el arquetipo quickstart, que es el m\u00e1s simple de todos, una vez hemos creado el proyecto, desde la consola o desde nuestro ide preferido, vamos a editar el POM para obtener todas las librer\u00edas precisas, si alguna de las que ponemos en este ejemplo no la puede encontrar vuestro maven, usad maven central para buscar una versi\u00f3n m\u00e1s actual o a\u00f1adid el jar a vuestro repositorio local.<\/p>\n<p>Podemos dejar nuestro POM similar al siguiente:<\/p>\n<blockquote>\n<pre>&lt;project xmlns=\"http:\/\/maven.apache.org\/POM\/4.0.0\" xmlns:xsi=\"http:\/\/www.w3.org\/2001\/XMLSchema-instance\"\r\n xsi:schemaLocation=\"http:\/\/maven.apache.org\/POM\/4.0.0 http:\/\/maven.apache.org\/xsd\/maven-4.0.0.xsd\"&gt;\r\n &lt;modelVersion&gt;4.0.0&lt;\/modelVersion&gt;<\/pre>\n<pre>&lt;groupId&gt;com.setblau.jetty.ws&lt;\/groupId&gt;\r\n &lt;artifactId&gt;rest&lt;\/artifactId&gt;\r\n &lt;version&gt;0.0.1&lt;\/version&gt;\r\n &lt;packaging&gt;jar&lt;\/packaging&gt;<\/pre>\n<pre>&lt;name&gt;restapi&lt;\/name&gt;\r\n &lt;url&gt;http:\/\/maven.apache.org&lt;\/url&gt;<\/pre>\n<pre>&lt;properties&gt;\r\n &lt;project.build.sourceEncoding&gt;UTF-8&lt;\/project.build.sourceEncoding&gt;\r\n &lt;\/properties&gt;<\/pre>\n<pre>&lt;dependencies&gt;\r\n &lt;dependency&gt;\r\n &lt;groupId&gt;org.eclipse.jetty&lt;\/groupId&gt;\r\n &lt;artifactId&gt;jetty-server&lt;\/artifactId&gt;\r\n &lt;version&gt;9.2.3.v20140905&lt;\/version&gt;\r\n &lt;\/dependency&gt;\r\n &lt;dependency&gt;\r\n &lt;groupId&gt;org.eclipse.jetty&lt;\/groupId&gt;\r\n &lt;artifactId&gt;jetty-servlet&lt;\/artifactId&gt;\r\n &lt;version&gt;9.2.3.v20140905&lt;\/version&gt;\r\n &lt;\/dependency&gt;\r\n &lt;dependency&gt;\r\n &lt;groupId&gt;org.glassfish.jersey.core&lt;\/groupId&gt;\r\n &lt;artifactId&gt;jersey-server&lt;\/artifactId&gt;\r\n &lt;version&gt;2.7&lt;\/version&gt;\r\n &lt;\/dependency&gt;\r\n &lt;dependency&gt;\r\n &lt;groupId&gt;org.glassfish.jersey.containers&lt;\/groupId&gt;\r\n &lt;artifactId&gt;jersey-container-servlet-core&lt;\/artifactId&gt;\r\n &lt;version&gt;2.7&lt;\/version&gt;\r\n &lt;\/dependency&gt;\r\n &lt;dependency&gt;\r\n &lt;groupId&gt;org.glassfish.jersey.containers&lt;\/groupId&gt;\r\n &lt;artifactId&gt;jersey-container-jetty-http&lt;\/artifactId&gt;\r\n &lt;version&gt;2.7&lt;\/version&gt;\r\n &lt;\/dependency&gt;\r\n &lt;dependency&gt;\r\n &lt;groupId&gt;org.glassfish.jersey.media&lt;\/groupId&gt;\r\n &lt;artifactId&gt;jersey-media-moxy&lt;\/artifactId&gt;\r\n &lt;version&gt;2.7&lt;\/version&gt;\r\n &lt;\/dependency&gt;\r\n &lt;dependency&gt;\r\n &lt;groupId&gt;com.vertica&lt;\/groupId&gt;\r\n &lt;artifactId&gt;vertica-jdbc&lt;\/artifactId&gt;\r\n &lt;version&gt;7.0.2-1&lt;\/version&gt;\r\n &lt;\/dependency&gt;\r\n &lt;dependency&gt;\r\n &lt;groupId&gt;log4j&lt;\/groupId&gt;\r\n &lt;artifactId&gt;log4j&lt;\/artifactId&gt;\r\n &lt;version&gt;1.2.17&lt;\/version&gt;\r\n &lt;\/dependency&gt;\r\n &lt;dependency&gt;\r\n &lt;groupId&gt;com.google.code.gson&lt;\/groupId&gt;\r\n &lt;artifactId&gt;gson&lt;\/artifactId&gt;\r\n &lt;version&gt;2.3.1&lt;\/version&gt;\r\n &lt;scope&gt;compile&lt;\/scope&gt;\r\n &lt;\/dependency&gt;<\/pre>\n<pre>&lt;\/dependencies&gt;\r\n &lt;build&gt;\r\n &lt;plugins&gt;\r\n &lt;plugin&gt;\r\n &lt;groupId&gt;org.apache.maven.plugins&lt;\/groupId&gt;\r\n &lt;artifactId&gt;maven-shade-plugin&lt;\/artifactId&gt;\r\n &lt;version&gt;1.6&lt;\/version&gt;\r\n &lt;configuration&gt;\r\n &lt;createDependencyReducedPom&gt;true&lt;\/createDependencyReducedPom&gt;\r\n &lt;filters&gt;\r\n &lt;filter&gt;\r\n &lt;artifact&gt;*:*&lt;\/artifact&gt;\r\n &lt;excludes&gt;\r\n &lt;exclude&gt;META-INF\/*.SF&lt;\/exclude&gt;\r\n &lt;exclude&gt;META-INF\/*.DSA&lt;\/exclude&gt;\r\n &lt;exclude&gt;META-INF\/*.RSA&lt;\/exclude&gt;\r\n &lt;\/excludes&gt;\r\n &lt;\/filter&gt;\r\n &lt;\/filters&gt;\r\n &lt;\/configuration&gt;<\/pre>\n<pre>&lt;executions&gt;\r\n &lt;execution&gt;\r\n &lt;phase&gt;package&lt;\/phase&gt;\r\n &lt;goals&gt;\r\n &lt;goal&gt;shade&lt;\/goal&gt;\r\n &lt;\/goals&gt;\r\n &lt;configuration&gt;\r\n &lt;transformers&gt;\r\n &lt;transformer\r\n implementation=\"org.apache.maven.plugins.shade.resource.ServicesResourceTransformer\" \/&gt;\r\n &lt;transformer\r\n implementation=\"org.apache.maven.plugins.shade.resource.ManifestResourceTransformer\"&gt;\r\n &lt;manifestEntries&gt;\r\n &lt;Main-Class&gt;abertis.ws.restapi.App&lt;\/Main-Class&gt;\r\n &lt;\/manifestEntries&gt;\r\n &lt;\/transformer&gt;\r\n &lt;\/transformers&gt;\r\n &lt;\/configuration&gt;\r\n &lt;\/execution&gt;\r\n &lt;\/executions&gt;\r\n &lt;\/plugin&gt;\r\n &lt;plugin&gt;\r\n &lt;groupId&gt;org.codehaus.mojo&lt;\/groupId&gt;\r\n &lt;artifactId&gt;exec-maven-plugin&lt;\/artifactId&gt;\r\n &lt;version&gt;1.2.1&lt;\/version&gt;\r\n &lt;configuration&gt;\r\n &lt;mainClass&gt;abertis.ws.restapi.App&lt;\/mainClass&gt;\r\n &lt;\/configuration&gt;\r\n &lt;\/plugin&gt;\r\n &lt;\/plugins&gt;\r\n &lt;\/build&gt;\r\n &lt;\/project&gt;<\/pre>\n<\/blockquote>\n<p>Una vez hecho esto pasamos a picar c\u00f3digo, creamos una nueva clase en la que haremos los siguiente imports:<\/p>\n<pre class=\"line number3 index2 alt2\"><code class=\"java keyword\">import<\/code> <code class=\"java plain\">javax.ws.rs.GET;<\/code><\/pre>\n<pre class=\"line number4 index3 alt1\"><code class=\"java keyword\">import<\/code> <code class=\"java plain\">javax.ws.rs.Path;<\/code><\/pre>\n<pre class=\"line number5 index4 alt2\"><code class=\"java keyword\">import<\/code> <code class=\"java plain\">javax.ws.rs.Produces;<\/code><\/pre>\n<pre class=\"line number6 index5 alt1\"><code class=\"java keyword\">import<\/code> <code class=\"java plain\">javax.ws.rs.core.MediaType;<\/code><\/pre>\n<div class=\"line number6 index5 alt1\"><\/div>\n<div class=\"line number6 index5 alt1\">Una vez hecha, a\u00f1adiremos las siguientes anotaciones:<\/div>\n<div class=\"line number6 index5 alt1\"><\/div>\n<pre class=\"line number6 index5 alt1\">package com.setblau.jetty.ws.service;\r\n\r\nimport javax.servlet.http.HttpServletRequest;\r\nimport javax.ws.rs.*;\r\nimport javax.ws.rs.core.*;\r\n\r\nimport org.apache.log4j.Logger;\r\n\r\nimport com.google.gson.Gson;\r\n\r\nimport abertis.ws.dao.Database;\r\nimport abertis.ws.dao.GetJobStatistics;\r\n\r\n\/**\r\n * Class as servlet for get all jersey requests\r\n * \r\n * @author lgonzalez\r\n *\r\n *\/\r\n@Path(\"\/api\")\r\npublic class EntryPoint {\r\n\r\n private static Logger logger = Logger.getLogger(EntryPoint.class);\r\n\r\n \/**\r\n * Test method\r\n * \r\n * @param name\r\n * @param request\r\n * @return\r\n *\/\r\n @GET\r\n @Path(\"test\")\r\n @Produces(MediaType.TEXT_PLAIN)\r\n public String test(@QueryParam(\"name\") String name,\r\n @Context HttpServletRequest request) {\r\n logger.info(\"Query -&gt; EntryPoint -&gt; \" + \"TEXT_PLAIN from : \"\r\n + request.getRemoteAddr());\r\n String respuesta = \"\";\r\n respuesta += \"Test call \" + name + \" your bdd connection: \"\r\n + Database.getConnection().toString() + \" your ip address is: \"\r\n + request.getRemoteAddr();\r\n return respuesta;\r\n }\r\n\r\n \/**\r\n * GetJobStatisticsByDate json reply\r\n * \r\n * @param customer\r\n * @param startTime\r\n * @param endTime\r\n * @param request\r\n * @return\r\n *\/\r\n @GET\r\n @Path(\"GetJobStatisticsByDate\")\r\n @Produces(MediaType.APPLICATION_JSON)\r\n public String GetJobStatisticsByDate(\r\n @QueryParam(\"customer\") String customer,\r\n @QueryParam(\"startTime\") String startTime,\r\n @QueryParam(\"endTime\") String endTime,\r\n @Context HttpServletRequest request) {\r\n logger.info(\"Query -&gt; EntryPoint -&gt; \"\r\n + \"GetJobStatisticsByDate -&gt; from: \" + request.getRemoteAddr()\r\n + \" witch parameters: \" + customer + \" \/ \" + startTime + \" \/ \"\r\n + endTime);\r\n String respuesta = \"\";\r\n\r\n \/\/ JobStatistics obj = new JobStatistics();\r\n Gson gson = new Gson();\r\n respuesta = gson.toJson(new GetJobStatistics().getDataFromDatabase(\r\n customer, startTime, endTime));\r\n\r\n return respuesta;\r\n }\r\n}<\/pre>\n<div class=\"line number6 index5 alt1\">Con esto ya tendremos un servlet que recoger\u00e1 las llamadas de nuestros clientes. Ahora pasamos a crear la clase que va a arrancar el contenedor de aplicaciones, que puede ser similar a la siguiente:<\/div>\n<div class=\"line number6 index5 alt1\"><\/div>\n<pre class=\"line number6 index5 alt1\">package com.setblau.jetty.ws.service;\r\n\r\nimport org.eclipse.jetty.server.Server;\r\nimport org.eclipse.jetty.servlet.ServletContextHandler;\r\nimport org.eclipse.jetty.servlet.ServletHolder;\r\nimport org.apache.log4j.Logger;\r\nimport org.apache.log4j.xml.DOMConfigurator;\r\n\r\n\/**\r\n * Launcher class\r\n * \r\n * @author lgonzalez\r\n *\r\n *\/\r\npublic class App {\r\n private static Logger logger = Logger.getLogger(App.class);\r\n\r\n \/**\r\n * Main method\r\n * \r\n * @param args\r\n *\/\r\n public static void main(String[] args) {\r\n DOMConfigurator.configure(\"log4j.xml\");\r\n logger.info(\"New execution : \");\r\n ServletContextHandler context = new ServletContextHandler(\r\n ServletContextHandler.SESSIONS);\r\n context.setContextPath(\"\/\");\r\n\r\n Server jettyServer = new Server(8080);\r\n jettyServer.setHandler(context);\r\n\r\n ServletHolder jerseyServlet = context.addServlet(\r\n org.glassfish.jersey.servlet.ServletContainer.class, \"\/*\");\r\n jerseyServlet.setInitOrder(0);\r\n\r\n \/\/ Tells the Jersey Servlet which REST service\/class to load.\r\n jerseyServlet.setInitParameter(\r\n \"jersey.config.server.provider.classnames\",\r\n EntryPoint.class.getCanonicalName());\r\n\r\n try {\r\n jettyServer.start();\r\n jettyServer.join();\r\n } catch (Exception e) {\r\n logger.error(e.getMessage());\r\n } finally {\r\n jettyServer.destroy();\r\n }\r\n }\r\n}<\/pre>\n<div class=\"line number6 index5 alt1\">Llamamos a maven con un simple clean install, ejecutamos el paquete jar generado con la m\u00e1quina virtual java que nos apetezca y listo !Tenemos un webservice rest con su contenedor de aplicaciones incorporado que podemos transportar y puede servir cualquier tipo de informaci\u00f3n.<\/div>\n<div class=\"line number6 index5 alt1\"><\/div>\n","protected":false},"excerpt":{"rendered":"<p>En algunas ocasiones, cuando la relaci\u00f3n con el departamento de sistemas no es tan buena como se desear\u00eda, es preferible minimizar las tareas a realizar por personas que no seamos nosotros&#8230; Para esos casos y aquellos en los que deseemos una aplicaci\u00f3n portable, accesible f\u00e1cilmente desde un framework javascript, potente y vers\u00e1til, podemos usar servicios REST con el contenedor de aplicaciones JETTY embebido en un \u00fanico JAR. El primer paso es crear un proyecto Maven, usamos Maven para no tener problemas de dependencias y generar el jar de una forma r\u00e1pida y comoda. Podemos usar el arquetipo quickstart, que es el m\u00e1s simple de todos, una vez hemos creado el proyecto, desde la consola o desde nuestro ide preferido, vamos a editar el POM para obtener todas las librer\u00edas precisas, si alguna de las que ponemos en este ejemplo no la puede encontrar vuestro maven, usad maven central para buscar una versi\u00f3n m\u00e1s actual o a\u00f1adid el jar a vuestro repositorio local. Podemos dejar nuestro POM similar al siguiente: &lt;project xmlns=\u00bbhttp:\/\/maven.apache.org\/POM\/4.0.0&#8243; xmlns:xsi=\u00bbhttp:\/\/www.w3.org\/2001\/XMLSchema-instance\u00bb xsi:schemaLocation=\u00bbhttp:\/\/maven.apache.org\/POM\/4.0.0 http:\/\/maven.apache.org\/xsd\/maven-4.0.0.xsd\u00bb&gt; &lt;modelVersion&gt;4.0.0&lt;\/modelVersion&gt; &lt;groupId&gt;com.setblau.jetty.ws&lt;\/groupId&gt; &lt;artifactId&gt;rest&lt;\/artifactId&gt; &lt;version&gt;0.0.1&lt;\/version&gt; &lt;packaging&gt;jar&lt;\/packaging&gt; &lt;name&gt;restapi&lt;\/name&gt; &lt;url&gt;http:\/\/maven.apache.org&lt;\/url&gt; &lt;properties&gt; &lt;project.build.sourceEncoding&gt;UTF-8&lt;\/project.build.sourceEncoding&gt; &lt;\/properties&gt; &lt;dependencies&gt; &lt;dependency&gt; &lt;groupId&gt;org.eclipse.jetty&lt;\/groupId&gt; &lt;artifactId&gt;jetty-server&lt;\/artifactId&gt; &lt;version&gt;9.2.3.v20140905&lt;\/version&gt; &lt;\/dependency&gt; &lt;dependency&gt; &lt;groupId&gt;org.eclipse.jetty&lt;\/groupId&gt; &lt;artifactId&gt;jetty-servlet&lt;\/artifactId&gt; &lt;version&gt;9.2.3.v20140905&lt;\/version&gt; &lt;\/dependency&gt; &lt;dependency&gt; &lt;groupId&gt;org.glassfish.jersey.core&lt;\/groupId&gt; &lt;artifactId&gt;jersey-server&lt;\/artifactId&gt; &lt;version&gt;2.7&lt;\/version&gt; &lt;\/dependency&gt; &lt;dependency&gt; &lt;groupId&gt;org.glassfish.jersey.containers&lt;\/groupId&gt; &lt;artifactId&gt;jersey-container-servlet-core&lt;\/artifactId&gt; &lt;version&gt;2.7&lt;\/version&gt; &lt;\/dependency&gt; &lt;dependency&gt; &lt;groupId&gt;org.glassfish.jersey.containers&lt;\/groupId&gt; &lt;artifactId&gt;jersey-container-jetty-http&lt;\/artifactId&gt; &lt;version&gt;2.7&lt;\/version&gt; &lt;\/dependency&gt; &lt;dependency&gt; &lt;groupId&gt;org.glassfish.jersey.media&lt;\/groupId&gt; &lt;artifactId&gt;jersey-media-moxy&lt;\/artifactId&gt; &lt;version&gt;2.7&lt;\/version&gt; &lt;\/dependency&gt; &lt;dependency&gt; &lt;groupId&gt;com.vertica&lt;\/groupId&gt; &lt;artifactId&gt;vertica-jdbc&lt;\/artifactId&gt; &lt;version&gt;7.0.2-1&lt;\/version&gt; &lt;\/dependency&gt; &lt;dependency&gt; &lt;groupId&gt;log4j&lt;\/groupId&gt; &lt;artifactId&gt;log4j&lt;\/artifactId&gt; &lt;version&gt;1.2.17&lt;\/version&gt; &lt;\/dependency&gt; &lt;dependency&gt; &lt;groupId&gt;com.google.code.gson&lt;\/groupId&gt; &lt;artifactId&gt;gson&lt;\/artifactId&gt; &lt;version&gt;2.3.1&lt;\/version&gt; &lt;scope&gt;compile&lt;\/scope&gt; &lt;\/dependency&gt; &lt;\/dependencies&gt; &lt;build&gt; &lt;plugins&gt; &lt;plugin&gt; &lt;groupId&gt;org.apache.maven.plugins&lt;\/groupId&gt; &lt;artifactId&gt;maven-shade-plugin&lt;\/artifactId&gt; &lt;version&gt;1.6&lt;\/version&gt; &lt;configuration&gt; &lt;createDependencyReducedPom&gt;true&lt;\/createDependencyReducedPom&gt; &lt;filters&gt; &lt;filter&gt; &lt;artifact&gt;*:*&lt;\/artifact&gt; &lt;excludes&gt; &lt;exclude&gt;META-INF\/*.SF&lt;\/exclude&gt; &lt;exclude&gt;META-INF\/*.DSA&lt;\/exclude&gt; &lt;exclude&gt;META-INF\/*.RSA&lt;\/exclude&gt; &lt;\/excludes&gt; &lt;\/filter&gt; &lt;\/filters&gt; &lt;\/configuration&gt; &lt;executions&gt; &lt;execution&gt; &lt;phase&gt;package&lt;\/phase&gt; &lt;goals&gt; &lt;goal&gt;shade&lt;\/goal&gt; &lt;\/goals&gt; &lt;configuration&gt; &lt;transformers&gt; &lt;transformer implementation=\u00bborg.apache.maven.plugins.shade.resource.ServicesResourceTransformer\u00bb \/&gt; &lt;transformer implementation=\u00bborg.apache.maven.plugins.shade.resource.ManifestResourceTransformer\u00bb&gt; &lt;manifestEntries&gt; &lt;Main-Class&gt;abertis.ws.restapi.App&lt;\/Main-Class&gt; &lt;\/manifestEntries&gt; &lt;\/transformer&gt; &lt;\/transformers&gt; &lt;\/configuration&gt; &lt;\/execution&gt; &lt;\/executions&gt; &lt;\/plugin&gt; &lt;plugin&gt; &lt;groupId&gt;org.codehaus.mojo&lt;\/groupId&gt; &lt;artifactId&gt;exec-maven-plugin&lt;\/artifactId&gt; &lt;version&gt;1.2.1&lt;\/version&gt; &lt;configuration&gt; &lt;mainClass&gt;abertis.ws.restapi.App&lt;\/mainClass&gt; &lt;\/configuration&gt; &lt;\/plugin&gt; &lt;\/plugins&gt; &lt;\/build&gt; &lt;\/project&gt; Una vez hecho esto pasamos a picar c\u00f3digo, creamos una nueva clase en la que haremos los siguiente imports: import javax.ws.rs.GET; import javax.ws.rs.Path; import javax.ws.rs.Produces; import javax.ws.rs.core.MediaType; Una vez hecha, a\u00f1adiremos las siguientes anotaciones: package com.setblau.jetty.ws.service; import javax.servlet.http.HttpServletRequest; import javax.ws.rs.*; import javax.ws.rs.core.*; import org.apache.log4j.Logger; import com.google.gson.Gson; import abertis.ws.dao.Database; import abertis.ws.dao.GetJobStatistics; \/** * Class as servlet for get all jersey requests * * @author lgonzalez * *\/ @Path(\u00ab\/api\u00bb) public class EntryPoint { private static Logger logger = Logger.getLogger(EntryPoint.class); \/** * Test method * * @param name * @param request * @return *\/ @GET @Path(\u00abtest\u00bb) @Produces(MediaType.TEXT_PLAIN) public String test(@QueryParam(\u00abname\u00bb) String name, @Context HttpServletRequest request) { logger.info(\u00abQuery -&gt; EntryPoint -&gt; \u00bb + \u00abTEXT_PLAIN from : \u00bb + request.getRemoteAddr()); String respuesta = \u00ab\u00bb; respuesta += \u00abTest call \u00bb + name + \u00bb your bdd connection: \u00bb + Database.getConnection().toString() + \u00bb your ip address is: \u00bb + request.getRemoteAddr(); return respuesta; } \/** * GetJobStatisticsByDate json reply * * @param customer * @param startTime * @param endTime * @param request * @return *\/ @GET @Path(\u00abGetJobStatisticsByDate\u00bb) @Produces(MediaType.APPLICATION_JSON) public String GetJobStatisticsByDate( @QueryParam(\u00abcustomer\u00bb) String customer, @QueryParam(\u00abstartTime\u00bb) String startTime, @QueryParam(\u00abendTime\u00bb) String endTime, @Context HttpServletRequest request) { logger.info(\u00abQuery -&gt; EntryPoint -&gt; \u00bb + \u00abGetJobStatisticsByDate -&gt; from: \u00bb + request.getRemoteAddr() + \u00bb witch parameters: \u00bb + customer + \u00bb \/ \u00bb + startTime + \u00bb \/ \u00bb + endTime); String respuesta = \u00ab\u00bb; \/\/ JobStatistics obj = new JobStatistics(); Gson gson = new Gson(); respuesta = gson.toJson(new GetJobStatistics().getDataFromDatabase( customer, startTime, endTime)); return respuesta; } } Con esto ya tendremos un servlet que recoger\u00e1 las llamadas de nuestros clientes. Ahora pasamos a crear la clase que va a arrancar el contenedor de aplicaciones, que puede ser similar a la siguiente: package com.setblau.jetty.ws.service; import org.eclipse.jetty.server.Server; import org.eclipse.jetty.servlet.ServletContextHandler; import org.eclipse.jetty.servlet.ServletHolder; import org.apache.log4j.Logger; import org.apache.log4j.xml.DOMConfigurator; \/** * Launcher class * * @author lgonzalez * *\/ public class App { private static Logger logger = Logger.getLogger(App.class); \/** * Main method * * @param args *\/ public static void main(String[] args) { DOMConfigurator.configure(\u00ablog4j.xml\u00bb); logger.info(\u00abNew execution : \u00ab); ServletContextHandler context = new ServletContextHandler( ServletContextHandler.SESSIONS); context.setContextPath(\u00ab\/\u00bb); Server jettyServer = new Server(8080); jettyServer.setHandler(context); ServletHolder jerseyServlet = context.addServlet( org.glassfish.jersey.servlet.ServletContainer.class, \u00ab\/*\u00bb); jerseyServlet.setInitOrder(0); \/\/ Tells the Jersey Servlet which REST service\/class to load. jerseyServlet.setInitParameter( \u00abjersey.config.server.provider.classnames\u00bb, EntryPoint.class.getCanonicalName()); try { jettyServer.start(); jettyServer.join(); } catch (Exception e) { logger.error(e.getMessage()); } finally { jettyServer.destroy(); } } } Llamamos a maven con un simple clean install, ejecutamos el paquete jar generado con la m\u00e1quina virtual java que nos apetezca y listo !Tenemos un webservice rest con su contenedor de aplicaciones incorporado que podemos transportar y puede servir cualquier tipo de informaci\u00f3n.<\/p>\n","protected":false},"author":3,"featured_media":476,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[9,4],"tags":[48,49,47,50],"class_list":["post-467","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-formacion","category-java","tag-java","tag-jetty","tag-rest","tag-servicio"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.4 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Servicio REST con Jetty embebido en un jar - Setblau<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/setblau.com\/blog\/servicio-rest-con-jetty-embebido-en-un-jar\/\" \/>\n<meta property=\"og:locale\" content=\"es_ES\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Servicio REST con Jetty embebido en un jar - Setblau\" \/>\n<meta property=\"og:description\" content=\"En algunas ocasiones, cuando la relaci\u00f3n con el departamento de sistemas no es tan buena como se desear\u00eda, es preferible minimizar las tareas a realizar por personas que no seamos nosotros&#8230; Para esos casos y aquellos en los que deseemos una aplicaci\u00f3n portable, accesible f\u00e1cilmente desde un framework javascript, potente y vers\u00e1til, podemos usar servicios REST con el contenedor de aplicaciones JETTY embebido en un \u00fanico JAR. El primer paso es crear un proyecto Maven, usamos Maven para no tener problemas de dependencias y generar el jar de una forma r\u00e1pida y comoda. Podemos usar el arquetipo quickstart, que es el m\u00e1s simple de todos, una vez hemos creado el proyecto, desde la consola o desde nuestro ide preferido, vamos a editar el POM para obtener todas las librer\u00edas precisas, si alguna de las que ponemos en este ejemplo no la puede encontrar vuestro maven, usad maven central para buscar una versi\u00f3n m\u00e1s actual o a\u00f1adid el jar a vuestro repositorio local. Podemos dejar nuestro POM similar al siguiente: &lt;project xmlns=&quot;http:\/\/maven.apache.org\/POM\/4.0.0&quot; xmlns:xsi=&quot;http:\/\/www.w3.org\/2001\/XMLSchema-instance&quot; xsi:schemaLocation=&quot;http:\/\/maven.apache.org\/POM\/4.0.0 http:\/\/maven.apache.org\/xsd\/maven-4.0.0.xsd&quot;&gt; &lt;modelVersion&gt;4.0.0&lt;\/modelVersion&gt; &lt;groupId&gt;com.setblau.jetty.ws&lt;\/groupId&gt; &lt;artifactId&gt;rest&lt;\/artifactId&gt; &lt;version&gt;0.0.1&lt;\/version&gt; &lt;packaging&gt;jar&lt;\/packaging&gt; &lt;name&gt;restapi&lt;\/name&gt; &lt;url&gt;http:\/\/maven.apache.org&lt;\/url&gt; &lt;properties&gt; &lt;project.build.sourceEncoding&gt;UTF-8&lt;\/project.build.sourceEncoding&gt; &lt;\/properties&gt; &lt;dependencies&gt; &lt;dependency&gt; &lt;groupId&gt;org.eclipse.jetty&lt;\/groupId&gt; &lt;artifactId&gt;jetty-server&lt;\/artifactId&gt; &lt;version&gt;9.2.3.v20140905&lt;\/version&gt; &lt;\/dependency&gt; &lt;dependency&gt; &lt;groupId&gt;org.eclipse.jetty&lt;\/groupId&gt; &lt;artifactId&gt;jetty-servlet&lt;\/artifactId&gt; &lt;version&gt;9.2.3.v20140905&lt;\/version&gt; &lt;\/dependency&gt; &lt;dependency&gt; &lt;groupId&gt;org.glassfish.jersey.core&lt;\/groupId&gt; &lt;artifactId&gt;jersey-server&lt;\/artifactId&gt; &lt;version&gt;2.7&lt;\/version&gt; &lt;\/dependency&gt; &lt;dependency&gt; &lt;groupId&gt;org.glassfish.jersey.containers&lt;\/groupId&gt; &lt;artifactId&gt;jersey-container-servlet-core&lt;\/artifactId&gt; &lt;version&gt;2.7&lt;\/version&gt; &lt;\/dependency&gt; &lt;dependency&gt; &lt;groupId&gt;org.glassfish.jersey.containers&lt;\/groupId&gt; &lt;artifactId&gt;jersey-container-jetty-http&lt;\/artifactId&gt; &lt;version&gt;2.7&lt;\/version&gt; &lt;\/dependency&gt; &lt;dependency&gt; &lt;groupId&gt;org.glassfish.jersey.media&lt;\/groupId&gt; &lt;artifactId&gt;jersey-media-moxy&lt;\/artifactId&gt; &lt;version&gt;2.7&lt;\/version&gt; &lt;\/dependency&gt; &lt;dependency&gt; &lt;groupId&gt;com.vertica&lt;\/groupId&gt; &lt;artifactId&gt;vertica-jdbc&lt;\/artifactId&gt; &lt;version&gt;7.0.2-1&lt;\/version&gt; &lt;\/dependency&gt; &lt;dependency&gt; &lt;groupId&gt;log4j&lt;\/groupId&gt; &lt;artifactId&gt;log4j&lt;\/artifactId&gt; &lt;version&gt;1.2.17&lt;\/version&gt; &lt;\/dependency&gt; &lt;dependency&gt; &lt;groupId&gt;com.google.code.gson&lt;\/groupId&gt; &lt;artifactId&gt;gson&lt;\/artifactId&gt; &lt;version&gt;2.3.1&lt;\/version&gt; &lt;scope&gt;compile&lt;\/scope&gt; &lt;\/dependency&gt; &lt;\/dependencies&gt; &lt;build&gt; &lt;plugins&gt; &lt;plugin&gt; &lt;groupId&gt;org.apache.maven.plugins&lt;\/groupId&gt; &lt;artifactId&gt;maven-shade-plugin&lt;\/artifactId&gt; &lt;version&gt;1.6&lt;\/version&gt; &lt;configuration&gt; &lt;createDependencyReducedPom&gt;true&lt;\/createDependencyReducedPom&gt; &lt;filters&gt; &lt;filter&gt; &lt;artifact&gt;*:*&lt;\/artifact&gt; &lt;excludes&gt; &lt;exclude&gt;META-INF\/*.SF&lt;\/exclude&gt; &lt;exclude&gt;META-INF\/*.DSA&lt;\/exclude&gt; &lt;exclude&gt;META-INF\/*.RSA&lt;\/exclude&gt; &lt;\/excludes&gt; &lt;\/filter&gt; &lt;\/filters&gt; &lt;\/configuration&gt; &lt;executions&gt; &lt;execution&gt; &lt;phase&gt;package&lt;\/phase&gt; &lt;goals&gt; &lt;goal&gt;shade&lt;\/goal&gt; &lt;\/goals&gt; &lt;configuration&gt; &lt;transformers&gt; &lt;transformer implementation=&quot;org.apache.maven.plugins.shade.resource.ServicesResourceTransformer&quot; \/&gt; &lt;transformer implementation=&quot;org.apache.maven.plugins.shade.resource.ManifestResourceTransformer&quot;&gt; &lt;manifestEntries&gt; &lt;Main-Class&gt;abertis.ws.restapi.App&lt;\/Main-Class&gt; &lt;\/manifestEntries&gt; &lt;\/transformer&gt; &lt;\/transformers&gt; &lt;\/configuration&gt; &lt;\/execution&gt; &lt;\/executions&gt; &lt;\/plugin&gt; &lt;plugin&gt; &lt;groupId&gt;org.codehaus.mojo&lt;\/groupId&gt; &lt;artifactId&gt;exec-maven-plugin&lt;\/artifactId&gt; &lt;version&gt;1.2.1&lt;\/version&gt; &lt;configuration&gt; &lt;mainClass&gt;abertis.ws.restapi.App&lt;\/mainClass&gt; &lt;\/configuration&gt; &lt;\/plugin&gt; &lt;\/plugins&gt; &lt;\/build&gt; &lt;\/project&gt; Una vez hecho esto pasamos a picar c\u00f3digo, creamos una nueva clase en la que haremos los siguiente imports: import javax.ws.rs.GET; import javax.ws.rs.Path; import javax.ws.rs.Produces; import javax.ws.rs.core.MediaType; Una vez hecha, a\u00f1adiremos las siguientes anotaciones: package com.setblau.jetty.ws.service; import javax.servlet.http.HttpServletRequest; import javax.ws.rs.*; import javax.ws.rs.core.*; import org.apache.log4j.Logger; import com.google.gson.Gson; import abertis.ws.dao.Database; import abertis.ws.dao.GetJobStatistics; \/** * Class as servlet for get all jersey requests * * @author lgonzalez * *\/ @Path(&quot;\/api&quot;) public class EntryPoint { private static Logger logger = Logger.getLogger(EntryPoint.class); \/** * Test method * * @param name * @param request * @return *\/ @GET @Path(&quot;test&quot;) @Produces(MediaType.TEXT_PLAIN) public String test(@QueryParam(&quot;name&quot;) String name, @Context HttpServletRequest request) { logger.info(&quot;Query -&gt; EntryPoint -&gt; &quot; + &quot;TEXT_PLAIN from : &quot; + request.getRemoteAddr()); String respuesta = &quot;&quot;; respuesta += &quot;Test call &quot; + name + &quot; your bdd connection: &quot; + Database.getConnection().toString() + &quot; your ip address is: &quot; + request.getRemoteAddr(); return respuesta; } \/** * GetJobStatisticsByDate json reply * * @param customer * @param startTime * @param endTime * @param request * @return *\/ @GET @Path(&quot;GetJobStatisticsByDate&quot;) @Produces(MediaType.APPLICATION_JSON) public String GetJobStatisticsByDate( @QueryParam(&quot;customer&quot;) String customer, @QueryParam(&quot;startTime&quot;) String startTime, @QueryParam(&quot;endTime&quot;) String endTime, @Context HttpServletRequest request) { logger.info(&quot;Query -&gt; EntryPoint -&gt; &quot; + &quot;GetJobStatisticsByDate -&gt; from: &quot; + request.getRemoteAddr() + &quot; witch parameters: &quot; + customer + &quot; \/ &quot; + startTime + &quot; \/ &quot; + endTime); String respuesta = &quot;&quot;; \/\/ JobStatistics obj = new JobStatistics(); Gson gson = new Gson(); respuesta = gson.toJson(new GetJobStatistics().getDataFromDatabase( customer, startTime, endTime)); return respuesta; } } Con esto ya tendremos un servlet que recoger\u00e1 las llamadas de nuestros clientes. Ahora pasamos a crear la clase que va a arrancar el contenedor de aplicaciones, que puede ser similar a la siguiente: package com.setblau.jetty.ws.service; import org.eclipse.jetty.server.Server; import org.eclipse.jetty.servlet.ServletContextHandler; import org.eclipse.jetty.servlet.ServletHolder; import org.apache.log4j.Logger; import org.apache.log4j.xml.DOMConfigurator; \/** * Launcher class * * @author lgonzalez * *\/ public class App { private static Logger logger = Logger.getLogger(App.class); \/** * Main method * * @param args *\/ public static void main(String[] args) { DOMConfigurator.configure(&quot;log4j.xml&quot;); logger.info(&quot;New execution : &quot;); ServletContextHandler context = new ServletContextHandler( ServletContextHandler.SESSIONS); context.setContextPath(&quot;\/&quot;); Server jettyServer = new Server(8080); jettyServer.setHandler(context); ServletHolder jerseyServlet = context.addServlet( org.glassfish.jersey.servlet.ServletContainer.class, &quot;\/*&quot;); jerseyServlet.setInitOrder(0); \/\/ Tells the Jersey Servlet which REST service\/class to load. jerseyServlet.setInitParameter( &quot;jersey.config.server.provider.classnames&quot;, EntryPoint.class.getCanonicalName()); try { jettyServer.start(); jettyServer.join(); } catch (Exception e) { logger.error(e.getMessage()); } finally { jettyServer.destroy(); } } } Llamamos a maven con un simple clean install, ejecutamos el paquete jar generado con la m\u00e1quina virtual java que nos apetezca y listo !Tenemos un webservice rest con su contenedor de aplicaciones incorporado que podemos transportar y puede servir cualquier tipo de informaci\u00f3n.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/setblau.com\/blog\/servicio-rest-con-jetty-embebido-en-un-jar\/\" \/>\n<meta property=\"og:site_name\" content=\"Setblau\" \/>\n<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/setblau\" \/>\n<meta property=\"article:published_time\" content=\"2015-06-15T03:00:23+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/setblau.com\/blog\/wp-content\/uploads\/2015\/06\/jersey_logo.png\" \/>\n\t<meta property=\"og:image:width\" content=\"64\" \/>\n\t<meta property=\"og:image:height\" content=\"55\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"author\" content=\"Llu\u00eds Gonz\u00e0lez\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@Setblau\" \/>\n<meta name=\"twitter:site\" content=\"@Setblau\" \/>\n<meta name=\"twitter:label1\" content=\"Escrito por\" \/>\n\t<meta name=\"twitter:data1\" content=\"Llu\u00eds Gonz\u00e0lez\" \/>\n\t<meta name=\"twitter:label2\" content=\"Tiempo de lectura\" \/>\n\t<meta name=\"twitter:data2\" content=\"6 minutos\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/setblau.com\\\/blog\\\/servicio-rest-con-jetty-embebido-en-un-jar\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/setblau.com\\\/blog\\\/servicio-rest-con-jetty-embebido-en-un-jar\\\/\"},\"author\":{\"name\":\"Llu\u00eds Gonz\u00e0lez\",\"@id\":\"https:\\\/\\\/setblau.com\\\/blog\\\/#\\\/schema\\\/person\\\/66c35168882c827bb8dc164524a3da4a\"},\"headline\":\"Servicio REST con Jetty embebido en un jar\",\"datePublished\":\"2015-06-15T03:00:23+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/setblau.com\\\/blog\\\/servicio-rest-con-jetty-embebido-en-un-jar\\\/\"},\"wordCount\":295,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\\\/\\\/setblau.com\\\/blog\\\/#organization\"},\"image\":{\"@id\":\"https:\\\/\\\/setblau.com\\\/blog\\\/servicio-rest-con-jetty-embebido-en-un-jar\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/setblau.com\\\/blog\\\/wp-content\\\/uploads\\\/2015\\\/06\\\/jersey_logo.png\",\"keywords\":[\"java\",\"jetty\",\"rest\",\"servicio\"],\"articleSection\":[\"Formaci\u00f3n\",\"Java\"],\"inLanguage\":\"es\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/setblau.com\\\/blog\\\/servicio-rest-con-jetty-embebido-en-un-jar\\\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/setblau.com\\\/blog\\\/servicio-rest-con-jetty-embebido-en-un-jar\\\/\",\"url\":\"https:\\\/\\\/setblau.com\\\/blog\\\/servicio-rest-con-jetty-embebido-en-un-jar\\\/\",\"name\":\"Servicio REST con Jetty embebido en un jar - Setblau\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/setblau.com\\\/blog\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/setblau.com\\\/blog\\\/servicio-rest-con-jetty-embebido-en-un-jar\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/setblau.com\\\/blog\\\/servicio-rest-con-jetty-embebido-en-un-jar\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/setblau.com\\\/blog\\\/wp-content\\\/uploads\\\/2015\\\/06\\\/jersey_logo.png\",\"datePublished\":\"2015-06-15T03:00:23+00:00\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/setblau.com\\\/blog\\\/servicio-rest-con-jetty-embebido-en-un-jar\\\/#breadcrumb\"},\"inLanguage\":\"es\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/setblau.com\\\/blog\\\/servicio-rest-con-jetty-embebido-en-un-jar\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"es\",\"@id\":\"https:\\\/\\\/setblau.com\\\/blog\\\/servicio-rest-con-jetty-embebido-en-un-jar\\\/#primaryimage\",\"url\":\"https:\\\/\\\/setblau.com\\\/blog\\\/wp-content\\\/uploads\\\/2015\\\/06\\\/jersey_logo.png\",\"contentUrl\":\"https:\\\/\\\/setblau.com\\\/blog\\\/wp-content\\\/uploads\\\/2015\\\/06\\\/jersey_logo.png\",\"width\":64,\"height\":55,\"caption\":\"jersey_logo\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/setblau.com\\\/blog\\\/servicio-rest-con-jetty-embebido-en-un-jar\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Portada\",\"item\":\"https:\\\/\\\/setblau.com\\\/blog\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Servicio REST con Jetty embebido en un jar\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/setblau.com\\\/blog\\\/#website\",\"url\":\"https:\\\/\\\/setblau.com\\\/blog\\\/\",\"name\":\"Setblau\",\"description\":\"Tutoriales y novedades\",\"publisher\":{\"@id\":\"https:\\\/\\\/setblau.com\\\/blog\\\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/setblau.com\\\/blog\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"es\"},{\"@type\":\"Organization\",\"@id\":\"https:\\\/\\\/setblau.com\\\/blog\\\/#organization\",\"name\":\"Setblau\",\"url\":\"https:\\\/\\\/setblau.com\\\/blog\\\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"es\",\"@id\":\"https:\\\/\\\/setblau.com\\\/blog\\\/#\\\/schema\\\/logo\\\/image\\\/\",\"url\":\"https:\\\/\\\/setblau.com\\\/blog\\\/wp-content\\\/uploads\\\/2015\\\/11\\\/setblau.gif\",\"contentUrl\":\"https:\\\/\\\/setblau.com\\\/blog\\\/wp-content\\\/uploads\\\/2015\\\/11\\\/setblau.gif\",\"width\":394,\"height\":83,\"caption\":\"Setblau\"},\"image\":{\"@id\":\"https:\\\/\\\/setblau.com\\\/blog\\\/#\\\/schema\\\/logo\\\/image\\\/\"},\"sameAs\":[\"https:\\\/\\\/www.facebook.com\\\/setblau\",\"https:\\\/\\\/x.com\\\/Setblau\"]},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/setblau.com\\\/blog\\\/#\\\/schema\\\/person\\\/66c35168882c827bb8dc164524a3da4a\",\"name\":\"Llu\u00eds Gonz\u00e0lez\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"es\",\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/9104069be4bfdffbd23837a15a8bd394dc6ebccfd101b9a57e30743adafe7d9f?s=96&d=mm&r=g\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/9104069be4bfdffbd23837a15a8bd394dc6ebccfd101b9a57e30743adafe7d9f?s=96&d=mm&r=g\",\"contentUrl\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/9104069be4bfdffbd23837a15a8bd394dc6ebccfd101b9a57e30743adafe7d9f?s=96&d=mm&r=g\",\"caption\":\"Llu\u00eds Gonz\u00e0lez\"},\"description\":\"Director and Founder from setblau.com\",\"sameAs\":[\"http:\\\/\\\/www.setblau.com\"],\"url\":\"https:\\\/\\\/setblau.com\\\/blog\\\/author\\\/lgonzalez\\\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Servicio REST con Jetty embebido en un jar - Setblau","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/setblau.com\/blog\/servicio-rest-con-jetty-embebido-en-un-jar\/","og_locale":"es_ES","og_type":"article","og_title":"Servicio REST con Jetty embebido en un jar - Setblau","og_description":"En algunas ocasiones, cuando la relaci\u00f3n con el departamento de sistemas no es tan buena como se desear\u00eda, es preferible minimizar las tareas a realizar por personas que no seamos nosotros&#8230; Para esos casos y aquellos en los que deseemos una aplicaci\u00f3n portable, accesible f\u00e1cilmente desde un framework javascript, potente y vers\u00e1til, podemos usar servicios REST con el contenedor de aplicaciones JETTY embebido en un \u00fanico JAR. El primer paso es crear un proyecto Maven, usamos Maven para no tener problemas de dependencias y generar el jar de una forma r\u00e1pida y comoda. Podemos usar el arquetipo quickstart, que es el m\u00e1s simple de todos, una vez hemos creado el proyecto, desde la consola o desde nuestro ide preferido, vamos a editar el POM para obtener todas las librer\u00edas precisas, si alguna de las que ponemos en este ejemplo no la puede encontrar vuestro maven, usad maven central para buscar una versi\u00f3n m\u00e1s actual o a\u00f1adid el jar a vuestro repositorio local. Podemos dejar nuestro POM similar al siguiente: &lt;project xmlns=\"http:\/\/maven.apache.org\/POM\/4.0.0\" xmlns:xsi=\"http:\/\/www.w3.org\/2001\/XMLSchema-instance\" xsi:schemaLocation=\"http:\/\/maven.apache.org\/POM\/4.0.0 http:\/\/maven.apache.org\/xsd\/maven-4.0.0.xsd\"&gt; &lt;modelVersion&gt;4.0.0&lt;\/modelVersion&gt; &lt;groupId&gt;com.setblau.jetty.ws&lt;\/groupId&gt; &lt;artifactId&gt;rest&lt;\/artifactId&gt; &lt;version&gt;0.0.1&lt;\/version&gt; &lt;packaging&gt;jar&lt;\/packaging&gt; &lt;name&gt;restapi&lt;\/name&gt; &lt;url&gt;http:\/\/maven.apache.org&lt;\/url&gt; &lt;properties&gt; &lt;project.build.sourceEncoding&gt;UTF-8&lt;\/project.build.sourceEncoding&gt; &lt;\/properties&gt; &lt;dependencies&gt; &lt;dependency&gt; &lt;groupId&gt;org.eclipse.jetty&lt;\/groupId&gt; &lt;artifactId&gt;jetty-server&lt;\/artifactId&gt; &lt;version&gt;9.2.3.v20140905&lt;\/version&gt; &lt;\/dependency&gt; &lt;dependency&gt; &lt;groupId&gt;org.eclipse.jetty&lt;\/groupId&gt; &lt;artifactId&gt;jetty-servlet&lt;\/artifactId&gt; &lt;version&gt;9.2.3.v20140905&lt;\/version&gt; &lt;\/dependency&gt; &lt;dependency&gt; &lt;groupId&gt;org.glassfish.jersey.core&lt;\/groupId&gt; &lt;artifactId&gt;jersey-server&lt;\/artifactId&gt; &lt;version&gt;2.7&lt;\/version&gt; &lt;\/dependency&gt; &lt;dependency&gt; &lt;groupId&gt;org.glassfish.jersey.containers&lt;\/groupId&gt; &lt;artifactId&gt;jersey-container-servlet-core&lt;\/artifactId&gt; &lt;version&gt;2.7&lt;\/version&gt; &lt;\/dependency&gt; &lt;dependency&gt; &lt;groupId&gt;org.glassfish.jersey.containers&lt;\/groupId&gt; &lt;artifactId&gt;jersey-container-jetty-http&lt;\/artifactId&gt; &lt;version&gt;2.7&lt;\/version&gt; &lt;\/dependency&gt; &lt;dependency&gt; &lt;groupId&gt;org.glassfish.jersey.media&lt;\/groupId&gt; &lt;artifactId&gt;jersey-media-moxy&lt;\/artifactId&gt; &lt;version&gt;2.7&lt;\/version&gt; &lt;\/dependency&gt; &lt;dependency&gt; &lt;groupId&gt;com.vertica&lt;\/groupId&gt; &lt;artifactId&gt;vertica-jdbc&lt;\/artifactId&gt; &lt;version&gt;7.0.2-1&lt;\/version&gt; &lt;\/dependency&gt; &lt;dependency&gt; &lt;groupId&gt;log4j&lt;\/groupId&gt; &lt;artifactId&gt;log4j&lt;\/artifactId&gt; &lt;version&gt;1.2.17&lt;\/version&gt; &lt;\/dependency&gt; &lt;dependency&gt; &lt;groupId&gt;com.google.code.gson&lt;\/groupId&gt; &lt;artifactId&gt;gson&lt;\/artifactId&gt; &lt;version&gt;2.3.1&lt;\/version&gt; &lt;scope&gt;compile&lt;\/scope&gt; &lt;\/dependency&gt; &lt;\/dependencies&gt; &lt;build&gt; &lt;plugins&gt; &lt;plugin&gt; &lt;groupId&gt;org.apache.maven.plugins&lt;\/groupId&gt; &lt;artifactId&gt;maven-shade-plugin&lt;\/artifactId&gt; &lt;version&gt;1.6&lt;\/version&gt; &lt;configuration&gt; &lt;createDependencyReducedPom&gt;true&lt;\/createDependencyReducedPom&gt; &lt;filters&gt; &lt;filter&gt; &lt;artifact&gt;*:*&lt;\/artifact&gt; &lt;excludes&gt; &lt;exclude&gt;META-INF\/*.SF&lt;\/exclude&gt; &lt;exclude&gt;META-INF\/*.DSA&lt;\/exclude&gt; &lt;exclude&gt;META-INF\/*.RSA&lt;\/exclude&gt; &lt;\/excludes&gt; &lt;\/filter&gt; &lt;\/filters&gt; &lt;\/configuration&gt; &lt;executions&gt; &lt;execution&gt; &lt;phase&gt;package&lt;\/phase&gt; &lt;goals&gt; &lt;goal&gt;shade&lt;\/goal&gt; &lt;\/goals&gt; &lt;configuration&gt; &lt;transformers&gt; &lt;transformer implementation=\"org.apache.maven.plugins.shade.resource.ServicesResourceTransformer\" \/&gt; &lt;transformer implementation=\"org.apache.maven.plugins.shade.resource.ManifestResourceTransformer\"&gt; &lt;manifestEntries&gt; &lt;Main-Class&gt;abertis.ws.restapi.App&lt;\/Main-Class&gt; &lt;\/manifestEntries&gt; &lt;\/transformer&gt; &lt;\/transformers&gt; &lt;\/configuration&gt; &lt;\/execution&gt; &lt;\/executions&gt; &lt;\/plugin&gt; &lt;plugin&gt; &lt;groupId&gt;org.codehaus.mojo&lt;\/groupId&gt; &lt;artifactId&gt;exec-maven-plugin&lt;\/artifactId&gt; &lt;version&gt;1.2.1&lt;\/version&gt; &lt;configuration&gt; &lt;mainClass&gt;abertis.ws.restapi.App&lt;\/mainClass&gt; &lt;\/configuration&gt; &lt;\/plugin&gt; &lt;\/plugins&gt; &lt;\/build&gt; &lt;\/project&gt; Una vez hecho esto pasamos a picar c\u00f3digo, creamos una nueva clase en la que haremos los siguiente imports: import javax.ws.rs.GET; import javax.ws.rs.Path; import javax.ws.rs.Produces; import javax.ws.rs.core.MediaType; Una vez hecha, a\u00f1adiremos las siguientes anotaciones: package com.setblau.jetty.ws.service; import javax.servlet.http.HttpServletRequest; import javax.ws.rs.*; import javax.ws.rs.core.*; import org.apache.log4j.Logger; import com.google.gson.Gson; import abertis.ws.dao.Database; import abertis.ws.dao.GetJobStatistics; \/** * Class as servlet for get all jersey requests * * @author lgonzalez * *\/ @Path(\"\/api\") public class EntryPoint { private static Logger logger = Logger.getLogger(EntryPoint.class); \/** * Test method * * @param name * @param request * @return *\/ @GET @Path(\"test\") @Produces(MediaType.TEXT_PLAIN) public String test(@QueryParam(\"name\") String name, @Context HttpServletRequest request) { logger.info(\"Query -&gt; EntryPoint -&gt; \" + \"TEXT_PLAIN from : \" + request.getRemoteAddr()); String respuesta = \"\"; respuesta += \"Test call \" + name + \" your bdd connection: \" + Database.getConnection().toString() + \" your ip address is: \" + request.getRemoteAddr(); return respuesta; } \/** * GetJobStatisticsByDate json reply * * @param customer * @param startTime * @param endTime * @param request * @return *\/ @GET @Path(\"GetJobStatisticsByDate\") @Produces(MediaType.APPLICATION_JSON) public String GetJobStatisticsByDate( @QueryParam(\"customer\") String customer, @QueryParam(\"startTime\") String startTime, @QueryParam(\"endTime\") String endTime, @Context HttpServletRequest request) { logger.info(\"Query -&gt; EntryPoint -&gt; \" + \"GetJobStatisticsByDate -&gt; from: \" + request.getRemoteAddr() + \" witch parameters: \" + customer + \" \/ \" + startTime + \" \/ \" + endTime); String respuesta = \"\"; \/\/ JobStatistics obj = new JobStatistics(); Gson gson = new Gson(); respuesta = gson.toJson(new GetJobStatistics().getDataFromDatabase( customer, startTime, endTime)); return respuesta; } } Con esto ya tendremos un servlet que recoger\u00e1 las llamadas de nuestros clientes. Ahora pasamos a crear la clase que va a arrancar el contenedor de aplicaciones, que puede ser similar a la siguiente: package com.setblau.jetty.ws.service; import org.eclipse.jetty.server.Server; import org.eclipse.jetty.servlet.ServletContextHandler; import org.eclipse.jetty.servlet.ServletHolder; import org.apache.log4j.Logger; import org.apache.log4j.xml.DOMConfigurator; \/** * Launcher class * * @author lgonzalez * *\/ public class App { private static Logger logger = Logger.getLogger(App.class); \/** * Main method * * @param args *\/ public static void main(String[] args) { DOMConfigurator.configure(\"log4j.xml\"); logger.info(\"New execution : \"); ServletContextHandler context = new ServletContextHandler( ServletContextHandler.SESSIONS); context.setContextPath(\"\/\"); Server jettyServer = new Server(8080); jettyServer.setHandler(context); ServletHolder jerseyServlet = context.addServlet( org.glassfish.jersey.servlet.ServletContainer.class, \"\/*\"); jerseyServlet.setInitOrder(0); \/\/ Tells the Jersey Servlet which REST service\/class to load. jerseyServlet.setInitParameter( \"jersey.config.server.provider.classnames\", EntryPoint.class.getCanonicalName()); try { jettyServer.start(); jettyServer.join(); } catch (Exception e) { logger.error(e.getMessage()); } finally { jettyServer.destroy(); } } } Llamamos a maven con un simple clean install, ejecutamos el paquete jar generado con la m\u00e1quina virtual java que nos apetezca y listo !Tenemos un webservice rest con su contenedor de aplicaciones incorporado que podemos transportar y puede servir cualquier tipo de informaci\u00f3n.","og_url":"https:\/\/setblau.com\/blog\/servicio-rest-con-jetty-embebido-en-un-jar\/","og_site_name":"Setblau","article_publisher":"https:\/\/www.facebook.com\/setblau","article_published_time":"2015-06-15T03:00:23+00:00","og_image":[{"width":64,"height":55,"url":"https:\/\/setblau.com\/blog\/wp-content\/uploads\/2015\/06\/jersey_logo.png","type":"image\/png"}],"author":"Llu\u00eds Gonz\u00e0lez","twitter_card":"summary_large_image","twitter_creator":"@Setblau","twitter_site":"@Setblau","twitter_misc":{"Escrito por":"Llu\u00eds Gonz\u00e0lez","Tiempo de lectura":"6 minutos"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/setblau.com\/blog\/servicio-rest-con-jetty-embebido-en-un-jar\/#article","isPartOf":{"@id":"https:\/\/setblau.com\/blog\/servicio-rest-con-jetty-embebido-en-un-jar\/"},"author":{"name":"Llu\u00eds Gonz\u00e0lez","@id":"https:\/\/setblau.com\/blog\/#\/schema\/person\/66c35168882c827bb8dc164524a3da4a"},"headline":"Servicio REST con Jetty embebido en un jar","datePublished":"2015-06-15T03:00:23+00:00","mainEntityOfPage":{"@id":"https:\/\/setblau.com\/blog\/servicio-rest-con-jetty-embebido-en-un-jar\/"},"wordCount":295,"commentCount":0,"publisher":{"@id":"https:\/\/setblau.com\/blog\/#organization"},"image":{"@id":"https:\/\/setblau.com\/blog\/servicio-rest-con-jetty-embebido-en-un-jar\/#primaryimage"},"thumbnailUrl":"https:\/\/setblau.com\/blog\/wp-content\/uploads\/2015\/06\/jersey_logo.png","keywords":["java","jetty","rest","servicio"],"articleSection":["Formaci\u00f3n","Java"],"inLanguage":"es","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/setblau.com\/blog\/servicio-rest-con-jetty-embebido-en-un-jar\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/setblau.com\/blog\/servicio-rest-con-jetty-embebido-en-un-jar\/","url":"https:\/\/setblau.com\/blog\/servicio-rest-con-jetty-embebido-en-un-jar\/","name":"Servicio REST con Jetty embebido en un jar - Setblau","isPartOf":{"@id":"https:\/\/setblau.com\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/setblau.com\/blog\/servicio-rest-con-jetty-embebido-en-un-jar\/#primaryimage"},"image":{"@id":"https:\/\/setblau.com\/blog\/servicio-rest-con-jetty-embebido-en-un-jar\/#primaryimage"},"thumbnailUrl":"https:\/\/setblau.com\/blog\/wp-content\/uploads\/2015\/06\/jersey_logo.png","datePublished":"2015-06-15T03:00:23+00:00","breadcrumb":{"@id":"https:\/\/setblau.com\/blog\/servicio-rest-con-jetty-embebido-en-un-jar\/#breadcrumb"},"inLanguage":"es","potentialAction":[{"@type":"ReadAction","target":["https:\/\/setblau.com\/blog\/servicio-rest-con-jetty-embebido-en-un-jar\/"]}]},{"@type":"ImageObject","inLanguage":"es","@id":"https:\/\/setblau.com\/blog\/servicio-rest-con-jetty-embebido-en-un-jar\/#primaryimage","url":"https:\/\/setblau.com\/blog\/wp-content\/uploads\/2015\/06\/jersey_logo.png","contentUrl":"https:\/\/setblau.com\/blog\/wp-content\/uploads\/2015\/06\/jersey_logo.png","width":64,"height":55,"caption":"jersey_logo"},{"@type":"BreadcrumbList","@id":"https:\/\/setblau.com\/blog\/servicio-rest-con-jetty-embebido-en-un-jar\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Portada","item":"https:\/\/setblau.com\/blog\/"},{"@type":"ListItem","position":2,"name":"Servicio REST con Jetty embebido en un jar"}]},{"@type":"WebSite","@id":"https:\/\/setblau.com\/blog\/#website","url":"https:\/\/setblau.com\/blog\/","name":"Setblau","description":"Tutoriales y novedades","publisher":{"@id":"https:\/\/setblau.com\/blog\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/setblau.com\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"es"},{"@type":"Organization","@id":"https:\/\/setblau.com\/blog\/#organization","name":"Setblau","url":"https:\/\/setblau.com\/blog\/","logo":{"@type":"ImageObject","inLanguage":"es","@id":"https:\/\/setblau.com\/blog\/#\/schema\/logo\/image\/","url":"https:\/\/setblau.com\/blog\/wp-content\/uploads\/2015\/11\/setblau.gif","contentUrl":"https:\/\/setblau.com\/blog\/wp-content\/uploads\/2015\/11\/setblau.gif","width":394,"height":83,"caption":"Setblau"},"image":{"@id":"https:\/\/setblau.com\/blog\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/www.facebook.com\/setblau","https:\/\/x.com\/Setblau"]},{"@type":"Person","@id":"https:\/\/setblau.com\/blog\/#\/schema\/person\/66c35168882c827bb8dc164524a3da4a","name":"Llu\u00eds Gonz\u00e0lez","image":{"@type":"ImageObject","inLanguage":"es","@id":"https:\/\/secure.gravatar.com\/avatar\/9104069be4bfdffbd23837a15a8bd394dc6ebccfd101b9a57e30743adafe7d9f?s=96&d=mm&r=g","url":"https:\/\/secure.gravatar.com\/avatar\/9104069be4bfdffbd23837a15a8bd394dc6ebccfd101b9a57e30743adafe7d9f?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/9104069be4bfdffbd23837a15a8bd394dc6ebccfd101b9a57e30743adafe7d9f?s=96&d=mm&r=g","caption":"Llu\u00eds Gonz\u00e0lez"},"description":"Director and Founder from setblau.com","sameAs":["http:\/\/www.setblau.com"],"url":"https:\/\/setblau.com\/blog\/author\/lgonzalez\/"}]}},"_links":{"self":[{"href":"https:\/\/setblau.com\/blog\/wp-json\/wp\/v2\/posts\/467","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/setblau.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/setblau.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/setblau.com\/blog\/wp-json\/wp\/v2\/users\/3"}],"replies":[{"embeddable":true,"href":"https:\/\/setblau.com\/blog\/wp-json\/wp\/v2\/comments?post=467"}],"version-history":[{"count":9,"href":"https:\/\/setblau.com\/blog\/wp-json\/wp\/v2\/posts\/467\/revisions"}],"predecessor-version":[{"id":477,"href":"https:\/\/setblau.com\/blog\/wp-json\/wp\/v2\/posts\/467\/revisions\/477"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/setblau.com\/blog\/wp-json\/wp\/v2\/media\/476"}],"wp:attachment":[{"href":"https:\/\/setblau.com\/blog\/wp-json\/wp\/v2\/media?parent=467"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/setblau.com\/blog\/wp-json\/wp\/v2\/categories?post=467"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/setblau.com\/blog\/wp-json\/wp\/v2\/tags?post=467"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}