Wilson Mar bio photo

Wilson Mar

Hello. Hire me!

Email me Calendar Skype call 310 320-7878

LinkedIn Twitter Gitter Google+ Youtube

Github Stackoverflow Pinterest

Spring for some Java web service client


Overview

This article introduces how Spring programs works by examining a simple Java Spring client program that calls a REST API (without authentication, GUI, or database).

This article describes the code while you take a hands-on approach where I introduce concepts after asking you to take an action, so that you have a visual image to go with my commentary.

If any of this doesn’t work for you or doesn’t make sense to you, please reach out to me.

  1. Click on the URL to a REST API written in Spring:

    https://gturnquist-quoters.cfapps.io/api/random

    The API is described at
    https://spring.io/guides/gs/consuming-rest

    The web service returns a JSON document containing a reponse type (“success” or “failure”), an id, and a text string (random quotes about Spring Boot).

    {"type":"success","value":{"id":10,"quote":"Really loving Spring Boot, makes stand alone Spring apps easy."}}
    

    The response is a raw (unformatted) string if you’re using a Google Chrome browser.

    If you are using a FireFox browser, you would see a formatted display such as:

    {
    type: "success",
    value: {
       id: 10,
       quote: "Really loving Spring Boot, makes stand alone Spring apps easy."
    }
    }
    

    Notice there are two levels in the above JSON file:

  2. If you’re using a Firefox browser, you would also see a tab to display HTTP headers it exchanges with servers behind the scenes.

    Sample Spring program source

  3. In an internet browser (Chrome or Firefox), go to:

    https://github.com/spring-guides/gs-consuming-rest

  4. Log into your own GitHub account.
  5. Click Fork because you’ll want to make changes and save it back to GitHub as backup if nothing else.

  6. Install on your laptop the Java Development Kit (JDK), Maven, and Git client software.
  7. Install Atom and Sublime Text for editing files. These are free tools. Commands in this tutorial used “atom” and “subl” to open text files for viewing and edit in context of its folder of other files.
  8. Install Eclipse STS IDE. Also free.

  9. Open a Terminal screen on your operating system (assuming Mac):
  10. Make a folder to hold the new folder to be added.
  11. Get the repository (substituting “spring-guides” with your own account name):

    git clone https://github.com/spring-guides/gs-consuming-rest.git --depth=1
    cd gs-consuming-rest

    NOTE: The account spring-guides is maintained by folks within Pivitol who maintain the spring.io website.

    Structure of folders

  12. View top level folders:

    cd gs-consuming-rest

    There are two folders: “initial” and “complete” so that this repo can be used for learning, with a completed set if changes were made correctly.

  13. View the folders

    cd completed

    Code for two build mechanisms are provided. Use either Maven or Gradle, not both.

    This tutorial makes use of Maven (although Gradle is a simpler, more modern tool).

    Maven to create target .jar

  14. Open to view the pom.xml file which tells the Maven program what artifacts and plugins to download from its Maven Central repository.

    (You can subsitute another editor than Atom)

    atom pom.xml

    <modelVersion>4.0.0</modelVersion> refers to the version of Maven.

    <groupId>org.springframework</groupId><br /> gs-consuming-rest` is used within Eclipse STS.

    java.version 1.8 is required by spring.framework specified as a dependency. (Others substitute a variable ${spring.version}, which is substituted automatically based on the value specified in the tag's content within the same file.)

    jackson provides methods to process JSON files.

    A full application would contain references to libraries to enable use of Tomcat, database, and others.

  15. Assemble all the various files necessary to run into a single .jar file within a target folder.

    On Windows:

    mvnw.cmd

    On Mac:

    chmod +x * ./mvnw

    Run .jar from command line

  16. Run the module (.jar file) created within the target folder:

    cd target
    java -jar gs-consuming-rest-0.1.0.jar

    DEFINITION: A module refers to the way that Java libraries are distributed and used - JAR, WAR, EAR. A .jar file contains all the other files assembled together.

    Although most other Spring apps have a UI, this sample program has only a “console” program with no UI.

    So we look to the console log messages to debug and see whether calls worked.

      .   ____          _            __ _ _
     /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
    ( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
     \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
      '  |____| .__|_| |_|_| |_\__, | / / / /
     =========|_|==============|___/=/_/_/_/
     :: Spring Boot ::        (v1.5.6.RELEASE)
     
    2017-07-30 15:02:46.236  INFO 27820 --- [           main] hello.Application                        : Starting Application v0.1.0 on macs-MacBook-Pro-4.local with PID 27820 (/Users/mac/gits/gs-consuming-rest/complete/target/gs-consuming-rest-0.1.0.jar started by mac in /Users/mac/gits/gs-consuming-rest/complete/target)
    2017-07-30 15:02:46.242  INFO 27820 --- [           main] hello.Application                        : No active profile set, falling back to default profiles: default
    2017-07-30 15:02:46.365  INFO 27820 --- [           main] s.c.a.AnnotationConfigApplicationContext : Refreshing org.springframework.context.annotation.AnnotationConfigApplicationContext@4b9af9a9: startup date [Sun Jul 30 15:02:46 EDT 2017]; root of context hierarchy
    2017-07-30 15:02:47.715  INFO 27820 --- [           main] o.s.j.e.a.AnnotationMBeanExporter        : Registering beans for JMX exposure on startup
    2017-07-30 15:02:48.031  INFO 27820 --- [           main] hello.Application                        : Quote{type='success', value=Value{id=7, quote='The real benefit of Boot, however, is that it's just Spring. That means any direction the code takes, regardless of complexity, I know it's a safe bet.'}}
    2017-07-30 15:02:48.035  INFO 27820 --- [           main] hello.Application                        : Started Application in 2.501 seconds (JVM running for 3.096)
    2017-07-30 15:02:48.035  INFO 27820 --- [       Thread-2] s.c.a.AnnotationConfigApplicationContext : Closing org.springframework.context.annotation.AnnotationConfigApplicationContext@4b9af9a9: startup date [Sun Jul 30 15:02:46 EDT 2017]; root of context hierarchy
    2017-07-30 15:02:48.037  INFO 27820 --- [       Thread-2] o.s.j.e.a.AnnotationMBeanExporter        : Unregistering JMX-exposed beans on shutdown
    

    PROTIP: Ignore the date/time stamps, markers, and warnings in the response. Scroll to the right.

    Notice “hello.Application” is called (even though “No active profile set”). NOTE: Spring Profiles provide a way to segregate parts of your application configuration and make it only available in certain environments.

    After “Registering beans for JMX exposure on startup” notice there is a valid response from the web service over the public internet.

    There is also
    Started Application in 2.501 seconds (JVM running for 3.096)

    Success!

    But how can the program know if the response was successful?

    Test Coding

  17. Look into the src (source) folder:

    cd src
    ls -al
    

    The src/test/java/hello folder contains an ApplicationTest.java file which exercises classes compiled from
    the src/main/java/hello folder.

  18. Use a text editor to look into the ApplicationTest.java file:

    atom test/java/hello/ApplicationTest.java
    

    Annotations have been processed by the Java compiler since version 5. The compiler looks up the processor associated with each annotation specified. Libraries are imported to enable the use of annotations added above regular code.

    Code to process the @Test annotation is imported from org.springframework.test.context.junit4.SpringRunner.

    The @Test annotation tells JUnit 4 that it can run as a test case the method defined beneath it. This improves upon JUnit 3 which assumes every method is a test if its name starts with “test” and its class extends TestCase.

    JUnit constructs a fresh instance of the class then invokes the annotated method. *

    Exceptions thrown by the test are reported by JUnit as a failure. If no exceptions are thrown, the test is assumed to have succeeded.

    Attributes can be optionally added with annotations:

    To fail a test if the method does NOT throw the named exception:

    @Test(expected = Exception.class)

    To fail a test if the function does not finish with the allotted milliseconds time limit:

    @Test(timeout = 500)

    BTW: Additional annotations @Before/@BeforeClass and @After/@AfterClass are not in JUnit 3.

    Code to process the @SpringBootTest annotation is imported from org.springframework.boot.test.context.SpringBootTest.

    Code to process the @Autowired annotation is imported from org.springframework.beans.factory.annotation.Autowired.

    The RestTemplateBuilder is injected by Spring to perform autoconfiguration (message converters and request factories).

    See http://www.baeldung.com/java-annotation-processing-builder

    See http://qaautomated.blogspot.in/p/junit.html

    (Multiple passes may be necessary to resolve annotations within annotation processor code.)

    PROTIP: Java programs are best read from the bottom of the file.

    At the bottom of the code, the Test program makes an assertThat/strong> restTemplate isNotNull based on code in the org.springframework.web.client.RestTemplate imported.

    @Autowired cause the injection of getter and setter function code automatically during build, to save developer time on the restTemplate. (Any Spring components can be autowired. These include, components, configurations, services and beans.)

    NOTE: A Java Bean is a simple POJO whose only behavior is getters and setters. POJO (Plain Old Java Object) is an object that has attributes as well as behaviors.

    Run Test from Eclipse IDE

    The easiest way of running a single JUnit test method is to run it from within the test case’s class editor within the Eclipse IDE.

  19. Place your cursor on the method’s name inside the test class. I’d recommend using the keyboard to navigate to the method, especially if there are many tests.
  20. To run the test, press Alt+Shift+X,T or right-click, Run As > JUnit Test.
  21. To rerun the same test method, press Ctrl+F11.

    For this to work, ensure that you’ve told Eclipse to always run the last launched application.

    Alternately, go to the Outline view and run the method from there.

    *

    Application.java

    The Java package name defined at the top of the file, hello, puts this in the same package as the Test code described above.

  22. Look into the src (source) folder:

    atom main/java/hello/Application.java
    

    The entry point into the package is this line of code that appears on all Java programs:

     public static void main(String args[]) {
       ...
     }
    

    The Application.class is then invoked:

       SpringApplication.run(Application.class);
    

    ???

    The @SpringBootApplication annotation marks the base package for Spring to begin scanning components. It marks a class for static configurations of the Application Context. And it provides for autoconfiguration to start applying default behaviors.

    The “CommandLineRunner” finishes by issuing an log entry with the code:

    log.info(quote.toString());
    

    The Logger class imported from the slf1j library takes care of sending lines displayed on your Console.

    Quote.java

    As for the line:

    Quote quote = restTemplate.getForObject(
     "http://gturnquist-quoters.cfapps.io/api/random", Quote.class);
    

    The “restTemplate” class’s getForObject method is supplied by the Spring Framework.

    “Quote.class” is the response. There must then be a Quote class file to define it.

    The Quote class is defined within the Quote.java file which creates a domain class to specify the data requested.

    Value.java

  23. Look at the bottom of the Quote.java file:

     public String toString() {
         return "Quote{" +
                 "type='" + type + '\'' +
                 ", value=" + value +
                 '}';
     }
    

    The programmer created this by typing the lines:

     private String type;
     private Value value;
    

    PROTIP: Set and get funtions can be automatically created within the Eclipse IDE.

    Notice “Value” is not a built-in data type such as “String”, etc. It is a custom type which needs to be defined.

  24. Look in file Value.java which defines the Value type:

     public String toString() {
         return "Value{" +
                 "id=" + id +
                 ", quote='" + quote + '\'' +
                 '}';
     }
    

    Annotations

    https://docs.spring.io/spring-boot/docs/current/reference/html/

    @Bean provies Bean Factory

    QUESTION: applicationContext.xml file

    “just something you have to do”

#

Data Manipulation Language (DML) is stored in a data.sql file in src > main > resources.

Free Videos about Spring clients

Competitors

JAX-RS - see http://www.java2novice.com/restful-web-services/

Java API for JSON Processing (JSR 353) provides an API to parse, transform, and query JSON data using the object model or the streaming mode. See http://www.java2novice.com/java-json/javax.json/

Google Gson is a Java library that can be used to convert Java Objects into their JSON representation. It can also be used to convert a JSON string to an equivalent Java object. Gson can work with arbitrary Java objects including pre-existing objects that you do not have source-code of. See http://www.java2novice.com/java-json/google-gson/