Monday, January 20, 2014

RESTful web services with jetty and jersey

Recently I was thinking if there is a way to start a web server in java just as easy as it is in node.js, if you don't know node.js you can check this link nodejs.org, so in node you just write a few lines and you have a server like this:


I thought that with something like this you can easily test your code without the burden of deploy it, and also saving some resources. 

So I start looking if there is something similar in java and I found several projects to start a web server or a minimal server, but I decided to go with jetty www.eclipse.org/jetty, so I'm going to show you how to run some restful web services using jetty. 

Also I'm going to use jersey jersey.java.net which simplifies the development of RESTful Web services and their clients in Java.

So you can download the jars from these projects or configure them through maven to your project to start using them, in these links www.eclipse.org/jetty , jersey.java.net you can check the instructions to do it.

So to create a web server with jetty is as easy as the following code:


If you run the code and check the http://localhost:8080/hello url you can see that your servlet is running, so basically in the code you create a Server object and set the port the Servlets and the servlets to run and that's it.

With jetty you can do much more than this, but for the purpose of this blog I will no go further, you can check the jetty documentation.

The following would be to create and deploy the RESTful web services, now we will use jersey to this.

The first thing to do is to create the services that we will deploy, for the example I will create two services one using JSON and other using XML, I will create two objects used to transfer the data.



In the classes above you can see two classes Employee with a nested class Address and Student, the only thing to notice from these classes are the annotations @XmlRootElement and @XmlAttribute, these annotations are used to do the parsing from object to the protocol used (XML, JSON) and from protocol to object.

The following would be to create the classes for the services.




The classes above use the standard Java EE specification for RESTful web services they use the @Path annotation at the top level to set the service path and each method use the @GET, @POST annotations to describe the type of service and the @Produces annotation to set the type of protocol to use.

The method getStudent of the class XMLStudentSvc has also the @Path("/student/{name}")  this specifies a path for this method, also note that it receives a parameter named "name" through the path and this parameter will be mapped to the parameter of the method.
For more about how define RESTful web services check the specification https://jcp.org/en/jsr/detail?id=311

Another thing to notice is that both classes are in a package called "rest", so the following to do would be to deploy these services in jetty as long as the jersey configuration.

This is the class for the server:



See in the class above all what it needs to configure jersey, a ServletHolder object is created to set the parameters, note that is indicated the package where the services are located and jersey will automatically deploy them. The ServletHolder object is passed to a ServletContextHandler object, and that's it with this the services should be up and running.

The last thing to do is to create a client for our services, for the client I will use jersey to help.

This is the client for the JSON service:


The client will call two methods, the first will be to the GET method and it uses the url with the path specified for this method ("http://localhost:9999/employee/getEmployee"), this method returns a response in JSON, then this response is unmarshal to a object with the call to "response.getEntity(Employee.class)".

If the JSON response is needed instead of the actual object all what is need to do is change the type to String in the unmarshal "response.getEntity(Employee.class)".

The other method specified in this client is the POST method this call doesn't return a thing,  it uses the url with the path specified for this method ("http://localhost:9999/employee/postEmployee") and it sends back the same object the client is receiving, you should see an output in the server since the service method is printing the object it is receiving.

This is the client for the XML service:


It is almost the same as the JSON client, the only difference is that a parameter is include in the url "http://localhost:9999/xmlServices/student/James", because the service is expecting it.

After running these examples I notice how easy and fast is to run the services and the few resources that required, I'm using at most 30Mb of memory.

51 comments:

  1. Hi, Your posts really helped me a lot in learning new things
    Specially the node.js, I was not aware of this....

    ReplyDelete
  2. In case someone arriving here is using Jersey 2.6 instead of 1.x which is used in the above examples, here is the Servlet Handler changes. Note that Moxy is now the default JSON processor and is loaded dynamically. No need to specify the POJO init parameter. Just make sure jersey.media.moxy and its dependencies are in the classpath and it will be loaded and used.

    ServletHolder jerseyServlet = context.addServlet(org.glassfish.jersey.servlet.ServletContainer.class, "/*");
    jerseyServlet.setInitOrder(1);
    jerseyServlet.setInitParameter("jersey.config.server.provider.packages","rest");

    ReplyDelete
  3. I follow the example and got:
    Exception in thread "main" java.lang.SecurityException: class "javax.servlet.ServletRegistration$Dynamic"'s signer information does not match signer information of other classes in the same package

    ReplyDelete
  4. I built the restful web service based on this tutorial and I found it very easy to use and understand.

    I had some problems migrating the tutorial from Jersey 1.x to 2.x but finally I got the web server up and running. Now, the problem is that it does not respond to requests from client (or browser). Does anyone know why?

    Here is my code:

    Provider package:

    package org.eclipse.eatop.jetty.helloworld.rest;
    import javax.ws.rs.GET;
    import javax.ws.rs.Path;
    import javax.ws.rs.PathParam;
    import javax.ws.rs.Produces;
    import javax.ws.rs.core.MediaType;


    @Path("/xmlServices")
    public class XMLProjectService {
    @GET
    @Produces(MediaType.TEXT_XML)
    public String getProject()
    {
    return "" + " hello world " ;
    }
    }
    Jetty embedded server:

    public Object execute(ExecutionEvent event) throws ExecutionException {
    Server server = new Server(8080);
    ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS);
    context.setContextPath("/");
    server.setHandler(context);
    ServletHolder sh = new ServletHolder(new ServletContainer());
    sh.setInitOrder(1);
    sh.setInitParameter(ServerProperties.PROVIDER_PACKAGES, "org.eclipse.eatop.jetty.helloworld.rest");
    context.addServlet(sh, "/*");

    try {
    server.start();
    } catch (Exception e) {
    System.out.println("Unable to start jetty web server");
    e.printStackTrace();
    }
    return null;
    }
    Client:

    public class Test {
    public static void main(String[] args) {
    Client client = ClientBuilder.newClient();
    WebTarget target = client.target(getBaseURI()).path("xmlServices");
    System.out.println(target.request("text/xml").get());
    }
    private static URI getBaseURI() {
    return UriBuilder.fromUri("http://localhost:8080/").build();
    }
    }

    The result I get is: InboundJaxrsResponse{ClientResponse{method=GET, uri=http://localhost:8080/xmlServices, status=404, reason=Not Found}}

    ReplyDelete
  5. you didn't setinitParameteres properly as what article mentioned :-

    sh.setInitParameter("com.sun.jersey.config.property.resourceConfigClass", "com.sun.jersey.api.core.PackagesResourceConfig");
    sh.setInitParameter("com.sun.jersey.config.property.packages", "rest");//Set the package where the services reside
    sh.setInitParameter("com.sun.jersey.api.json.POJOMappingFeature", "true");

    ReplyDelete
  6. Thanks for informative post which is very useful. I appreciate the blog author and like the articles of these blog.
    Web Development Company in Indore

    ReplyDelete
    Replies
    1. An important building block of SEO is to develop your website which can be easily understandable for both Online Visitors (most important) and search engine robots. In the current digital age, seo is important for your online success means to generate leads.

      SEO Services in IndiaSEO Company in India SEO Company in India SEO Services in India

      SEO Company in India SEO Services in India

      Delete
  7. Nice post. Gave me inspiration to write a few on my own since newer version don't quite work with this setup:
    http://ironicprogrammer.blogspot.se/2015/05/rest-with-jersey-and-jetty-part-3.html

    ReplyDelete
  8. Hi,

    I have tried to run the server and then access the link http://localhost:9999/employee/getEmployee.

    but it throws below error.

    2015-06-16 07:19:54.879:INFO:oejs.Server:jetty-8.1.14.v20131031
    2015-06-16 07:19:54.983:INFO:oejs.AbstractConnector:Started SelectChannelConnector@0.0.0.0:9999
    Jun 16, 2015 7:20:02 AM com.sun.jersey.api.core.PackagesResourceConfig init
    INFO: Scanning for root resource and provider classes in the packages:
    com.package.rest
    2015-06-16 07:20:02.744:WARN:/:unavailable
    java.lang.reflect.InvocationTargetException

    Any Hep..!!

    ReplyDelete
  9. Hi

    guys

    i see your post . i am very interested your post so i am very happy .
    website designing company in india

    ReplyDelete
  10. very informative post, Loved reading this post. Hostgator Review

    ReplyDelete
  11. Thanks for information on web services. for more information SEO Services Company in Chandigarh

    ReplyDelete

  12. Its a very good post, you said many useful information here .
    java servlet programming
    hardware and networking course

    ReplyDelete
  13. This is nice information,, Thanks for sharing this information,, Its very useful to me
    mobile app development

    ReplyDelete
  14. How did you get javax.servlet? I'm struggling to work it out, and a lot of answers online seem to boil down to 'use Eclipse EE', which is, of course, no use to me.

    ReplyDelete
  15. Nice Website...
    Hey JOIN now fblikesbot.com and Increase Facebook Likes your profile and websites.
    Increase Facebook Likes and check your website worth worth my websites
    its may be very beneficial for you also really

    ReplyDelete
  16. http://www.javaproficiency.com/2015/03/jersey-tutorial-for-beginners.html

    ReplyDelete
  17. Thanks for sharing excellent information. Your site is very cool . I am impressed by the details that you have on this site.Website Designing Bangalore | Web Design Company Bangalore

    ReplyDelete
  18. Thanks for this article, very useful. I have managed to update the jersey examples to jersey 2 and get a response from the server, but I still have 2 problems:
    a) how can I inject dependencies into my jersey resources? they get instanciated with the default ctor but in my case I need to pass in a dao object, so I get a NPE when I do a request
    b) how can I make jersey's logging less verbose? Ideally I want to send it through java.util.logging but I've tried adding jetty-logging.properties and also in the code with Log.setLog(...) but nothing seems to work. thanks,
    Martin

    ReplyDelete
  19. Thank you for taking the time to this information very useful!
    SEO services pakistan

    ReplyDelete
  20. Hi,
    I used the above examples to get example of JSON and XML Clients. Had a bit of trouble with the JSON client but eventually solved it by including jackson jar. In this case I don't think the com.sun.jersey.api.json.POJOMappingFeature needs to be set in the server code.
    I am using jackson-all-1.9.0.jar, jersey-bundle-1.19.jar, servlet-api-3.0.jar and jetty-8.1.2.

    I will probably move on now and try and get a similar example working with the latest version of Jersey.

    ReplyDelete
  21. Nice Information you have written here. Really Great Stuff. I keep it bookmark for our future purpose.

    We are also Web development Company in India who provide the services in Android App Development in Nagpur , SEO Company in Nagpur , Ecommerce Website Development in Nagpur. Visit Us today

    AceZed IT Solution

    ReplyDelete
  22. Nice Information you have written here. Really Great Stuff. I keep it bookmark for our future purpose. Our Best Presence in Content Marketing Find our Content Writing Services in Nagpur & Content Writing Company in Nagpur .
    AceZed IT Solution

    ReplyDelete
  23. It will very helpful as user point of view. Please keep sharing for the beneficial knowledge of users.

    Web Design services in Lucknow

    ReplyDelete
  24. Accuratesolutionltd führt mobile app Entwicklungsunternehmen. Wir entwickeln Apps für Handys, Tablets , iPads und iPhones . Dies ist aufgrund der zunehmenden Nutzung von Internet und Mobilgeräte in Deutschland .

    ReplyDelete
  25. Grateful to check out your website, I seem to be ahead to more excellent content and I believe we all really like to thank for so many excellent content, weblog to discuss with us Nimble Social CRM

    ReplyDelete
  26. Nice post, I bookmark your blog because I found very good information on your blog, Thanks for sharing more information Dynamic Web Development Services.

    ReplyDelete
  27. Hi, Am having this error.

    "java.lang.UnsupportedClassVersionError: org/eclipse/jetty/server/HandlerContainer : Unsupported major.minor version 52.0"

    Please can someone tell which JDK to use.

    Thanks.

    ReplyDelete
  28. Nice post, I bookmark your blog because I found very good information on your blog, Thanks for sharing more information Dynamic Web Development Company.

    ReplyDelete
  29. I just like the title of your post code like a boss. Logo Designs Company

    ReplyDelete
  30. A simple question, What is a website? In its bare form a website is a single domain that consists of different web pages. We should all know that by now, but surprisingly what we don’t all know, is the benefits a website can provide for your business and its shocking to witness how many business don’t actually have a website or online presence!
    A1 Digital Solutions

    ReplyDelete
  31. If quality web design company means,it should providing a quality services in all the development.

    Web Design Company in Delhi | Website Designing Company in Delhi

    ReplyDelete
  32. The blog was absolutely fantastic! Lot of great information which can be helpful in some or the other way. Keep updating the blog, looking forward for more contents...Great job, keep it up..
    Web Development Bangalore | Web Designing Company Bangalore

    ReplyDelete
  33. Programming is combination of intelligent and creative work. Programmers can do anything with code. The entire Programming tutorials that you mention here on this blog are awesome. Beginners Heap also provides latest tutorials of Programming from beginning to advance level.
    Be with us to learn programming in new and creative way.

    ReplyDelete
  34. Hi, is it possible to obtain the pom.xml ?

    So i have a strange error

    2016-08-09 20:08:15.593:INFO::main: Logging initialized @214ms
    2016-08-09 20:08:15.780:INFO:oejs.Server:main: jetty-9.3.11.v20160721
    2016-08-09 20:08:15.852:INFO:oejsh.ContextHandler:main: Started o.e.j.s.ServletContextHandler@5594a1b5{/,null,AVAILABLE}
    2016-08-09 20:08:15.877:INFO:oejs.AbstractConnector:main: Started ServerConnector@2812cbfa{HTTP/1.1,[http/1.1]}{0.0.0.0:9999}
    2016-08-09 20:08:15.877:INFO:oejs.Server:main: Started @502ms
    2016-08-09 20:08:22.544:WARN:oejs.ServletHandler:qtp1469821799-17: Error for /employee/getEmployee
    java.lang.NoSuchMethodError: com.sun.jersey.core.reflection.ReflectionHelper.classForNameWithExceptionPEA(Ljava/lang/String;)Ljava/security/PrivilegedExceptionAction;
    at com.sun.jersey.spi.container.servlet.WebComponent.createResourceConfig(WebComponent.java:707)
    at com.sun.jersey.spi.container.servlet.WebComponent.createResourceConfig(WebComponent.java:674)
    at com.sun.jersey.spi.container.servlet.WebComponent.init(WebComponent.java:205)
    at com.sun.jersey.spi.container.servlet.ServletContainer.init(ServletContainer.java:394)
    at com.sun.jersey.spi.container.servlet.ServletContainer.init(ServletContainer.java:577)
    at javax.servlet.GenericServlet.init(GenericServlet.java:244)
    at org.eclipse.jetty.servlet.ServletHolder.initServlet(ServletHolder.java:640)
    at org.eclipse.jetty.servlet.ServletHolder.getServlet(ServletHolder.java:496)
    at org.eclipse.jetty.servlet.ServletHolder.ensureInstance(ServletHolder.java:788)
    at org.eclipse.jetty.servlet.ServletHolder.prepare(ServletHolder.java:773)
    at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:578)
    at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:224)
    at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1180)
    at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:511)
    at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:185)
    at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1112)
    at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:141)
    at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:134)
    at org.eclipse.jetty.server.Server.handle(Server.java:524)
    at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:319)
    at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:253)
    at org.eclipse.jetty.io.AbstractConnection$ReadCallback.succeeded(AbstractConnection.java:273)
    at org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:95)
    at org.eclipse.jetty.io.SelectChannelEndPoint$2.run(SelectChannelEndPoint.java:93)
    at org.eclipse.jetty.util.thread.strategy.ExecuteProduceConsume.executeProduceConsume(ExecuteProduceConsume.java:303)
    at org.eclipse.jetty.util.thread.strategy.ExecuteProduceConsume.produceConsume(ExecuteProduceConsume.java:148)
    at org.eclipse.jetty.util.thread.strategy.ExecuteProduceConsume.run(ExecuteProduceConsume.java:136)
    at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:671)
    at org.eclipse.jetty.util.thread.QueuedThreadPool$2.run(QueuedThreadPool.java:589)
    at java.lang.Thread.run(Thread.java:745)

    ReplyDelete
    Replies
    1. [INFO] --- maven-dependency-plugin:2.8:tree (default-cli) @ TestRest ---
      [INFO] TestRest:TestRest:jar:1.0-SNAPSHOT
      [INFO] +- javax.servlet:javax.servlet-api:jar:3.1.0:compile
      [INFO] +- org.eclipse.jetty:jetty-server:jar:9.3.11.v20160721:compile
      [INFO] | +- org.eclipse.jetty:jetty-http:jar:9.3.11.v20160721:compile
      [INFO] | | \- org.eclipse.jetty:jetty-util:jar:9.3.11.v20160721:compile
      [INFO] | \- org.eclipse.jetty:jetty-io:jar:9.3.11.v20160721:compile
      [INFO] +- org.eclipse.jetty:jetty-servlet:jar:9.3.11.v20160721:compile
      [INFO] | \- org.eclipse.jetty:jetty-security:jar:9.3.11.v20160721:compile
      [INFO] +- com.sun.jersey:jersey-servlet:jar:1.17.1:compile
      [INFO] | \- com.sun.jersey:jersey-server:jar:1.17.1:compile
      [INFO] | \- asm:asm:jar:3.1:compile
      [INFO] +- org.glassfish.jersey.core:jersey-client:jar:2.23.1:compile
      [INFO] | +- javax.ws.rs:javax.ws.rs-api:jar:2.0.1:compile
      [INFO] | +- org.glassfish.jersey.core:jersey-common:jar:2.23.1:compile
      [INFO] | | +- javax.annotation:javax.annotation-api:jar:1.2:compile
      [INFO] | | +- org.glassfish.jersey.bundles.repackaged:jersey-guava:jar:2.23.1:compile
      [INFO] | | \- org.glassfish.hk2:osgi-resource-locator:jar:1.0.1:compile
      [INFO] | +- org.glassfish.hk2:hk2-api:jar:2.4.0-b34:compile
      [INFO] | | +- org.glassfish.hk2:hk2-utils:jar:2.4.0-b34:compile
      [INFO] | | \- org.glassfish.hk2.external:aopalliance-repackaged:jar:2.4.0-b34:compile
      [INFO] | +- org.glassfish.hk2.external:javax.inject:jar:2.4.0-b34:compile
      [INFO] | \- org.glassfish.hk2:hk2-locator:jar:2.4.0-b34:compile
      [INFO] | \- org.javassist:javassist:jar:3.18.1-GA:compile
      [INFO] \- com.sun.jersey:jersey-client:jar:1.17:compile
      [INFO] \- com.sun.jersey:jersey-core:jar:1.17:compile

      Delete
  35. This comment has been removed by the author.

    ReplyDelete
  36. Great Work. This post is worth everyone’s attention. web design company in chennai

    ReplyDelete
  37. This is a wonderfully written and helpful article, And this was a long guide. So I appreciate you taking the time to check it out!
    Website Design Company Nagpur

    ReplyDelete
  38. Great Work. This post is worth everyone’s attention.http://www.aqtsoft.com/

    ReplyDelete
  39. Informative article, just what I was looking for.seo services chennai

    ReplyDelete
  40. I am reading your post from the beginning, it was so interesting to read & I feel thanks to you for posting such a good blog, keep updates regularly.

    web hosting company in lucknow | Website designing Company in Lucknow | Domain Registration Service in lucknow | it Company in lucknow

    ReplyDelete
  41. Thanks for your post? But can I ask one question: what is the relationship between Jetty and Jersey? Thanks a lot

    ReplyDelete
  42. Can truly relate and retain this outstanding post. Very well written. web design company Chennai

    ReplyDelete
  43. helpdesk management system is a wonderful way to get help for external resources. The team offered by us are amazing in help desk management and offer the best to satisfy the clients.

    ReplyDelete
  44. Great post! I am actually getting ready to across this information, It's very helpful for this blog.Also great with all of the valuable information you have Keep up the good work you are doing well.
    Embedded Training in Chennai

    ReplyDelete


  45. Hai Author, Very Good informative blog post,
    Thanks for Sharing

    ReplyDelete