Skip to main content

Simple tutorial to create RESTful web services using SPRING, GRADLE & ECLIPSE

How to create RESTful web services using SPRING, GRADLE & ECLIPSE

* First install Eclipse in your machine by referring to the official wiki (I have installed an eclipse version called Kepler in my machine)

* After installing Eclipse, open it and go to "eclipse market place" to add Gradle as seen in below screenshots:


* Now create a new blank Gradle project in Eclipse


*Now lets build the blank project using Gradle to ensure that everything is fine so far



* Now change the build.gradle file to below as seen in http://spring.io/guides/gs/rest-service/

buildscript { repositories { maven { url "http://repo.spring.io/libs-release" } mavenLocal() mavenCentral() } dependencies { classpath("org.springframework.boot:spring-boot-gradle-plugin:1.1.4.RELEASE") } } apply plugin: 'java' apply plugin: 'eclipse' apply plugin: 'idea' apply plugin: 'spring-boot' jar { baseName = 'gs-rest-service' version = '0.1.0' } repositories { mavenLocal() mavenCentral() maven { url "http://repo.spring.io/libs-release" } } dependencies { compile("org.springframework.boot:spring-boot-starter-web") testCompile("junit:junit") } task wrapper(type: Wrapper) { gradleVersion = '1.11' }

* We can now delete the default java files created as a part of blank project

* Now add Spring webservice files as per official spring website http://spring.io/guides/gs/rest-service/

package hello;

public class Greeting {

    private final long id;
    private final String content;

    public Greeting(long id, String content) {
        this.id = id;
        this.content = content;
    }

    public long getId() {
        return id;
    }

    public String getContent() {
        return content;
    }
}
package hello;

import java.util.concurrent.atomic.AtomicLong;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class GreetingController {

    private static final String template = "Hello, %s!";
    private final AtomicLong counter = new AtomicLong();

    @RequestMapping("/greeting")
    public Greeting greeting(@RequestParam(value="name", required=false, defaultValue="World") String name) {
        return new Greeting(counter.incrementAndGet(),
                            String.format(template, name));
    }
}
package hello;

import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.SpringApplication;
import org.springframework.context.annotation.ComponentScan;

@ComponentScan
@EnableAutoConfiguration
public class Application {

    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}
directory structure in eclipse will look like this
as seen above, eclipse shows in some errors in the files (see red marks in front of the file). This is because spring jar files are not yet there in the eclipse classpath.
In order to download the dependencies we can just go to the Gradle menu as shown below and click on refresh dependencies
as seen below the red errors are gone now after dependencies are refreshed - thanks to Gradle for making dependency management this so easy - it used to be done in ant previously by manually downloading each jar file

*We are done now! lets run the server by executing Application class in eclipse

* Lets checkout that the results look ok by running the following url in our browser: http://localhost:8080/greeting
Result looks something like this:

You also run http://localhost:8080/greeting?name=Bhajan to pass a parameter the the webservice. This is how it looks after passing the parameter:
* Now there is one more way by which we can pass parameters in RESTful urls. 
If we use that way then the URL will look something like this http://localhost:8080/greeting/Bhajan
(This link gives more details on understanding REST)
so to change it to the new way, change the GreetingController as seen below

package hello;

import java.util.concurrent.atomic.AtomicLong;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class GreetingController {

    private static final String template = "Hello, %s!";
    private final AtomicLong counter = new AtomicLong();
    //The two lines below have been changed 
    @RequestMapping(method = RequestMethod.GET, value = "greeting/{name}")
    public Greeting greeting(@PathVariable String name){
        return new Greeting(counter.incrementAndGet(),
                            String.format(template, name));
    }
}
* Stop the server by clicking on red button as seen below 

* I am trying to rebuild by running Gradle build again but i am getting the following error now
[sts] -----------------------------------------------------
[sts] Starting Gradle build for the following tasks: 
[sts]      :build
[sts] -----------------------------------------------------
:compileJava
:processResources UP-TO-DATE
:classes
:jar
:bootRepackage
:assemble
:compileTestJava UP-TO-DATE
:processTestResources UP-TO-DATE
:testClasses UP-TO-DATE
:test

org.gradle.PersonTest > canConstructAPersonWithAName FAILED
    java.lang.NoClassDefFoundError at PersonTest.java:9
        Caused by: java.lang.ClassNotFoundException at PersonTest.java:9

1 test completed, 1 failed
:test FAILED

FAILURE: Build failed with an exception.

* What went wrong:
Execution failed for task ':test'.
> There were failing tests. See the report at: file:///C:/Users/bsingh/workspace/MySpringWS/build/reports/tests/index.html

* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output.

BUILD FAILED

Total time: 2.611 secs
[sts] Build failed
org.gradle.tooling.BuildException: Could not execute build using Gradle distribution 'http://services.gradle.org/distributions/gradle-1.10-bin.zip'.

In order to debug when I build I will use debug mode:

 Now when i build again i see the following message somewhere in the log
21:31:22.604 [QUIET] [system.out] 21:31:22.603 [INFO] [org.gradle.api.internal.tasks.testing.worker.TestWorker] Gradle Worker 1 finished executing tests.
21:31:22.614 [QUIET] [system.out] 21:31:22.610 [DEBUG] [org.gradle.process.internal.child.ActionExecutionWorker] Completed Gradle Worker 1.
21:31:22.630 [DEBUG] [TestEventLogger] 
21:31:22.631 [DEBUG] [TestEventLogger] org.gradle.PersonTest > canConstructAPersonWithAName FAILED
21:31:22.633 [DEBUG] [TestEventLogger]     java.lang.NoClassDefFoundError: org/gradle/Person
21:31:22.633 [DEBUG] [TestEventLogger]         at org.gradle.PersonTest.canConstructAPersonWithAName(PersonTest.java:9)
21:31:22.634 [DEBUG] [TestEventLogger]         at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
21:31:22.634 [DEBUG] [TestEventLogger]         at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
21:31:22.635 [DEBUG] [TestEventLogger]         at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)

So I see that there is still a function called canConstructAPersonWithAName in org.gradle.PersonTest from the blank project that we created in the start. This is causing error. 

In order to resolve this i will just run the clean target and then the build target in Gradle

* Now run the server again  by executing Application class in eclipse


And this is the way i can call my webservice now...
That's it! 
Details of the application we built are in http://spring.io/guides/gs/rest-service/
Enjoy the Spring!
--Bhajan

Comments

Anonymous said…
Everything work fine according to this my project is build successfully but when i tried to Right click on Application Class, its not showing option Run on Server....Whats wrong?..I guess I am missing something...plz help

Popular posts from this blog

Hive

Hive What is Transactional Processing? * Small data * recent data * updates data * real time * narrow scope - single data source What is Analytical Processing? * Mostly batch * Mostly old data * Mostly long running * wide scope multiple data source to give a big picture ----------- RDBMS (mostly for transactional) * Single m/c with backup, structured data, usually one source Its hard to do analytics on RDBMS Big Data (mostly for analytical using data warehouse) * distributed data, semi/unstructured, auto replication with fault tolerance, usually different source and different format Not always... * hbase is special db that can be configured for transactional processing even if its on big data * qlikview can be used for analyitial processing even if its running on a single m/c --------- Whats a Data Warehouse? Technology that aggregates data  from one or more sources for analytical processing used by long running jobs, lagged data, large data, multi s...

Simple FitNesse tutorial

(Time spent for writing - 1:30 min) In simple words, FitNesse is a testing framework that can be used to develop automated test cases. I had searched many posts but could not find a single tutorial that could help me get started with FitNesse. So writing it now... BTW I am a java developer, so this tutorial is in pure java! I use windows XP and Java version is 1.5.0 To get started first download FitNesse from http://fitnesse.org/ I didnt like its 2 minute example, because that just showed what it does, doesnt really help me to start with development. They should have a real getting started tutorial there, I think. I had downloaded fitnesse20070619.zip from downloads section After downloading, install it by unzipping the all the files to a some location like c:\fitnesse c:\fitnesse will then act as the root folder for you and all the classpaths will be relative to root folder By default FitNesse will run on port 80. If you want another port you can edit the run.bat file in the root fol...