RESTful web service is very popular today. With supporting from a lot of frameworks such as: Spring Data Rest, Jersey, JBoss Resteasy, developing a RESTful web service is pretty easy for Java developer. Consuming a RESTful service from client side technologies like Javascript, JQuery is pretty easy too; however, there are some cases which we have to call a RESTful service from our Java source code. It’s simple; however, searching on the Internet gives us a lot of examples implemented by different frameworks, and they requires a lot of dependencies of course. In this post, I’d like to show several examples how to implement Java REST client using java.net.URL package. This package was consisted in the JDK, and we don’t need to include any other dependencies on the classpath.
1. Preparation
Assume that we have an RESTful web services with several API as below:
1.1. List all books
1 |
GET http://localhost:8080/v1/books |
1.2. Create a new book
1 |
POST http://localhost:8080/v1/books |
Example:
1 2 3 4 |
{ "name": "Java How To Program", "author": "Paul Deitel" } |
Responses
STATUS 201 if the book is created successfully.
1.3. Source code
The sample source code presented in this tutorial is available on my Github project.
Regarding the dependencies, we will use two Jackson libraries:
1 2 3 4 5 6 7 8 9 10 11 12 |
<dependencies> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>2.7.5</version> </dependency> <dependency> <groupId>com.fasterxml.jackson.dataformat</groupId> <artifactId>jackson-dataformat-xml</artifactId> <version>2.6.3</version> </dependency> </dependencies> |
The first one is used for JSON and the second one is used for XML.
2. Create Java REST client using java.net.URL package
2.1. Make a GET request to the RESTful web service.
We will get the list of books from the first API.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
public static void main(String arg[]) { HttpURLConnection connection = null; BufferedReader reader = null; String retVal = null; try { URL resetEndpoint = new URL("http://localhost:8080/v1/books"); connection = (HttpURLConnection) resetEndpoint.openConnection(); //Set request method to GET as required from the API connection.setRequestMethod("GET"); // Read the response reader = new BufferedReader(new InputStreamReader(connection.getInputStream())); StringBuilder jsonSb = new StringBuilder(); String line = null; while ((line = reader.readLine()) != null) { jsonSb.append(line); } retVal = jsonSb.toString(); // print out the json response System.out.println(retVal); } catch (Exception e) { e.printStackTrace(); } finally { // Clean up if (reader != null) { try { reader.close(); } catch (IOException e) { e.printStackTrace(); } } if (connection != null) { connection.disconnect(); } } } |
The output from console is an array of book in JSON format.
1 |
[{"id":1,"name":"Java How To Program","author":"Paul Deitel"},{"id":2,"name":"Thinking in Java","author":"Bruce Eckel"}] |
2.2. Make a POST request to the RESTful web service.
We will create a new book using the second API.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
public static void main(String args[]) { try { URL url = new URL("http://localhost:8080/v1/books"); HttpURLConnection con = (HttpURLConnection) url.openConnection(); //Set the request method to POST as required from the API con.setRequestMethod("POST"); // Set the Content-Type to "application/json" as required from the API con.setRequestProperty("Content-Type", "application/json"); con.setDoOutput(true); OutputStream os = con.getOutputStream(); //The book we want to create in JSON format String book = "{\"name\":\"Effective Java\",\"author\":\"Joshua Bloch\"}"; os.write(book.getBytes()); os.flush(); os.close(); int responseCode = con.getResponseCode(); System.out.println("Response Code :" + responseCode); if (responseCode == HttpURLConnection.HTTP_CREATED) { System.out.println("Created book successfully."); } else { System.out.println("Created book failed."); } } catch (Exception e) { e.printStackTrace(); } } |
The console output is:
1 2 |
Response Code :201 Created book successfully. |
2.3. Make a POST request with XML Content-Type to the RESTful web service.
Here is an example about how to make a POST request with XML Content-Type to the RESTful web service.
We assume that the above RESTful API support the Content-Type XML. The source code is almost the same with posting the JSON Content-Type. We just need to set the property Content-Type of the connection object to “application/xml” and replace the JSON content by XML content.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
public static void main(String arg[]) { try { URL url = new URL("http://localhost:8080/v1/books"); HttpURLConnection con = (HttpURLConnection) url.openConnection(); // Set the request method to POST as required from the API con.setRequestMethod("POST"); // Set the Content-Type to "application/xml" as required from the API con.setRequestProperty("Content-Type", "application/xml"); con.setDoOutput(true); OutputStream os = con.getOutputStream(); // The book we want to create in XML format String book = "<book><name>Effective Java</name><author>Joshua Bloch</author></book>"; os.write(book.getBytes()); os.flush(); os.close(); int responseCode = con.getResponseCode(); System.out.println("Response Code :" + responseCode); if (responseCode == HttpURLConnection.HTTP_CREATED) { System.out.println("Created book successfully."); } else { System.out.println("Created book failed."); } } catch (Exception e) { e.printStackTrace(); } } |
The console output is:
1 2 |
Response Code :201 Created book successfully. |
3. Improvements
We have seen some examples about Java REST client using java.net.URL package. Those examples are very basic and suitable for applications that need to make several calls to the a RESTful web service for notification purpose or trigger a remote action. If we need more interactions between our application and other RESTful web services, these ways may be not productive and efficiency. One reason we can see on above examples is how to convert our objects to JSON and XML strings to post them to the RESTful services.
We can improve this by using some libraries which will support us in automating the conversion back and forward such as: Jackson, Google Json, Json Lib. You can reference my previous post for more detail: Convert Java Objects To JSON And Vice Versa
So, we will try to improve our above examples by using Jackson library. We first need an Book class which its instances will be converted to JSON/XML and vice versa.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
@JacksonXmlRootElement(localName = "book") public class Book { private Long id; private String name; private String author; public Book() { super(); } public Book(Long id, String name, String author) { super(); this.id = id; this.name = name; this.author = author; } @Override public String toString() { return "Book [id=" + id + ", name=" + name + ", author=" + author + "]"; } //All Getters, Setters here } |
3.1. Make a GET request to the RESTful web service.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
public static void main(String arg[]) { HttpURLConnection connection = null; BufferedReader reader = null; String json = null; try { URL resetEndpoint = new URL("http://localhost:8080/v1/books"); connection = (HttpURLConnection) resetEndpoint.openConnection(); // Set request method to GET as required from the API connection.setRequestMethod("GET"); // Read the response reader = new BufferedReader(new InputStreamReader(connection.getInputStream())); StringBuilder jsonSb = new StringBuilder(); String line = null; while ((line = reader.readLine()) != null) { jsonSb.append(line); } json = jsonSb.toString(); // Converts JSON string to Java object ObjectMapper mapper = new ObjectMapper(); // Converts to an array of Book Book[] books = mapper.readValue(json, Book[].class); for (Book book : books) { System.out.println(book); } } catch (Exception e) { e.printStackTrace(); } } |
The source code for getting the list of books from the RESTful API is the same with the first example. After getting the JSON response from the RESTful API, we create a new ObjectMapper and convert the response to an array of book.
The output in the console is as below. Note that we already generated the toString() method of the Book class.
1 2 |
Book [id=1, name=Java How To Program, author=Paul Deitel] Book [id=2, name=Thinking in Java, author=Bruce Eckel] |
3.2. Make a POST request to the RESTful web service.
The source code is almost the same with the 2nd example above. In this example, instead of creating a JSON string, we create an Book object. Converting the object to byte array is responsibility of the ObjectMapper. It will be more efficiency.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
try { URL url = new URL("http://localhost:8080/v1/books"); HttpURLConnection con = (HttpURLConnection) url.openConnection(); // Set the request method to POST as required from the API con.setRequestMethod("POST"); // Set the Content-Type to "application/json" as required from the API con.setRequestProperty("Content-Type", "application/json"); con.setDoOutput(true); OutputStream os = con.getOutputStream(); // The book we want to create in JSON format // String book = "{\"name\":\"Effective Java\",\"author\":\"Joshua Bloch\"}"; // Creates new Book instance Book book = new Book(null, "Effective Java", "Joshua Bloch"); // Convert Book object to byte array ObjectMapper mapper = new ObjectMapper(); os.write(mapper.writeValueAsBytes(book)); os.flush(); os.close(); int responseCode = con.getResponseCode(); System.out.println("Response Code :" + responseCode); if (responseCode == HttpURLConnection.HTTP_CREATED) { System.out.println("Created book successfully."); } else { System.out.println("Created book failed."); } } catch (Exception e) { e.printStackTrace(); } |
3.3. Make a POST request with XML Content-Type to the RESTful web service.
In this example, we also use the jackson-dataformat-xml package to convert the Java object to XML. In stead of creating an XML string, we create an instance of Book and use the XMLMapper object to convert the book to XML.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 |
public static void main(String arg[]) { try { URL url = new URL("http://localhost:8080/v1/books"); HttpURLConnection con = (HttpURLConnection) url.openConnection(); // Set the request method to POST as required from the API con.setRequestMethod("POST"); // Set the Content-Type to "application/xml" as required from the API con.setRequestProperty("Content-Type", "application/xml"); con.setDoOutput(true); OutputStream os = con.getOutputStream(); // The book we want to create in JSON format // String book = "<book><name>Effective Java</name><author>Joshua Bloch</author></book>"; // Creates new Book instance Book book = new Book(null, "Effective Java", "Joshua Bloch"); JacksonXmlModule module = new JacksonXmlModule(); // and then configure, for example: module.setDefaultUseWrapper(false); XmlMapper xmlMapper = new XmlMapper(module); System.out.println(xmlMapper.writeValueAsString(book)); os.write(xmlMapper.writeValueAsBytes(book)); os.flush(); os.close(); int responseCode = con.getResponseCode(); System.out.println("Response Code :" + responseCode); if (responseCode == HttpURLConnection.HTTP_CREATED) { System.out.println("Created book successfully."); } else { System.out.println("Created book failed."); } } catch (Exception e) { e.printStackTrace(); } } |
The output at client side is:
1 2 3 |
<book xmlns=""><id/><name>Effective Java</name><author>Joshua Bloch</author></book> Response Code :201 Created book successfully. |
4. Conclusion
We have seen some examples about implementing Java REST client using java.net.URL package of the JDK. This method is very simple, suitable for several calls to RESTful web services and requires no other dependencies in our classpath. There are some better libraries such as: SpringTemplate, Jersey client,etc, and I’d like to mention in the following posts:
Java REST Client Using Netflix Feign
Java REST Client Using Apache CXF Proxy based API
Java REST Client Using Resteasy Client Proxy Framework
Java REST Client Using Resteasy Client
Java REST Client Using Spring RestTemplate
Java REST Client Using Apache HttpClient
Java REST Client Using Jersey Client