Package ej.rest.web

Class Resty

  • Direct Known Subclasses:
    AbstractResource

    public class Resty
    extends Object
    Main class. Use me! Use me! Resty is a small, convenient interface to talk to RESTful services. Basic usage is very simple: Create a Resty instance, use authenticate methode to add credentials (optional), then call one of the content type specific methods, like json(...), xml(...), text(...) or bytes(...). The idea is that the method name will convey the expected content type you can then operate on. Most static methods help you build content objects or queries with a compact syntax. Static methods like put(...) and delete() are used to implement the respective HTTP methods. A neat trick to save you typing is to use
     import static us.monoid.web.Resty.*;
     

    GETting an URL (as JSON):

     new Resty().json(url);
     
    POSTing to an URL (using multipart/form-data) and expecting JSON back:
     new Resty().json(url, form(data("name", "Don Draper"), data("occupation", "Ad Man")));
     
    PUTting content and expecting JSON back:
     
     new Resty().json(url, put(content(someJSON)));
     
     
    DELETE a resource via URL expecting JSON back:
     new Resty().json(url, delete());
     
    Here is an example on how to use the geonames web service. It retrieves the json object (see json.org for details) and gets the name of a place from the zip code:
     
            Resty r = new Resty();
            Object name = r.json("http://ws.geonames.org/postalCodeLookupJSON?postalcode=66780&country=DE").get("postalcodes[0].placeName");
            assertEquals(name, "Rehlingen-Siersburg");
     
     
    The return value is a resource with the data you requested AND a new Resty instance with the same set of options you initialized Resty with. Resty supports complex path queries to navigate into a json object. This is mainly used for extracting URIs to surf along a series of REST resources for web services following the HATEOS paradigm. Resty objects are not re-entrant. You can also specify options when creating a Resty instance. Well, currently there is one option to set the timeout for connections. But you can also create your own options! See Resty.Option for more info.
    • Field Detail

      • MOZILLA

        protected static String MOZILLA
      • DEFAULT_USER_AGENT

        protected static String DEFAULT_USER_AGENT
      • userAgent

        protected String userAgent
    • Constructor Detail

      • Resty

        public Resty​(Resty.Option... someOptions)
        Create an instance of Resty with the following list of options. Also, options are carried over to resources created by calls to json/text/binary etc. Use setOptions(Option...) to change options afterwards.
    • Method Detail

      • setOptions

        public Resty setOptions​(Resty.Option... someOptions)
        Set options if you missed your opportunity in the c'tor or if you want to change the options.
        Parameters:
        someOptions - new set of options
        Returns:
      • identifyAsMozilla

        public Resty identifyAsMozilla()
        Sets the User-Agent to identify as Mozilla/Firefox. Otherwise a Resty specific User-Agent is used
      • identifyAsResty

        public Resty identifyAsResty()
        Sets the User-Agent to Resty. WHICH IS THE DEFAULT. Sorry for yelling.
      • json

        public JSONResource json​(URI anUri)
                          throws IOException
        GET a URI and parse the result as JSON.
        Parameters:
        anUri - the URI to request
        Returns:
        the JSONObject, wrapped in a neat JSONResource
        Throws:
        IOException
      • createJSONResource

        protected JSONResource createJSONResource()
      • json

        public JSONResource json​(URI anUri,
                                 AbstractContent requestContent)
                          throws IOException
        POST to a URI and parse the result as JSON
        Parameters:
        anUri - the URI to visit
        requestContent - the content to POST to the URI
        Returns:
        Throws:
        IOException - if uri is wrong or no connection could be made or for 10 zillion other reasons
      • text

        public TextResource text​(URI anUri)
                          throws IOException
        Get a plain text resource for the specified URI.
        Parameters:
        anUri - the URI to follow
        Returns:
        a plain text resource, if available
        Throws:
        IOException - if content type sent is not a plain text, if the connection could not be made and gazillion other reasons
      • createTextResource

        protected TextResource createTextResource()
      • text

        public TextResource text​(URI anUri,
                                 AbstractContent content)
                          throws IOException
        Get a plain text resource for the specified URI by POSTing to it.
        Parameters:
        anUri - the URI to follow
        Returns:
        a plain text resource, if available
        Throws:
        IOException - if content type sent is not a plain text, if the connection could not be made and gazillion other reasons
      • text

        public TextResource text​(String anUri)
                          throws IOException
        Get a plain text resource for the specified URI.
        Parameters:
        anUri - the URI to follow
        Returns:
        a plain text resource, if available
        Throws:
        IOException - if content type sent is not a plain text, if the connection could not be made and gazillion other reasons
      • text

        public TextResource text​(String anUri,
                                 AbstractContent content)
                          throws IOException
        Get a plain text resource for the specified URI by POSTing to it.
        Parameters:
        anUri - the URI to follow
        Returns:
        a plain text resource, if available
        Throws:
        IOException - if content type sent is not a plain text, if the connection could not be made and gazillion other reasons
      • bytes

        public BinaryResource bytes​(String anUri)
                             throws IOException
        Get the resource specified by the uri and return a binary resource for it.
        Parameters:
        anUri - the uri to follow
        Returns:
        Throws:
        IOException
      • bytes

        public BinaryResource bytes​(URI anUri)
                             throws IOException
        Get the resource specified by the uri and return a binary resource for it.
        Parameters:
        anUri - the uri to follow
        Returns:
        Throws:
        IOException
      • createBinaryResource

        protected BinaryResource createBinaryResource()
      • addAdditionalHeaders

        protected void addAdditionalHeaders​(URLConnection con)
        Add all headers that have been set with the alwaysSend call.
      • addStandardHeaders

        protected <T extends AbstractResource> void addStandardHeaders​(URLConnection con,
                                                                       T resource)
        Add all standard headers (User-Agent, Accept) to the URLConnection.
      • fillResourceFromURL

        protected <T extends AbstractResource> T fillResourceFromURL​(URLConnection con,
                                                                     T resource)
                                                              throws IOException
        Get the content from the URLConnection, create a Resource representing the content and carry over some metadata like HTTP Result and location header. <T extends AbstractResource> the resource that will be created and filled.
        Parameters:
        con - the URLConnection used to get the data
        resource - the resource class to instantiate
        Returns:
        the new resource
        Throws:
        IOException
      • path

        public static JSONPathQuery path​(String string)
        Create a JSONPathQuery to extract data from a JSON object. This is usually used to extract a URI and use it in json|text|xml(JSONPathQuery...) methods of JSONResource. Resty r = new Resty(); r.json(someUrl).json(path("path.to.url.in.json"));
        Parameters:
        string -
        Returns:
      • content

        public static Content content​(JSONObject someJson)
        Create a content object from a JSON object. Use this to POST the content to a URL.
        Parameters:
        someJson - the JSON object to use
        Returns:
        the content to send
      • content

        public static Content content​(JSONArray someJson)
        Create a content object from a JSON array. Use this to POST the content to a URL.
        Parameters:
        someJson - the JSON array to use
        Returns:
        the content to send
      • content

        public static Content content​(String somePlainText)
        Create a content object from plain text. Use this to POST the content to a URL.
        Parameters:
        somePlainText - the plain text to send
        Returns:
        the content to send
      • content

        public static Content content​(byte[] bytes)
        Create a content object from a byte array. Use this to POST the content to a URL with mime type application/octet-stream.
        Parameters:
        bytes - the bytes to send
        Returns:
        the content to send
      • form

        public static FormContent form​(String query)
        Create form content as application/x-www-form-urlencoded (i.e. a=b&c=d&...)
        Parameters:
        query - the preformatted, properly encoded form data
        Returns:
        a content object to be useable for upload
      • form

        public static MultipartContent form​(FormData... formData)
        Create form content to be sent as multipart/form-data. Useful if you want to upload files or have tons of form data that looks really ugly in a URL.
      • data

        public static FormData data​(String name,
                                    String plainTextValue)
        Create a plain/text form data entry for a multipart form.
        Parameters:
        name - the name of the control of the form
        plainTextValue - the plain text value
        Returns:
        the FormData part used in a multipart/form-data upload
      • data

        public static FormData data​(String name,
                                    AbstractContent content)
        Create a form data entry for a multipart form with any kind of content type.
        Parameters:
        name - the name of the control or variable in a form
        content - the content to send
        Returns:
      • chunked

        public static ChunkedContent chunked​(String mime,
                                             InputStream stream)
        Create chunked data
        Parameters:
        mime - mime type
        stream - stream to read content from
        Returns:
      • chunked

        public static ChunkedContent chunked​(String mime,
                                             InputStream stream,
                                             int chunkSize)
        Create chunked data
        Parameters:
        mime - the mime
        stream - the stream
        chunkSize - the chunk size used to configure HttpURLConnection streaming mode
        Returns:
        the chunked content
      • put

        public static AbstractContent put​(Content someContent)
        Tell Resty to replace the specified content on the server, resulting in a PUT operation instead of a POST operation. Example use: r.json(uri, put(content("bubu")));
      • delete

        public static AbstractContent delete()
        Tell Resty to delete the URL content on the server, resulting in a DELETE. Example use: r.json(uri,delete());
      • withHeader

        public void withHeader​(String aHeader,
                               String aValue)
        Tell Resty to send the specified header with each request done on this instance. These headers will also be sent from any resource object returned by this instance. I.e. chained calls will carry over the headers r.json(url).json(get("some.path.to.a.url")); Multiple headers of the same type are not supported (yet).
        Parameters:
        aHeader - the header to send
        aValue - the value
      • dontSend

        public void dontSend​(String aHeader)
        Don't send a header that was formely added in the alwaysSend method.
        Parameters:
        aHeader - the header to remove
      • getAdditionalHeaders

        protected Map<String,​String> getAdditionalHeaders()