Spring MVC 4 RESTFul Web Services CRUD Example+RestTemplate

In this post we will write a CRUD Restful WebService using Spring MVC 4, and write a REST client with RestTemplate to consume those services. We will also test those services using external clients.


Short & Quick introduction to REST

REST stands for Representational State Transfer.It’s an is an architectural style which can be used to design web services, that can be consumed from a variety of clients. The core idea is that, rather than using complex mechanisms such as CORBA, RPC or SOAP to connect between machines, simple HTTP is used to make calls among them.

In Rest based design, resources are being manipulated using a common set of verbs.

  • To Create a resource : HTTP POST should be used
  • To Retrieve a resource : HTTP GET should be used
  • To Update a resource : HTTP PUT should be used
  • To Delete a resource : HTTP DELETE should be used

That means, you as a REST service developer or Client, should comply to above criteria, in order to be REST complained.

Often Rest based Web services return JSON or XML as response, although it is not limited to these types only. Clients can specify (using HTTP Accept header) the resource type they are interested in, and server may return the resource , specifying Content-Type of the resource it is serving. This StackOverflow link is a must read to understand REST in detail.



Rest Based Controller

Following is one possible Rest based controller, implementing REST API. I said possible, means Other’s may implement it in another way, still (or even more pure way) conforming to REST style.

This is what our REST API does:

  • GET request to /api/user/ returns a list of users
  • GET request to /api/user/1 returns the user with ID 1
  • POST request to /api/user/ with a user object as JSON creates a new user
  • PUT request to /api/user/3 with a user object as JSON updates the user with ID 3
  • DELETE request to /api/user/4 deletes the user with ID 4
  • DELETE request to /api/user/ deletes all the users
package com.websystique.springmvc.controller;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.util.UriComponentsBuilder;

import com.websystique.springmvc.model.User;
import com.websystique.springmvc.service.UserService;

@RestController
public class HelloWorldRestController {

	@Autowired
	UserService userService;  //Service which will do all data retrieval/manipulation work

	
	//-------------------Retrieve All Users--------------------------------------------------------
	
	@RequestMapping(value = "/user/", method = RequestMethod.GET)
	public ResponseEntity<List<User>> listAllUsers() {
		List<User> users = userService.findAllUsers();
		if(users.isEmpty()){
			return new ResponseEntity<List<User>>(HttpStatus.NO_CONTENT);//You many decide to return HttpStatus.NOT_FOUND
		}
		return new ResponseEntity<List<User>>(users, HttpStatus.OK);
	}


	//-------------------Retrieve Single User--------------------------------------------------------
	
	@RequestMapping(value = "/user/{id}", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
	public ResponseEntity<User> getUser(@PathVariable("id") long id) {
		System.out.println("Fetching User with id " + id);
		User user = userService.findById(id);
		if (user == null) {
			System.out.println("User with id " + id + " not found");
			return new ResponseEntity<User>(HttpStatus.NOT_FOUND);
		}
		return new ResponseEntity<User>(user, HttpStatus.OK);
	}

	
	
	//-------------------Create a User--------------------------------------------------------
	
	@RequestMapping(value = "/user/", method = RequestMethod.POST)
	public ResponseEntity<Void> createUser(@RequestBody User user, 	UriComponentsBuilder ucBuilder) {
		System.out.println("Creating User " + user.getName());

		if (userService.isUserExist(user)) {
			System.out.println("A User with name " + user.getName() + " already exist");
			return new ResponseEntity<Void>(HttpStatus.CONFLICT);
		}

		userService.saveUser(user);

		HttpHeaders headers = new HttpHeaders();
		headers.setLocation(ucBuilder.path("/user/{id}").buildAndExpand(user.getId()).toUri());
		return new ResponseEntity<Void>(headers, HttpStatus.CREATED);
	}

	
	//------------------- Update a User --------------------------------------------------------
	
	@RequestMapping(value = "/user/{id}", method = RequestMethod.PUT)
	public ResponseEntity<User> updateUser(@PathVariable("id") long id, @RequestBody User user) {
		System.out.println("Updating User " + id);
		
		User currentUser = userService.findById(id);
		
		if (currentUser==null) {
			System.out.println("User with id " + id + " not found");
			return new ResponseEntity<User>(HttpStatus.NOT_FOUND);
		}

		currentUser.setName(user.getName());
		currentUser.setAge(user.getAge());
		currentUser.setSalary(user.getSalary());
		
		userService.updateUser(currentUser);
		return new ResponseEntity<User>(currentUser, HttpStatus.OK);
	}

	//------------------- Delete a User --------------------------------------------------------
	
	@RequestMapping(value = "/user/{id}", method = RequestMethod.DELETE)
	public ResponseEntity<User> deleteUser(@PathVariable("id") long id) {
		System.out.println("Fetching & Deleting User with id " + id);

		User user = userService.findById(id);
		if (user == null) {
			System.out.println("Unable to delete. User with id " + id + " not found");
			return new ResponseEntity<User>(HttpStatus.NOT_FOUND);
		}

		userService.deleteUserById(id);
		return new ResponseEntity<User>(HttpStatus.NO_CONTENT);
	}

	
	//------------------- Delete All Users --------------------------------------------------------
	
	@RequestMapping(value = "/user/", method = RequestMethod.DELETE)
	public ResponseEntity<User> deleteAllUsers() {
		System.out.println("Deleting All Users");

		userService.deleteAllUsers();
		return new ResponseEntity<User>(HttpStatus.NO_CONTENT);
	}

}

Detailed Explanation :

@RestController : First of all, we are using Spring 4′s new @RestController annotation. This annotation eliminates the need of annotating each method with @ResponseBody. Under the hood, @RestController is itself annotated with @ResponseBody, and can be considered as combination of @Controller and @ResponseBody.

@RequestBody : If a method parameter is annotated with @RequestBody, Spring will bind the incoming HTTP request body(for the URL mentioned in @RequestMapping for that method) to that parameter. While doing that, Spring will [behind the scenes] use HTTP Message converters to convert the HTTP request body into domain object [deserialize request body to domain object], based on ACCEPT or Content-Type header present in request.

@ResponseBody : If a method is annotated with @ResponseBody, Spring will bind the return value to outgoing HTTP response body. While doing that, Spring will [behind the scenes] use HTTP Message converters to convert the return value to HTTP response body [serialize the object to response body], based on Content-Type present in request HTTP header. As already mentioned, in Spring 4, you may stop using this annotation.

ResponseEntity is a real deal. It represents the entire HTTP response. Good thing about it is that you can control anything that goes into it. You can specify status code, headers, and body. It comes with several constructors to carry the information you want to sent in HTTP Response.

@PathVariable This annotation indicates that a method parameter should be bound to a URI template variable [the one in '{}'].

Basically, @RestController , @RequestBody, ResponseEntity & @PathVariable are all you need to know to implement a REST API in Spring 4. Additionally, spring provides several support classes to help you implement something customized.

MediaType : With @RequestMapping annotation, you can additionally, specify the MediaType to be produced or consumed (using produces or consumes attributes) by that particular controller method, to further narrow down the mapping.


Deploy and Test this API, let’s dig deeper into how this thing works

At the at end of day, it’s just a plain controller class, part of a deploy-able application.[Complete downloadable application code is shown further down in post which you can deploy straight-away in your container]. I am going to deploy it, in order to see things live and discuss each operation in detail. Deployed Application is available at http://localhost:8080/Spring4MVCCRUDRestService.

To test this API, i will use an external client POSTMAN (An extension from CHROME). We will write our own client in just few minutes.

1. Retrieve all users

Open POSTMAN tool, select request type [GET for this usecase], specify the operation uri.

SpringMVC4CRUDRestService_img_1

Notice that we did not specify any HTTP header here. Click on Send, you will receive list of all users.

SpringMVC4CRUDRestService_img_2

Also notice the HTTP 200 response. Additionally check headers.

SpringMVC4CRUDRestService_img_3

You might be wondering how the response is sent as JSON string, and the Content-Type header in response confirms that. Glad you asked. This is due to the fact that we have included Jackson library in our project.

		<dependency>
		    <groupId>com.fasterxml.jackson.core</groupId>
		    <artifactId>jackson-databind</artifactId>
		    <version>2.5.3</version>
		</dependency>

Since spring finds this library in class path, it invokes inbuilt MappingJackson2HttpMessageConverter converter to convert the response (List of objects) into JSON.

Good thing about Spring inbuilt converters are that most of the time they just need certain library in classpath in order to perform conversion. Of course sometime we do need to adapt our API/application as well. For instance, if we want to serve XML as well, we should annotate User class with proper JAXB annoations.

2. Retrieve Single User

Specify a GET with /user/1 , click on send.

SpringMVC4CRUDRestService_img_4

Now try to send a GET with invalid identifier, you should receive a HTTP 404.

SpringMVC4CRUDRestService_img_5

3. Create a User

Select the method as POST, specify uri as /user/, specify body in POSTMAN body tab, select the type [application/json].

SpringMVC4CRUDRestService_img_6

You might have noticed that POSTMAN automatically adds a header Content-Type.

SpringMVC4CRUDRestService_img_7

Along with POST and PUT request, clients send the data to the server and they should specify the actual content type of the data being sent.

Remember : Accept header says about what type client can understand. Content-Type header says what type of data actually is of.

Send. You should see HTTP 200 response with no body (as API don’t send anything in body). But you should find a Location header specifying the location the newly created user can be found at.

SpringMVC4CRUDRestService_img_8

You can now fetch the newly created user.

SpringMVC4CRUDRestService_img_9

This way of implementation is common in REST. But no one stops you if you do want to send the content in Response body of a POST/PUT request. Will that still be REST complaint API? It’s a debatable point.

Anyway, Lets try to create the same user again.You should get HTTP Conflict response.

SpringMVC4CRUDRestService_img_10

4. Update a User

Send a HTTP PUT request to update a user. Send along the new user details to be put in.

SpringMVC4CRUDRestService_img_11

Notice that we have received response body this time. This is because the method implementation in controller is sending it. Again, one may decide not to send the updated details in response body, and just send the location header(as in create).

5. Delete a User

SpringMVC4CRUDRestService_img_12

6. Delete All Users

SpringMVC4CRUDRestService_img_13

7. Verify users after delete-all

SpringMVC4CRUDRestService_img_14


Writing REST Client using RestTemplate

Postman tool we used above is a wonderful Client to test Rest API. But if you want to consume REST based web services from your application, you would need a REST client for your application. One of the most popular HTTP client is Apache HttpComponents HttpClient. But the details to access REST services using this are too low level.

Spring’s RestTemplate comes to Rescue. RestTemplate provides higher level methods that correspond to each of the six main HTTP methods that make invoking many RESTful services a one-liner and enforce REST best practices.

Below shown are HTTP methods and corresponding RestTemplate methods to handle that type of HTTP request.

HTTP Methods and corresponding RestTemplate methods:

  • HTTP GET : getForObject, getForEntity
  • HTTP PUT : put(String url, Object request, String…​urlVariables)
  • HTTP DELETE : delete
  • HTTP POST : postForLocation(String url, Object request, String…​ urlVariables), postForObject(String url, Object request, Class responseType, String…​ uriVariables)
  • HTTP HEAD : headForHeaders(String url, String…​ urlVariables)
  • HTTP OPTIONS : optionsForAllow(String url, String…​ urlVariables)
  • HTTP PATCH and others : exchange execute

Custom Rest client , consuming the REST services created earlier.

package com.websystique.springmvc;

import java.net.URI;
import java.util.LinkedHashMap;
import java.util.List;

import org.springframework.web.client.RestTemplate;

import com.websystique.springmvc.model.User;

public class SpringRestTestClient {

	public static final String REST_SERVICE_URI = "http://localhost:8080/Spring4MVCCRUDRestService";
	
	/* GET */
	@SuppressWarnings("unchecked")
	private static void listAllUsers(){
		System.out.println("Testing listAllUsers API-----------");
		
		RestTemplate restTemplate = new RestTemplate();
		List<LinkedHashMap<String, Object>> usersMap = restTemplate.getForObject(REST_SERVICE_URI+"/user/", List.class);
		
		if(usersMap!=null){
			for(LinkedHashMap<String, Object> map : usersMap){
	            System.out.println("User : id="+map.get("id")+", Name="+map.get("name")+", Age="+map.get("age")+", Salary="+map.get("salary"));;
	        }
		}else{
			System.out.println("No user exist----------");
		}
	}
	
	/* GET */
	private static void getUser(){
		System.out.println("Testing getUser API----------");
		RestTemplate restTemplate = new RestTemplate();
        User user = restTemplate.getForObject(REST_SERVICE_URI+"/user/1", User.class);
        System.out.println(user);
	}
	
	/* POST */
    private static void createUser() {
		System.out.println("Testing create User API----------");
    	RestTemplate restTemplate = new RestTemplate();
        User user = new User(0,"Sarah",51,134);
        URI uri = restTemplate.postForLocation(REST_SERVICE_URI+"/user/", user, User.class);
        System.out.println("Location : "+uri.toASCIIString());
    }

    /* PUT */
    private static void updateUser() {
		System.out.println("Testing update User API----------");
        RestTemplate restTemplate = new RestTemplate();
        User user  = new User(1,"Tomy",33, 70000);
        restTemplate.put(REST_SERVICE_URI+"/user/1", user);
        System.out.println(user);
    }

    /* DELETE */
    private static void deleteUser() {
		System.out.println("Testing delete User API----------");
        RestTemplate restTemplate = new RestTemplate();
        restTemplate.delete(REST_SERVICE_URI+"/user/3");
    }


    /* DELETE */
    private static void deleteAllUsers() {
		System.out.println("Testing all delete Users API----------");
        RestTemplate restTemplate = new RestTemplate();
        restTemplate.delete(REST_SERVICE_URI+"/user/");
    }

    public static void main(String args[]){
		listAllUsers();
		getUser();
		createUser();
		listAllUsers();
		updateUser();
		listAllUsers();
		deleteUser();
		listAllUsers();
		deleteAllUsers();
		listAllUsers();
    }
}

Restart server(In our example, data on server side is fixed.). Run above program.

Output from above Client program

Testing listAllUsers API-----------
User : id=1, Name=Sam, Age=30, Salary=70000.0
User : id=2, Name=Tom, Age=40, Salary=50000.0
User : id=3, Name=Jerome, Age=45, Salary=30000.0
User : id=4, Name=Silvia, Age=50, Salary=40000.0
Testing getUser API----------
User [id=1, name=Sam, age=30, salary=70000.0]
Testing create User API----------
Location : http://localhost:8080/Spring4MVCCRUDRestService/user/5
Testing listAllUsers API-----------
User : id=1, Name=Sam, Age=30, Salary=70000.0
User : id=2, Name=Tom, Age=40, Salary=50000.0
User : id=3, Name=Jerome, Age=45, Salary=30000.0
User : id=4, Name=Silvia, Age=50, Salary=40000.0
User : id=5, Name=Sarah, Age=51, Salary=134.0
Testing update User API----------
User [id=1, name=Tomy, age=33, salary=70000.0]
Testing listAllUsers API-----------
User : id=1, Name=Tomy, Age=33, Salary=70000.0
User : id=2, Name=Tom, Age=40, Salary=50000.0
User : id=3, Name=Jerome, Age=45, Salary=30000.0
User : id=4, Name=Silvia, Age=50, Salary=40000.0
User : id=5, Name=Sarah, Age=51, Salary=134.0
Testing delete User API----------
Testing listAllUsers API-----------
User : id=1, Name=Tomy, Age=33, Salary=70000.0
User : id=2, Name=Tom, Age=40, Salary=50000.0
User : id=4, Name=Silvia, Age=50, Salary=40000.0
User : id=5, Name=Sarah, Age=51, Salary=134.0
Testing all delete Users API----------
Testing listAllUsers API-----------
No user exist----------

Complete Example


Project Structure

Spring4MVCCRUDRestService_img0


Declare project dependencies

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.websystique.springmvc</groupId>
  <artifactId>Spring4MVCCRUDRestService</artifactId>
  <packaging>war</packaging>
  <version>1.0.0</version>
  <name>Spring4MVCCRUDRestService Maven Webapp</name>

  	<properties>
		<springframework.version>4.2.0.RELEASE</springframework.version>
		<jackson.version>2.5.3</jackson.version>
	</properties>

	<dependencies>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-webmvc</artifactId>
			<version>${springframework.version}</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-tx</artifactId>
			<version>${springframework.version}</version>
		</dependency>

		<dependency>
			<groupId>com.fasterxml.jackson.core</groupId>
		    <artifactId>jackson-databind</artifactId>
		    <version>${jackson.version}</version>
		</dependency>
		<dependency>
			<groupId>javax.servlet</groupId>
			<artifactId>javax.servlet-api</artifactId>
			<version>3.1.0</version>
		</dependency>
			
	</dependencies>


	<build>
		<pluginManagement>
			<plugins>
				<plugin>
					<groupId>org.apache.maven.plugins</groupId>
					<artifactId>maven-compiler-plugin</artifactId>
					<version>3.2</version>
					<configuration>
						<source>1.7</source>
						<target>1.7</target>
					</configuration>
				</plugin>
				<plugin>
					<groupId>org.apache.maven.plugins</groupId>
					<artifactId>maven-war-plugin</artifactId>
					<version>2.4</version>
					<configuration>
						<warSourceDirectory>src/main/webapp</warSourceDirectory>
						<warName>Spring4MVCCRUDRestService</warName>
						<failOnMissingWebXml>false</failOnMissingWebXml>
					</configuration>
				</plugin>
			</plugins>
		</pluginManagement>

		<finalName>Spring4MVCCRUDRestService</finalName>
	</build>
</project>


User Service

package com.websystique.springmvc.service;

import java.util.List;

import com.websystique.springmvc.model.User;



public interface UserService {
	
	User findById(long id);
	
	User findByName(String name);
	
	void saveUser(User user);
	
	void updateUser(User user);
	
	void deleteUserById(long id);

	List<User> findAllUsers(); 
	
	void deleteAllUsers();
	
	public boolean isUserExist(User user);
	
}

package com.websystique.springmvc.service;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.concurrent.atomic.AtomicLong;

import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.websystique.springmvc.model.User;

@Service("userService")
@Transactional
public class UserServiceImpl implements UserService{
	
	private static final AtomicLong counter = new AtomicLong();
	
	private static List<User> users;
	
	static{
		users= populateDummyUsers();
	}

	public List<User> findAllUsers() {
		return users;
	}
	
	public User findById(long id) {
		for(User user : users){
			if(user.getId() == id){
				return user;
			}
		}
		return null;
	}
	
	public User findByName(String name) {
		for(User user : users){
			if(user.getName().equalsIgnoreCase(name)){
				return user;
			}
		}
		return null;
	}
	
	public void saveUser(User user) {
		user.setId(counter.incrementAndGet());
		users.add(user);
	}

	public void updateUser(User user) {
		int index = users.indexOf(user);
		users.set(index, user);
	}

	public void deleteUserById(long id) {
		
		for (Iterator<User> iterator = users.iterator(); iterator.hasNext(); ) {
		    User user = iterator.next();
		    if (user.getId() == id) {
		        iterator.remove();
		    }
		}
	}

	public boolean isUserExist(User user) {
		return findByName(user.getName())!=null;
	}

	private static List<User> populateDummyUsers(){
		List<User> users = new ArrayList<User>();
		users.add(new User(counter.incrementAndGet(),"Sam",30, 70000));
		users.add(new User(counter.incrementAndGet(),"Tom",40, 50000));
		users.add(new User(counter.incrementAndGet(),"Jerome",45, 30000));
		users.add(new User(counter.incrementAndGet(),"Silvia",50, 40000));
		return users;
	}

	public void deleteAllUsers() {
		users.clear();
	}

}


Model class

package com.websystique.springmvc.model;

public class User {

	private long id;
	
	private String name;
	
	private int age;
	
	private double salary;

	public User(){
		id=0;
	}
	
	public User(long id, String name, int age, double salary){
		this.id = id;
		this.name = name;
		this.age = age;
		this.salary = salary;
	}
	
	public long getId() {
		return id;
	}

	public void setId(long id) {
		this.id = id;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public int getAge() {
		return age;
	}

	public void setAge(int age) {
		this.age = age;
	}

	public double getSalary() {
		return salary;
	}

	public void setSalary(double salary) {
		this.salary = salary;
	}

	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + (int) (id ^ (id >>> 32));
		return result;
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		User other = (User) obj;
		if (id != other.id)
			return false;
		return true;
	}

	@Override
	public String toString() {
		return "User [id=" + id + ", name=" + name + ", age=" + age
				+ ", salary=" + salary + "]";
	}


}


Configuration class

package com.websystique.springmvc.configuration;

import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;

@Configuration
@EnableWebMvc
@ComponentScan(basePackages = "com.websystique.springmvc")
public class HelloWorldConfiguration {
	

}


Initialization Class

package com.websystique.springmvc.configuration;

import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;

public class HelloWorldInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
 
    @Override
    protected Class<?>[] getRootConfigClasses() {
        return new Class[] { HelloWorldConfiguration.class };
    }
  
    @Override
    protected Class<?>[] getServletConfigClasses() {
        return null;
    }
  
    @Override
    protected String[] getServletMappings() {
        return new String[] { "/" };
    }
 
}

Adding CORS support to your REST API

While accessing the REST API, you might face issues concerning Same Origin Policy.

Errors like :
” No ‘Access-Control-Allow-Origin’ header is present on the requested resource. Origin ‘http://127.0.0.1:8080′ is therefore not allowed access.” OR
” XMLHttpRequest cannot load http://abc.com/bla. Origin http://localhost:12345 is not allowed by Access-Control-Allow-Origin.” are common in such case.

Solution is Cross-Origin Resource Sharing. Basically, on server side, we can return additional CORS access control headers with response, which will eventually allow further inter-domain communication.

With Spring, we can write a simple filter which adds those CORS specific headers in each response.

package com.websystique.springmvc.configuration;

import java.io.IOException;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletResponse;


public class CORSFilter implements Filter {

	public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
		System.out.println("Filtering on...........................................................");
		HttpServletResponse response = (HttpServletResponse) res;
		response.setHeader("Access-Control-Allow-Origin", "*");
		response.setHeader("Access-Control-Allow-Methods", "POST, GET, PUT, OPTIONS, DELETE");
		response.setHeader("Access-Control-Max-Age", "3600");
		response.setHeader("Access-Control-Allow-Headers", "x-requested-with");
		chain.doFilter(req, res);
	}

	public void init(FilterConfig filterConfig) {}

	public void destroy() {}

}

Then we can simply configure it in our Spring configuration like shown below:

package com.websystique.springmvc.configuration;

import javax.servlet.Filter;

import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;

public class HelloWorldInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
 
    @Override
    protected Class<?>[] getRootConfigClasses() {
        return new Class[] { HelloWorldConfiguration.class };
    }
  
    @Override
    protected Class<?>[] getServletConfigClasses() {
        return null;
    }
  
    @Override
    protected String[] getServletMappings() {
        return new String[] { "/" };
    }
    
    @Override
    protected Filter[] getServletFilters() {
    	Filter [] singleton = { new CORSFilter()};
    	return singleton;
    }
 
}

That’s it. With these two additional steps, clients will be able to communicate with your REST API without worrying about Cross domain issues.

Download Source Code



With CORS support:

References

If you like tutorials on this site, why not take a step further and connect me on Facebook , Google Plus & Twitter as well? I would love to hear your thoughts on these articles, it will help me improve further our learning process.

If you appreciate the effort I have put in this learning site, help me improve the visibility of this site towards global audience by sharing and linking this site from within and beyond your network. You & your friends can always link my site from your site on www.websystique.com, and share the learning.

After all, we are here to learn together, aren’t we?

  • Deepak Ray Chowdhury

    Hi websystique

    http://localhost:8088/Mobitino/oauth/token?grant_type=password&username=bill&password=abc123
    i imported the source and tried runnig it to my local but getting an error 404

    • websystique

      Hi Deepak, Probably your local tomcat setup is having some issue. Please have a look at Setup Tomcat with Eclipse, should be fine.

  • Deepak Ray Chowdhury

    Hi Can i configure servlet.xml and web.xml file becouse i can not use view resolver.so please help me

  • Mahesh Thorat

    Hi
    I am getting this error while fetching data against id
    request -http://localhost:8080/Spring4MVCCRUDRestService/user/1
    Error-
    Fetching User with id 1
    Oct 22, 2016 1:11:58 PM org.springframework.web.servlet.mvc.support.DefaultHandlerExceptionResolver logException
    WARNING: Handler execution resulted in exception: Could not find acceptable representation

    • websystique

      Hi Mahesh, Please make sure that ‘jackson-databind’ dependency is included in your pom.xml.

  • Andrey Stepanov

    Dear site owner,
    I’m very thankful to you for the fantastic set of course and your generosity in sharing your experience.

    May I ask you two questions regarding this particular article? May be you could answer …

    First, I got curious about specifics controller methods for POST and PUT.
    Both of them have (User) user as one of the arguments.
    And in both case we do not transmit id as part of the request body (in case of PUT we get it from URI parameter though)
    How does it come that argument of type User is constructed as RequestBody without unique identifier?

    Second question is a bit more practical,
    when I run POST request in POSTMAN I do get ‘Error 415 Unsupported Media Type’ server response
    despite that:
    a) I have specified JSON as data type from the drop-down in POSTMAN
    b) I added ‘consumes = MediaType.APPLICATION_JSON_VALUE’ to the @RequestMapping for the controller POST method
    sure we have jackson-databind library on the classpath
    - only adding Content-Type header in POSTMAN with value application/json solved the problem

    Does it mean that the server … not always capable to read the content type from the code?
    Or am I doing something wrong?

    Again, let me wish you all the best, and let me hope that my questions will strike your interest and desire to reply

    • websystique

      Hi Andrey, Not sure how i missed your message, but here i am.

      About your first question : Post relates to HTTP POST while Put to HTTP Put. In both, you send content as request body, but POST is [conceptually] used for ‘Create’ while Put is used for ‘update’.For Post, as object is not created yet, we don’t have id yet. For Put, we do have the object id [and it CAN be sent as part of request body], the object id is the key to look for original object which will be updated with new content.

      For the second question: Server can send the requested resource in different formats depending on the client request ['Accept' header]. ‘Content-Type’ Header in HTTP request is special and is essential in a PUT or POST request. With PUT/POST, client is actually sending a bunch of data to the server as part of the request, and the Content-Type header tells the server what the data actually is (and thus determines how the server will parse it).Without Content-Type header, server have no means of specifying what is the type of data in request [Unless server itself tries to figure it out but it is not mandatory on server part]. Hope it clarifies your doubt.

  • Nilesh Za

    Thanks for this great tutorial. I was trying to deploy this code with the help IntelliJ and Jboss 6.4 , but whenever i hit the request ,am getting 404. is there any change i need to do. Could you please help me.

    • websystique

      Hi Nilesh, did you try if your local seutp [Intellij+JBoss] works for any other project. It seems to me a configuration issue in your setup.

  • Pingback: Spring MVC 4 RESTFul Web Services | ALİ ÖZDEMİR()

  • Stone Patterson

    will this work in IntelliJ

    • Stone Patterson

      what would i need to change . add . delete. update, etc. if anything at all in order to have this function in IntelliJ?

      • websystique

        I don’t think you need any change.Did you get any error while running on IntelliJ?

        • Stone Patterson

          Couldn’t get this /import com.websystique.springmvc.model.User;// to resolve symbol error .

          • websystique

            Did you refresh and then build your project in intellij?

          • Stone Patterson

            yes I did. any other suggestions

          • Stone Patterson

            yes. I did a refresh. Still no luck.

          • websystique

            Hi Stone, I just imported it into IntelliJ and no issue. Are you sure you have imported it correctly? Did you try to mark src/main/java directory as ‘sources root’? BTW, do you have any other projects successfully setup on your IDE?

  • Ismael Ezequiel

    Why I’m receiving that error:

    java.lang.NullPointerException: null

    ??

    • websystique

      Hey ismael, only saying that i get error is not so helpful.Could you please past complete exception so that we know where it was thrown?

  • Gyver

    I am very new in spring mvc, can i ask if what are the things i need to set up first in my eclipse so that i can create spring mvc application, specifically a crud application? Is there someone who can guide me? thank you!

  • Naina R

    plz help
    and you have done a great job…by making this site…helps a lot

    • websystique

      Hi,it seems that you are asking the response of specific type [e.g. using Accept header in request] which is not supported by default. Please check your accept header. You can see in above examples that JSON is supported [since jackson-databind is in classpath]. Please have a look at this post to learn about the converters.

      You may want to explicitly send the expected type using Headers. For instance, listAllUsers() can be re-written like following:

      private static void listAllUsers(){
      System.out.println(“Testing listAllUsers API———–”);
      RestTemplate restTemplate = new RestTemplate();

      HttpHeaders headers = new HttpHeaders();
      headers.setAccept(Arrays.asList(MediaType.APPLICATION_JSON));

      HttpEntity request = new HttpEntity(headers);
      ResponseEntity response = restTemplate.exchange(REST_SERVICE_URI+”/user/”, HttpMethod.GET, request, List.class);
      List<LinkedHashMap> usersMap = (List<LinkedHashMap>)response.getBody();

      if(usersMap!=null){
      for(LinkedHashMap map : usersMap){
      System.out.println(“User : id=”+map.get(“id”)+”, Name=”+map.get(“name”)+”, Age=”+map.get(“age”)+”, Salary=”+map.get(“salary”));;
      }
      }else{
      System.out.println(“No user exist———-”);
      }
      }

      • Naina R

        thnks for the answer…but my exception is still the same….i have edited the code…

  • Gil Shapir

    1) Trying to deploy the project directly from Eclipse Neon, by right click on it and choose run on server I’m getting: this selection cannot run on any server.
    I do have Tomcat 8 installed.
    As there is no main method defined not so sure if/how this should work
    2) also getting a message:
    Cannot change version of project facet Dynamic Web Module to 3.1. Spring4MVCCRUDRestService line 1 Maven Java EE Configuration Problem

    Any help will be appreciated

  • Srinivasa Praneeth

    Hi,

    Thank you very much… it is an Awesome tutorial it helped me a lot.

  • Chriso Lopez C

    Hi, I downloaded your project and trying to run it from Eclipse on Glassfish, I keep getting a 404 Not found.

    • websystique

      Hi Chriso, It could be related to your environment setup. Have a look at Setup tomcat+Eclipse. Although that post is for tomcat, you can follow the similar procedure to setup your server with Eclipse.

  • SG

    Hi, thanks for this tutorial. This is really wonderful. I have a question more to do with the design part of the components. For the registration page, I mean the actual html/jsp client we need to have a non-rest controller ? I don’t want to call the JSP/HTML and would like to go through Springs MVC? what will be the best way to handle this.

    • websystique

      Hi SG, you can implement everything in REST way. Even in this example post, the createUser method is written in a REST way, returning ResponseEntity with actual HTTP status code. We should implement our logic in a consistent way. Let me know if i misunderstood your question.

      • SG

        Sorry If my question was not clear. I am talking about the initial view page to input data for the CreateUser method. Say for example user.jsp is the initial page, which is holding form input element to enter user information which in turns call the CreateUser REST api. In below code I am using a normal Spring Controller instead of REST. I believe below approach is a correct.
        @Controller // Using a non REST Controller.
        @RequestMapping(“/registerUser”)
        public class HomeController {
        @RequestMapping(method=RequestMethod.GET)
        public String HomePage(Model model){
        return “user”;
        }
        }

  • hzms

    hi, may i know what is the difference between using spring with restful web services and using spring without it?

    • websystique

      Hi hzms,
      Spring provides different ways to implement applications. In case your application is build with REST architecture in mind, you take advantage of Spring REST support to implement your application. If not, you go for traditional Spring MVC controllers, returning views [instead of data & HTTP status codes].

  • ashish

    hi very nice tutorial.. but so many new things… How can I integrate this module with mybatis..?

    • websystique

      Hi Ashish, i don’t have knowledge of mybatis yet, sorry, probably something for future.

  • Maun Bisma

    Hi, nice tutorial,,,
    I already try your tutorial http://websystique.com/springmvc/spring-mvc-4-and-spring-security-4-integration-example/,,,,but when I add the restfull controller like this tutorial, i get error 405 about POST request not support,,,, can you give me advice what wrong?

    Thank you,,,

    • websystique

      Hi Maun, in that post, we are using Spring Security with CSRF enabled. Make sure that in your page, the expressions are evaluated [set in JSP].

  • sonia rao

    Hi,I have tried this example …its asking for Username And password in postman…can anyone help with this??

    • websystique

      Hi Sonia, this example does not required any authentication anywhere. Could it be that you are mixing it with requests for other posts [Spring Security]?

  • Daniel

    Hi, how does it come that I did not declare this jackson dependency and it still returns a JSON with the header Content-Type →application/json;charset=UTF-8 …. I checked all the jars in my project and it does NOT seem like some other dependency transitively brought it.. any idea? Great post by the way, thanks!

    ANSWER: My bad, actually spring-webmvc does bring that dependency

  • Girish Balodi

    Ultimate guid step by step… :)

  • Pingback: Ruksis780()

  • http://hendisantika.wordpress.com Hendi Santika

    Hi. I’ve been enjoying your tutorials, they’re great :)

    How ever I want to know the way you handle those api in form / web page. So that I can continue learning your nice tutorial more understand implementations.

    • websystique

      Hi Hendi, Sorry i missed it. For web pages in a Spring MVC based application, normally if we get the response from server as plain JSON, our preference [in 2016] should be using AngularJS [within jsp as shown SpringMVC+AngularJS Example or without jsp but with a template[Velocity/Freemarker] as shown Spring 4 MVC+AngularJS Routing Example using UI-Router]. But if for any reason you are stuck with plain JSP[no angularJS], you should consider using JQuery with JSP to get the response from server [using $.ajax()] and display in appropriate element [node] within your page.

  • Kali Prasad Padhy

    Hi,
    Can you tell me why we use AbstractAnnotationConfigDispatcherServletInitializer to intalize HelloWorldInitializer class.

    Thanks

    • websystique

      Hi,
      Functionally, AbstractAnnotationConfigDispatcherServletInitializer provides a way to handle the configuration you would normally specify in traditional web.xml: register a DispatcherServlet. It provides hooks to register classes & filters with global ContextLoaderListener as well as with DispatcherServlet. More detailed description can be found at Spring Docs.

  • greo

    i get error 404 in netbeans and eclipse, i try server tomcat in eclipse and server tomcat and glassfish in netbeans, how to fix that :( ?

    • websystique

      As i am using Eclipse, i would suspect the tomcat configuration. Did you already go through each step from post Setup Tomcat with Eclipse?

  • Sof Ham

    Hi I’m getting “Etat HTTP 404 – /Spring4MVCCRUDRestService/user/” when calling http://localhost:8282/Spring4MVCCRUDRestService/user/

    please note that tomcat is correctly installed.

    • websystique

      Hi Sof, Is your tomcat deployment listening on 8282 or 8080?

  • Patrick Ndukwe

    Today I have been given a new task and will like to share. I have two websites written in Spring MVC that does registration and payment processing. On beginning the registration process on the first portal, when it comes to payment the user is thereby directed to the second portal to complete the payment and thereby returns the person back to the first website. The registration details entered by the user is required to be transferred from the first portal to the second portal in other to generate the required payment processing. My question is, please what are the steps to channel my efforts towards using JSON to transfer data from one portal to another considering data security using Spring MVC. Please can you help me with ideas…

  • Michael Dmitriev

    Thank you very much! helped me a lot

  • Abhijit Marne Deshmukh

    thank you so much for providing this great example. it is really helpful.

    • websystique

      Thanks for the comments Abhijit.

  • Binh Thanh Nguyen

    Thanks, nice tips.

  • sanji

    Hi, very nice tutorial I learned so much from it :)

    When creating a user via Postman I get an HTTP 201 Created (which is obvious) instead of HTTP 200 OK like in your examples (less obvious…) is there any explanations about that ?

    Second, I’m using Spring Tool Suite (latest version) I wanted to deploy the app with spring-boot (have all the necessary dependencies in maven) so when I type the command “mvn spring-boot:run” I get this output http://pastebin.com/AAYnCCnN server returns 404 when I type http://localhost:8080/stbwebservice/user/ in the browser on the other hand when I deploy it as a war and run it on a standalone tomcat8 it works… How can I solve that ?

    Thanks again.

  • Rupali Solaskar

    Hi. I am running same code on my laptop and also following every step of setting tomcat with eclipse but i got an error -”Server Tomcat v8.0 Server at localhost failed to start.” i am not getting that because of what error comes. after every step performing when i tried to start tomcat at that time this error occurs.

    please help me.

    Thanks

  • Gísli Leifsson

    Hi there and thanks for a great series of tutorials! Been following quite a few.

    For those of you who are dealing with a 404 error, the answer might be extremely simple.
    In the controller class, the request mapping for listAllUsers looks like this:
    @RequestMapping(value = “/user/”, method = RequestMethod.GET)
    Notice that it’s “/user/” and not “/user”. This means that if you end the URL with “/user”, it gives you a 404 error. If you end it with “/user/” however, it will work. At least it behaves like this in Tomcat 8.

    Simply change the request mapping to “/user” and it will work as expected.

    • Ashmin Pathak

      Thanks..

    • Schmit

      http://localhost:8077/Spring4MVCCRUDRestService/user/ it is working fine. we need to use user/
      i downloaded tomcat 8.0 and builded it using maven 3.0 and pasted the war file in the webapps folder and clicked on start.bat. And as given in the postmaster i given extra / it worked fine for me

  • Rupali Solaskar

    Hi I am using your above code but it is not executing. I am getting 404 error, I am running it in Eclipse -Luna can any one help me how to remove error.

    • websystique

      Hi Rupali,

      Probably your local tomcat+Eclipse setup is not correct. Please have a look at Setting Tomcat with Eclipse, should be helpful.

      • Rupali Solaskar

        its done!!!!!!
        Thank you.!!!!!!!!!!!!

        Yes you were correct there was problem in my setting of tomcat with Eclipse.

        Great Work. its very helpful.

  • Muhammed Abdul

    Hello, I have also added Spring Security basic authentication as mentioned in your previous tutorials,

    But i am not able to access it if i provide a header with authorization and Basic

    Can you help? Do i need to change the security class ( i am using the same security class as in ur previous tutorials without any changes)

  • wang

    A good example for study spring rest

    Thanks a lot!

  • lab

    I am using netbean, and deploying in tomcat 8. However i get error 404 – not found accessing resources. How I can solve it?

    • websystique

      Hi, I don’t have a netbeans setup, but the problem itself seems similar to eclipse+tomcat when the tomcat is not configured properly with your IDE. To get an idea, you may want to refer to Setting Tomcat with Eclipse, and check if your IDE missing some specific configuration.

  • Mamuka Arabuli

    I was unable to produce xml . simple call always returns json , I added @XmlRootElement but no result :

    406 Not Acceptable

    • Antonio D.A. (adoalonso)

      You should add the dependency to com.fasterxml.jackson.dataformat::jackson-dataformat-xml

      com.fasterxml.jackson.dataformat
      jackson-dataformat-xml
      ${jackson.version}

  • javalearner

    Thanks for sharing this project .. I have downloaded the project and then did the Maven build and then Maven Install and then run on tomcat 8.0 but its giving me 404 error . Please help

    • websystique

      Hi, Your Tomcat setup seems not correct. Please follow Setup Tomcat With Eclipse, should be fine. Let me know if you still face issues.

  • Faisal Arkan

    Thanks !! it’s so helpful,,

  • swapyish

    Great tutorial indeed. Very useful and good explaination.

  • dgoyal

    Hi
    I ran project zip shared by you successfully. I then tried to create my own project, following all inputs given by you. I get a blank HTTP 200 OK response when I try to list all users. Somehow application is not passing controls to methods specified in controller class. Any suggestions?
    I see that mappings happened correctly
    ——————————————-
    Feb 03, 2016 1:11:02 PM org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping register

    INFO: Mapped “{[/user/],methods=[POST]}” onto public org.springframework.http.ResponseEntity com.intelligrated.springmvc.controller.HelloWorldRestController.createUser(com.intelligrated.springmvc.model.User,org.springframework.web.util.UriComponentsBuilder)

    Feb 03, 2016 1:11:02 PM org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping register

    INFO: Mapped “{[/user1/],methods=[GET]}” onto public org.springframework.http.ResponseEntity<java.util.List> com.intelligrated.springmvc.controller.HelloWorldRestController.listAllUsers()

    Feb 03, 2016 1:11:02 PM org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping register

    INFO: Mapped “{[/user/{id}],methods=[GET],produces=[application/json]}” onto public org.springframework.http.ResponseEntity com.intelligrated.springmvc.controller.HelloWorldRestController.getUser(long)

    Feb 03, 2016 1:11:02 PM org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping register

    INFO: Mapped “{[/user/{id}],methods=[PUT]}” onto public org.springframework.http.ResponseEntity com.intelligrated.springmvc.controller.HelloWorldRestController.updateUser(long,com.intelligrated.springmvc.model.User)

    Feb 03, 2016 1:11:02 PM org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping register

    INFO: Mapped “{[/user/{id}],methods=[DELETE]}” onto public org.springframework.http.ResponseEntity com.intelligrated.springmvc.controller.HelloWorldRestController.deleteUser(long)

    Feb 03, 2016 1:11:02 PM org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping register

    INFO: Mapped “{[/user/],methods=[DELETE]}” onto public org.springframework.http.ResponseEntity com.intelligrated.springmvc.controller.HelloWorldRestController.deleteAllUsers()

    Feb 03, 2016 1:11:02 PM org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter initControllerAdviceCache
    —————————————————–
    One difference I notice between logs of application provided by you and created by me is that log for your project shows following and my project log does not have these lines.

    Feb 03, 2016 1:15:33 PM org.springframework.web.servlet.PageNotFound noHandlerFound

    WARNING: No mapping found for HTTP request with URI [/Spring4MVCCRUDRestService/] in DispatcherServlet with name ‘dispatcher’

    Any guidance will be appreciated. (I am on eclipse, JDK1.8, Tomcat, Windows 7)

    • websystique

      Hi, Glad you found it useful.

  • Tej

    Superb blog and great example. I downloaded, did maven build and deploy on Tomcat 7 and even 8 but when visit http://localhost:8080/Spring4MVCCRUDRestService/user/ gets Bad Format???
    I am using intelliJ idea ..but no errors while deploying too !!

  • Pingback: Spring 4 MVC+AngularJS Example - WebSystique()

  • Pingback: Spring 4 MVC+AngularJS CRUD Application using ngResource - WebSystique()

  • Anurag P

    Hello All,
    I tried this on tomcat 7 , it was working fine …,

    I have tried running it on jboss eap 6.3.0 and i am getting 404 Error!!!!!
    Did anyone else tried running it on JBOSS EAP 6.3.0 ???

  • Balakrishna Pedada

    Hello,

    I am trying to write an ajax call for form submission using this example, my question is did restcontroller only accepts json content type and json data format for processing the post request?

    I am trying to do an ajax call using form data object with the content type application/json, but I am getting 400 bad request error.

    Will @requestbody won’t take care of auto converting formdata to json??

    Do we need to always call a rest controller with json data and content type to JSON?

    Please correct me If I misunderstood something.

    • websystique

      Hi Balakrishna,

      On your question to RestController capabilities, it DOES SUPPORTS multiple formats. But to handle different formats , it needs help of HttpMessageConverters. They are automatically registered based on the presence of specific libraries in classpath. This Post contains more detail on this topic.

      Coming back to your issue, application/json should have been handled by default if you have jackson-databind library in classpath (as included in this tutorial). If it is, and you are not using any custom datatype which can not be directly converted to JSON, then most probably the issue is not on server but in sending the request.

      Are you using jquery ajax to send the form-submission post request, then make sure you are setting the dataType & ContentType correctly.this link can be handy.

      It always help to open Developer tool in your browser to see what’s going on wire, and if the Content-Type header is present with appropriate type. Let me know if you remain blocked, then we will dig in deeper together.

      • Balakrishna Pedada

        Thank you for your reply, Yes I am sending jquery ajax request. I am able to get response only if I send my content type as JSON and form data as JSON data.

        But If I am using “application/x-www-form-urlencoded” with form data I am getting a 415 error. Please find the below screenshots and My rest controller. Also I have included jackson databind in the classpath.

        • websystique

          Hi, You did not mention anything about application/x-www-form-urlencoded before. Anyway, this post contains the info you are looking for. Basically you need to register Spring’s FormHttpMessageConverter to handle the type you mentioned.There is an example give in the post.

  • Vikash Kumar

    hello sir,
    When i have deployed project on weblogic12 c then generates following exception.
    please say to me how to remove it?..

  • Vikash Kumar

    May u provide me its war file????????

    • websystique

      Hi Vikas,
      Just download the zip and perform mvn clean install. you will get the war.

  • Vikash Kumar

    Hello admin may i know about web.xml. There is no xml why???????

    • websystique

      Hey Vikas,

      This is because we are using Servlet 3.x based configurations.Everything we need is already there in HelloWorldInitializer.

      • Vikash Kumar

        ok

  • Максим Микрюков

    Hello. Thanks for interesting blog. I have quastion. How bind org.joda dateTime type from JSON String.

  • Pingback: Modern web: Spring 4 MVC & AngularJS Example | LearncoolTech()

  • Pingback: AngularJS $http service example-server communication - WebSystique()

  • Clebio Vieira

    Hello. I´m from Brasil. Thanks for sharing your time !!!

  • nmpg

    Hi. I’ve been enjoying your tutorials, they’re great :)

    However, I’m having an issue with this one. I always get a Error 404 – Not Found when accessing

    http://localhost:7001/Spring4MVCCRUDRestService/user/

    I using your code as-is. I’m using Weblogic if that matters btw..

    Any idea what I may doing wrong? Or how I can debug this?

    • websystique

      Hi,

      Are you deploying on Weblogic externally or using it from within Eclipse? You might want to go through Setting Tomcat with Eclipse. Although the post is for setting up Tomcat, similar setup should be applicable for other servers/containers. Let me know if the outcome.

      • nmpg

        I’m using Netbeans, and deploying to external Weblogic server (but through Netbeans IDE..). It works just fine with others projects (some from here actually), but for some reason does not work with this one.

        By the way, I just tried http://websystique.com/springmvc/spring-mvc-4-angularjs-example/ and whenever accessing http://localhost:7001/Spring4MVCAngularJSExample/ I get Error 403 –Forbidden..

        I’m not even sure how I can debug this.. Any thoughts on what I may doing wrong?

        • Stone Patterson

          what would i need to change . add . delete. update, etc. if anything at all in order to have this function in IntelliJ?

  • http://junjunguo.com/ guojunjun

    Thanks for the grate tutorial :)

  • http://junjunguo.com/ guojunjun

    hei, websystique

    Thanks for another great tutorial :)

    in the user class there are

    “`

    @Override

    public int hashCode() {

    final int prime = 31;

    int result = 1;

    result = prime * result + (int) (id ^ (id >>> 32));

    return result;

    }

    @Override

    public boolean equals(Object obj) {

    if (this == obj)

    return true;

    if (obj == null)

    return false;

    if (getClass() != obj.getClass())

    return false;

    User other = (User) obj;

    if (id != other.id)

    return false;

    return true;

    }

    “`

    can you explain what is the purpose of this to methods, what are overrided ?

    Best Greetings

  • badr benabbou

    Hello WebSystique , please i have this error message , i need a help thanks u

    • websystique

      Hey Badr,

      Seems you are missing Spring form taglib(spring-form.tld). Which version of Spring are you using? Do you have spring-webmvc dependency in your pom.xml, as in this post? Did you declare the form taglib in your JSP like shown below?

  • Guilherme Marquesini Reis Ribe

    - When do you call to create the user:
    “URI uri = restTemplate.postForLocation(REST_SERVICE_URI+”/user/”, user, User.class);”
    The method convert a object to JSON ? Where do you set this? Or send other type?

    • websystique

      Hi Guilherme,

      Yes it converts it to JSON. This is due to presence of jackson-databind in classpath. Eventually spring uses inbuilt MappingJackson2HttpMessageConverter to convert to/from json.

      Look at this post to understand the conversion and other possible types.

  • droidark ☭

    Thanks for the tutorial, it’s very helpful for me.

    • websystique

      Glad you liked it.

  • Pingback: Spring MVC @RequestBody @ResponseBody Example - WebSystique()

  • Pingback: Spring 4 MVC REST Service Example using @RestController - WebSystique()