Get json from spring REST webservice using jquery

Exposing JSON from a spring controller is surprisingly simple. In this episode I will create a controller that returns JSON and make a GET request from a client side template using jquery.

Detailed Video Notes

One of the first exercises you encounter while exploring services is how to get JSON from a REST endpoint. There is a variety of client side JavaScript frameworks such as angularjs, backbone and jquery that allow you to do this from a webpage. If your focus is on backend development postman and advanced rest client are popular chrome extensions while rest-shell is a command line interface for interacting with REST applications. In this tutorial lets walk through exposing an endpoint that returns a list of JSON representing contacts and using the popular jquery library to make the request. Once you made it through this tutorial the next step is learning how to post json to a spring controller.

Project set up

[0:33]

Following our spring boot tutorial let us create a project using spring initializer web interface, selecting spring web and velocity as template engine. Lets start off by creating a Contact and ContactController class. The controller is annotated with @RestController which is a convenience annotation that combines the @Controller and @ResponseBody

Contact

public class Contact {

    private String name;
    private String telephone;
    private String emailAddress;

    //...
}

ContactController

@RestController
public class ContactController {
}

Creating endpoint

[0:53]

Next creating a @RequestMapping will expose an endpoint of /contacts that will return JSON. We included additional meta data of produces and method which is a good practice that will allow spring to narrow down the mappings of the request. In other words, when DispatcherServlet accepts a request it will look at information in the request to determine where to route it. This would read, when a request is made to the application with an HTTP method of GET, a url of /contacts and wanting JSON then spring will execute the getContacts method. We will write a method to mock up some data but it could be substituted to connect to a database or a microservice. Firing up our server and making a request to http://localhost:8080/contacts will convert the contacts arraylist to a jsonarray.

@RequestMapping(value="/contacts", produces = {
        MediaType.APPLICATION_JSON_VALUE},
        method = RequestMethod.GET)
public ResponseEntity<List<Contact>> getContacts () {

    List<Contact> contacts = getDummyContacts ();

    return new ResponseEntity<List<Contact>>(contacts, HttpStatus.OK);
}

public List<Contact> getDummyContacts () {

    Contact contact1 = new Contact("Joe", "202-555-0105", "[email protected]");
    Contact contact2 = new Contact("Jenny", "515-876-5309", "[email protected]");
    Contact contact3 = new Contact("Brit", "515-555-0127", "[email protected]");

    List<Contact> contacts = new ArrayList<>();
    contacts.add(contact1);
    contacts.add(contact2);
    contacts.add(contact3);

    return contacts;
}
[
   {
      "name":"Joe",
      "telephone":"202-555-0105",
      "emailAddress":"[email protected]"
   },
   {
      "name":"Jenny",
      "telephone":"515-876-5309",
      "emailAddress":"[email protected]"
   },
   {
      "name":"Brit",
      "telephone":"515-555-0127",
      "emailAddress":"[email protected]"
   }
]

Rendering template

[1:35]

Once we have the REST URL returning JSON we need to create the template and render the view. Since ContactController is annotated with @RestController it will by pass processing the template and return the string directly to the response. We can fix this by either adding a new controller or changing the @RestController to a @Controller and adding the @ResponseBody to the method we want to process JSON. For this example lets change @RestController to @Controller and add the @ResponseBody.

Adding mapping for template

We will then add the mapping that will resolve the template.

@RequestMapping(value="/view", produces = {
        MediaType.TEXT_HTML_VALUE},
        method = RequestMethod.GET)
public String viewContacts () {
    return "contact-listing";
}

Creating the template

Lets run through the template at a high level. Binding a click event to the button and upon the event firing will execute the jquery get, a wrapper method for jquery ajax, that will getjson from /contacts end point on our local server. Each contact returned from the successful response will be appended as a row to the tables with a class of data-contacts-js. Finally importing bootstrap css and adding classes will add some presentation eye candy.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Level Up Lunch - Contact Listing</title>

    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.1/css/bootstrap.min.css"></head>
<body>

    <h2>Contact Listing</h2>

    <table class="data-contacts-js table table-striped" >
        <tr>
            <th>Name</th>
            <th>Telephone</th>
            <th>Email</th>
        </th>
    </table>

    <button id="fetchContacts" class="btn btn-default" type="submit">Button</button>

    <script src="http://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
    <script type="text/javascript">

        $("#fetchContacts").bind("click", function() {

            $.get("http://localhost:8080/contacts", function(data) {

                $.each(data, function(i, contact) {

                    $(".data-contacts-js").append(
                        "<tr><td>" + contact.name + "</td>" +
                        "<td>" + contact.telephone + "</td>" +
                        "<td>" + contact.emailAddress + "</td></tr>");
                });

            });
        });
    </script>
</body>
</html>

Making the GET request

[2:30]

Opening up chrome and developer tools console to inspect the network traffic we will making a request to http://localhost:8080/view which will render the template successfully. Next clicking on the button will fire a request to our local server populating our table.

Thanks for joining in todays level up, have a great day.