{"version":"1.0","provider_name":"Setblau","provider_url":"https:\/\/setblau.com\/blog","author_name":"Llu\u00eds Gonz\u00e0lez","author_url":"https:\/\/setblau.com\/blog\/author\/lgonzalez\/","title":"Servicio REST con Jetty embebido en un jar - Setblau","type":"rich","width":600,"height":338,"html":"<blockquote class=\"wp-embedded-content\" data-secret=\"PM2gdJIlV1\"><a href=\"https:\/\/setblau.com\/blog\/servicio-rest-con-jetty-embebido-en-un-jar\/\">Servicio REST con Jetty embebido en un jar<\/a><\/blockquote><iframe sandbox=\"allow-scripts\" security=\"restricted\" src=\"https:\/\/setblau.com\/blog\/servicio-rest-con-jetty-embebido-en-un-jar\/embed\/#?secret=PM2gdJIlV1\" width=\"600\" height=\"338\" title=\"\u00abServicio REST con Jetty embebido en un jar\u00bb \u2014 Setblau\" data-secret=\"PM2gdJIlV1\" frameborder=\"0\" marginwidth=\"0\" marginheight=\"0\" scrolling=\"no\" class=\"wp-embedded-content\"><\/iframe><script type=\"text\/javascript\">\n\/* <![CDATA[ *\/\n\/*! This file is auto-generated *\/\n!function(d,l){\"use strict\";l.querySelector&&d.addEventListener&&\"undefined\"!=typeof URL&&(d.wp=d.wp||{},d.wp.receiveEmbedMessage||(d.wp.receiveEmbedMessage=function(e){var t=e.data;if((t||t.secret||t.message||t.value)&&!\/[^a-zA-Z0-9]\/.test(t.secret)){for(var s,r,n,a=l.querySelectorAll('iframe[data-secret=\"'+t.secret+'\"]'),o=l.querySelectorAll('blockquote[data-secret=\"'+t.secret+'\"]'),c=new RegExp(\"^https?:$\",\"i\"),i=0;i<o.length;i++)o[i].style.display=\"none\";for(i=0;i<a.length;i++)s=a[i],e.source===s.contentWindow&&(s.removeAttribute(\"style\"),\"height\"===t.message?(1e3<(r=parseInt(t.value,10))?r=1e3:~~r<200&&(r=200),s.height=r):\"link\"===t.message&&(r=new URL(s.getAttribute(\"src\")),n=new URL(t.value),c.test(n.protocol))&&n.host===r.host&&l.activeElement===s&&(d.top.location.href=t.value))}},d.addEventListener(\"message\",d.wp.receiveEmbedMessage,!1),l.addEventListener(\"DOMContentLoaded\",function(){for(var e,t,s=l.querySelectorAll(\"iframe.wp-embedded-content\"),r=0;r<s.length;r++)(t=(e=s[r]).getAttribute(\"data-secret\"))||(t=Math.random().toString(36).substring(2,12),e.src+=\"#?secret=\"+t,e.setAttribute(\"data-secret\",t)),e.contentWindow.postMessage({message:\"ready\",secret:t},\"*\")},!1)))}(window,document);\n\/\/# sourceURL=https:\/\/setblau.com\/blog\/wp-includes\/js\/wp-embed.min.js\n\/* ]]> *\/\n<\/script>\n","thumbnail_url":"https:\/\/setblau.com\/blog\/wp-content\/uploads\/2015\/06\/jersey_logo.png","thumbnail_width":64,"thumbnail_height":55,"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."}