How do you create a REST client for Java?

544

Solution 1

This is an old question (2008) so there are many more options now than there were then:

UPDATES (projects still active in 2020):

  • Apache HTTP Components (4.2) Fluent adapter - Basic replacement for JDK, used by several other candidates in this list. Better than old Commons HTTP Client 3 and easier to use for building your own REST client. You'll have to use something like Jackson for JSON parsing support and you can use HTTP components URIBuilder to construct resource URIs similar to Jersey/JAX-RS Rest client. HTTP components also supports NIO but I doubt you will get better performance than BIO given the short requestnature of REST. Apache HttpComponents 5 has HTTP/2 support.
  • OkHttp - Basic replacement for JDK, similar to http components, used by several other candidates in this list. Supports newer HTTP protocols (SPDY and HTTP2). Works on Android. Unfortunately it does not offer a true reactor-loop based async option (see Ning and HTTP components above). However if you use the newer HTTP2 protocol this is less of a problem (assuming connection count is problem).
  • Ning Async-http-client - provides NIO support. Previously known as Async-http-client by Sonatype.
  • Feign wrapper for lower level http clients (okhttp, apache httpcomponents). Auto-creates clients based on interface stubs similar to some Jersey and CXF extensions. Strong spring integration.
  • Retrofit - wrapper for lower level http clients (okhttp). Auto-creates clients based on interface stubs similar to some Jersey and CXF extensions.
  • Volley wrapper for jdk http client, by google
  • google-http wrapper for jdk http client, or apache httpcomponents, by google
  • Unirest wrapper for jdk http client, by kong
  • Resteasy JakartaEE wrapper for jdk http client, by jboss, part of jboss framework
  • jcabi-http wrapper for apache httpcomponents, part of jcabi collection
  • restlet wrapper for apache httpcomponents, part of restlet framework
  • rest-assured wrapper with asserts for easy testing

A caveat on picking HTTP/REST clients. Make sure to check what your framework stack is using for an HTTP client, how it does threading, and ideally use the same client if it offers one. That is if your using something like Vert.x or Play you may want to try to use its backing client to participate in whatever bus or reactor loop the framework provides... otherwise be prepared for possibly interesting threading issues.

Solution 2

As I mentioned in this thread I tend to use Jersey which implements JAX-RS and comes with a nice REST client. The nice thing is if you implement your RESTful resources using JAX-RS then the Jersey client can reuse the entity providers such as for JAXB/XML/JSON/Atom and so forth - so you can reuse the same objects on the server side as you use on the client side unit test.

For example here is a unit test case from the Apache Camel project which looks up XML payloads from a RESTful resource (using the JAXB object Endpoints). The resource(uri) method is defined in this base class which just uses the Jersey client API.

e.g.

    clientConfig = new DefaultClientConfig();
    client = Client.create(clientConfig);

    resource = client.resource("http://localhost:8080");
    // lets get the XML as a String
    String text = resource("foo").accept("application/xml").get(String.class);        

BTW I hope that future version of JAX-RS add a nice client side API along the lines of the one in Jersey

Solution 3

You can use the standard Java SE APIs:

private void updateCustomer(Customer customer) { 
    try { 
        URL url = new URL("http://www.example.com/customers"); 
        HttpURLConnection connection = (HttpURLConnection) url.openConnection(); 
        connection.setDoOutput(true); 
        connection.setInstanceFollowRedirects(false); 
        connection.setRequestMethod("PUT"); 
        connection.setRequestProperty("Content-Type", "application/xml"); 

        OutputStream os = connection.getOutputStream(); 
        jaxbContext.createMarshaller().marshal(customer, os); 
        os.flush(); 

        connection.getResponseCode(); 
        connection.disconnect(); 
    } catch(Exception e) { 
        throw new RuntimeException(e); 
    } 
} 

Or you can use the REST client APIs provided by JAX-RS implementations such as Jersey. These APIs are easier to use, but require additional jars on your class path.

WebResource resource = client.resource("http://www.example.com/customers"); 
ClientResponse response = resource.type("application/xml");).put(ClientResponse.class, "<customer>...</customer."); 
System.out.println(response); 

For more information see:

Solution 4

If you only wish to invoke a REST service and parse the response you can try out Rest Assured

// Make a GET request to "/lotto"
String json = get("/lotto").asString()
// Parse the JSON response
List<String> winnderIds = with(json).get("lotto.winners.winnerId");

// Make a POST request to "/shopping"
String xml = post("/shopping").andReturn().body().asString()
// Parse the XML
Node category = with(xml).get("shopping.category[0]");

Solution 5

You can also check Restlet which has full client-side capabilities, more REST oriented that lower-level libraries such as HttpURLConnection or Apache HTTP Client (which we can leverage as connectors).

Best regards, Jerome Louvel

Share:
544

Related videos on Youtube

user3309116
Author by

user3309116

Updated on March 09, 2020

Comments

  • user3309116
    user3309116 about 4 years

    I wish to change the appearance (background colour) of an item of a navigation menu item depending on the current page.

    Here is the HTML code I have for my navigation menu:

    <ul id="menu">
        <li><a href="#">Home</a></li>
        <li><a href="#">Services</a>
            <ul>
                <li><a href="#">Recruitment</a></li>
                <li><a href="#">Training & Development</a></li>
                <li><a href="#">Outsourcing</a></li>
            </ul>
        </li>
        <li><a href="#">About Us</a></li>
        <li><a href="#">Contact</a></li>
    </ul>
    

    Here is the CSS code I have for my navigation menu:

    #menu, #menu ul {
        margin: 0;
        padding: 0;
        list-style: none;
    }
    
    #menu {
        width: 960px;
        margin: 60px auto;
        border: 1px solid #222;
        background-color: #111;
        background-image: linear-gradient(#444, #111);
        border-radius: 6px;   
        box-shadow: 0 1px 1px #777;
    }
    
    #menu:before,
    #menu:after {
        content: "";
        display: table;
    }
    
    #menu:after {
        clear: both;
    }
    
    #menu {
        zoom:1;
    }
    
    #menu li {
        float: left;
    /*  border-right: 1px solid #222;
    */  
        box-shadow: 1px 0 0 #444;
        position: relative;
    }
    
    #menu a {
        float: left;
        padding: 12px 30px;
        color: #FFF;
        text-transform: uppercase;
        text-decoration: none;
        text-shadow: 0 1px 0 #000;
        font-family: Arial, Helvetica;
        font-size: 12px;
        font-weight: bold;
    }
    
    #menu li:hover > a {
        color: #fafafa;
    }
    
    *html #menu li a:hover { /* IE6 only */
        color: #fafafa;
    }
    
    #menu ul {
        margin: 20px 0 0 0;
        _margin: 0; /*IE6 only*/
        opacity: 0;
        visibility: hidden;
        position: absolute;
        top: 38px;
        left: 0;
        z-index: 1;    
        background: #444;   
        background: linear-gradient(#444, #111);
        box-shadow: 0 -1px 0 rgba(255,255,255,.3);  
        border-radius: 3px;
        transition: all .2s ease-in-out;  
    }
    
    #menu li:hover > ul {
        opacity: 1;
        visibility: visible;
        margin: 0;
    }
    
    #menu ul ul {
        top: 0;
        left: 150px;
        margin: 0 0 0 20px;
        _margin: 0; /*IE6 only*/
        box-shadow: -1px 0 0 rgba(255,255,255,.3);      
    }
    
    #menu ul li {
        float: none;
        display: block;
        border: 0;
        _line-height: 0; /*IE6 only*/
        box-shadow: 0 1px 0 #111, 0 2px 0 #666;
    }
    
    #menu ul li:last-child {   
        box-shadow: none;    
    }
    
    #menu ul a {    
        padding: 10px;
        width: 130px;
        _height: 10px; /*IE6 only*/
        display: block;
        white-space: nowrap;
        float: none;
        text-transform: none;
    }
    
    #menu ul a:hover {
        background-color: #f80033;
        background-image: linear-gradient(#f80033, #955d61);
    }
    
    #menu li:hover {
        border-radius:5px;
        background-color: #f80033;
        background-image: linear-gradient(#f80033, #955d61);
    }
    
    #menu ul li:first-child > a {
        border-radius: 3px 3px 0 0;
    }
    
    #menu ul li:first-child > a:after {
        content: '';
        position: absolute;
        left: 40px;
        top: -6px;
        border-left: 6px solid transparent;
        border-right: 6px solid transparent;
        border-bottom: 6px solid #444;
    }
    
    #menu ul ul li:first-child a:after {
        left: -6px;
        top: 50%;
        margin-top: -6px;
        border-left: 0; 
        border-bottom: 6px solid transparent;
        border-top: 6px solid transparent;
        border-right: 6px solid #3b3b3b;
    }
    
    #menu ul li:first-child a:hover:after {
        border-bottom-color: #f80033; 
    }
    
    #menu ul ul li:first-child a:hover:after {
        border-right-color: #ba4d5c; 
        border-bottom-color: transparent;   
    }
    
    #menu ul li:last-child > a {
        border-radius: 0 0 3px 3px;
    }
    
    • Yaba
      Yaba almost 15 years
      Just found Apache Wink in the Apache Incubator. Could be a interesting project for creating REST servers and clients.
    • ipolevoy
      ipolevoy over 13 years
    • neel
      neel almost 13 years
      Check out [Resting]( code.google.com/p/resting). It promises to invoke REST services and create list of objects from XML/JSON/YAML response in one step.
    • RyanBrady
      RyanBrady about 12 years
      Resting has issues with POST requests.
    • Guido
      Guido over 11 years
      You can do it in a very simple way with resteasy (by Jboss). I wrote a blog post about how to develop a Java REST client if you want a getting started guide. Anyway, there are hundreds of alternatives in Java.
    • pasquy73
      pasquy73 almost 11 years
      If you are interesting in Eclipse plugin to generate a java client class from WADL, you can see at link stackoverflow.com/questions/9159881/restful-client-from-wadl‌​/…
    • Richa
      Richa about 10 years
      its working perfect. whats the issue? jsfiddle.net/TNUG2
    • David Thomas
      David Thomas about 10 years
      You want to highlight the menu item linking to the current page? If so this is impossible without either server, or client, side scripting; CSS has (as yet) no concept of the page's location.
    • user3309116
      user3309116 about 10 years
      @Era i want active menu if i move to other page
    • Richa
      Richa about 10 years
      and you want to achieve this with css only ? as David said its not possible only with CSS. you need to include jquery for this.
    • user3309116
      user3309116 about 10 years
      @Era may i know how to do that help me
    • David Thomas
      David Thomas about 10 years
      @Era: no, jQuery's not necessary; php, ruby, asp.net and plain javascript (among many others) can achieve this.
    • Richa
      Richa about 10 years
      @DavidThomas : I am talking about quick and easiest way.
    • David Thomas
      David Thomas about 10 years
      I'm not convinced that jQuery's significantly easier or quicker than the alternatives but yes, it's an option.
    • Aditya
      Aditya almost 8 years
      please find my solution here: stackoverflow.com/a/38724942/6668328
    • RussellH
      RussellH over 3 years
      Why in the world would this be closed as "off topic"?
  • Adam Gent
    Adam Gent about 13 years
    In my opinion this is the worst way to do REST. Manually handling serialization in Java is a waste of time when you have so many options like JAXB and Jackson. Even loading the whole document and using XPath is marginally slower than SAX and nothing compared to getting the XML (network speed).
  • afternoon
    afternoon about 13 years
    Rapa has a really nice interface and few dependencies. A good alternative to RestSharp in the .NET world.
  • Njax3SmmM2x2a0Zf7Hpd
    Njax3SmmM2x2a0Zf7Hpd almost 12 years
    Is there a method where we can mention REST service server list in ClientResource, in case the server is down try the next server?
  • iPadDevloperJr
    iPadDevloperJr over 11 years
    Just an update, but to address James' 'BTW' comment, the new version of JAX-RS 2.0 will have a client-side API: infoq.com/presentations/Java-REST
  • JeeBee
    JeeBee over 10 years
    I agree too, and I wrote the original comment. Back then I had a desire for control of the deserialisation, but nowadays I would use Jackson and decently annotated model classes.
  • David Thomas
    David Thomas about 10 years
    When the new page loads the styling applied by .active Will be lost (assuming it's not a single-page site).
  • David Thomas
    David Thomas about 10 years
    Bear in mind that the attribute might contain only a relative URL, causing this approach to fail, it'd probably be best to select the relevant elements and then filter using the element.href property (for the full URL) to compare that against window.location.href. Mind you, both our approaches would fail given that the href of every link is, in the posted code, simply #.
  • balexandre
    balexandre about 10 years
    maybe you didn't understand... W3Schools have wrong information across all website! DO NOT use them! period.
  • aaron-bond
    aaron-bond about 10 years
    I removed the link in favor of a CSS-Tricks page. Not sure what else you want from me :P Also, W3Schools isn't the greatest learning tool, but as a quick-reference, I've found the answers I've been looking for more times than I can count from there. It's not all bad.
  • botchniaque
    botchniaque over 9 years
    Unfortunately Jersey client does not support PATCH method if used with JDK < 8
  • Dejell
    Dejell almost 9 years
    as well as Jersey client has some serious memory leaks java.net/jira/browse/JERSEY-2830
  • bekce
    bekce over 8 years
    Unirest is very easy to use but its static design makes it unusable in shared and server environments.
  • Heisenberg
    Heisenberg about 8 years
    Unirest is easier but slower as compared to apache HttpClient.
  • dnault
    dnault almost 8 years
    Here's another new one: Netflix/feign
  • wegenmic
    wegenmic over 7 years
    Regarding the unirest comment, I would like to add that it currently (end of 2016) looks as if this project is no longer maintained. There is even an issue open that asks for a new maintainer.
  • Tim
    Tim about 7 years
    Just want to add about NIO and doubts about its performance improvement: as always it depends on how we use the target REST API. Indeed, NIO benefits servers a lot because they handle a lot of requests in parallel. And indeed, for clients, there will be few benefit for short single REST calls. However, same as for servers, NIO will also shine on a client when you issue many requests in parallel. For example, calling GMail API to download 10 messages will consume 10 "units of time" with blocking IO, or 1 "unit of time" with NIO. So, NIO can be very important, depending on your usage.
  • Chris Sim
    Chris Sim about 7 years
    @Adam Gent retrofit2 can be compared to jersey with Apache HTTP client ?? can retrofit2 be used to any java reas API (not android) and supports a high performance like jersey? Thank u
  • Saisurya Kattamuri
    Saisurya Kattamuri almost 7 years
    Netflix Feign is also a good alternative github.com/OpenFeign/feign
  • Clint Eastwood
    Clint Eastwood about 6 years
    13 lines for a simple rest call, in 2018, sounds like way too much...
  • Josh
    Josh about 6 years
    For those who like Unirest, I've got a fork of it that's currently being actively maintained / updated.
  • Sam
    Sam almost 6 years
    Jetty, Netty, HttpURLConnection in Java 8 and HttpClient in Java 9/10
  • Aryan Venkat
    Aryan Venkat over 5 years
    @Adam Gent Any information about which one of these rest clients is performant (over HTTPS) in terms of response time?
  • tekHedd
    tekHedd about 5 years
    Once you add error handling and options, it's not really significantly different. If the SE approach seems long, you can always wrap it in a class... :> After two days of debugging JAX-RS library conflicts I'm really fine with 5 extra lines of code to avoid the whole SPI nightmare.
  • Ilya Serbis
    Ilya Serbis about 5 years
    Unirest actively uses static configuration. Even cookies are saved as a static state (see stackoverflow.com/q/32442318/355438). That's why I strongly recommend NOT to use Unirest!
  • 0ddlyoko
    0ddlyoko about 5 years
    @ClintEastwood this post was wrote in 2010
  • Hans Deragon
    Hans Deragon over 4 years
    As of 2019-10-24, the link provided returns: 'Restlet Platform has reached end of life.'
  • tkruse
    tkruse about 4 years
    would be nice to turn the answer into a community wiki
  • tkruse
    tkruse about 4 years
    project looks dead
  • tkruse
    tkruse about 4 years
    Restfulie looks dead
  • tkruse
    tkruse about 4 years
    project looks dead, no commits since 2015.
  • Herve Mutombo
    Herve Mutombo almost 4 years
    I found this to be more elegant than many of the other proposed solutions.