Saturday, February 26, 2011

Spring 3: REST Web Service Provider and Client Tutorial (Part 1)

In this tutorial we'll create a RESTful web service based on Spring 3. We'll be developing a REST provider using URI templates that returns XML and JSON representations of our data. We'll also add basic support for retrieving images and html pages. We'll test our provider via RESTClient to verify the service's availability. In part 2, we'll add an actual client based on RestTemplate and Spring MVC that will access our service.

What is REST?
Representational State Transfer (REST) is a style of software architecture for distributed hypermedia systems such as the World Wide Web. The term Representational State Transfer was introduced and defined in 2000 by Roy Fielding in his doctoral dissertation.

Source: http://en.wikipedia.org/wiki/Representational_State_Transfer

The Representational State Transfer (REST) style is an abstraction of the architectural elements within a distributed hypermedia system. REST ignores the details of component implementation and protocol syntax in order to focus on the roles of components, the constraints upon their interaction with other components, and their interpretation of significant data elements. It encompasses the fundamental constraints upon components, connectors, and data that define the basis of the Web architecture, and thus the essence of its behavior as a network-based application.

Source: Architectural Styles and the Design of Network-based Software Architectures, a dissertation of Roy Thomas Fielding,

REST vs SOAP
Unlike SOAP-based web services, there is no "official" standard for RESTful web services. This is because REST is an architecture, unlike SOAP, which is a protocol. Even though REST is not a standard, a RESTful implementation such as the Web can use standards like HTTP, URL, XML, PNG, etc.

Source: http://en.wikipedia.org/wiki/Representational_State_Transfer

What is REST in Spring 3?
For a great introduction, please see the following links:
- REST in Spring 3: @MVC
- REST in Spring 3: RestTemplate

The Provider

Our application is a simple CRUD system for managing a list of persons. We'll start our project with the provider service which produces XML and JSON representations of our data.

The Domain Layer

We'll be declaring two domain objects: Person and PersonList

Person.java
package org.krams.tutorial.domain;

import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement(name="person")
public class Person {

 private Long id;
 private String firstName;
 private String lastName;
 private Double money;
 
 public Long getId() {
  return id;
 }
 public void setId(Long id) {
  this.id = id;
 }
 public String getFirstName() {
  return firstName;
 }
 public void setFirstName(String firstName) {
  this.firstName = firstName;
 }
 public String getLastName() {
  return lastName;
 }
 public void setLastName(String lastName) {
  this.lastName = lastName;
 }
 public Double getMoney() {
  return money;
 }
 public void setMoney(Double money) {
  this.money = money;
 }
}
Person is a simple POJO consisting of three properties. Notice we've annotated the class name with @XmlRootElement(name="person"). Its purpose is to help JAXB (the one responsible for marshalling/unmarshalling to XML) determine the root of our POJO.

PersonList.java
package org.krams.tutorial.domain;

import java.util.List;

import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement(name="persons")
public class PersonList {

 @XmlElement(required = true)
 public List<person> data;

 @XmlElement(required = false)
 public List<person> getData() {
  return data;
 }

 public void setData(List<person> data) {
  this.data = data;
 }
}
PersonList is another simple POJO. It's purpose is to wrap a list of Person objects.

Ideally we should be able to return a List instead of a PersonList. However, JAXB has difficulties processing java.util.List. A simple Google search verifies this unwanted behavior, for example, http://stackoverflow.com/questions/298733/java-util-list-is-an-interface-and-jaxb-cant-handle-interfaces

To resolve this issue with JAXB, we wrap our List with another object. To learn more about JAXB please visit the following link: http://download.oracle.com/javaee/5/tutorial/doc/bnazf.html

The Controller Layer

The controller layer is the most important section of the provider service because here's where we define the RESTful services available to our clients.

ProviderController.java
package org.krams.tutorial.controller;

import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;

import javax.imageio.ImageIO;
import org.apache.log4j.Logger;
import org.krams.tutorial.domain.Person;
import org.krams.tutorial.domain.PersonList;
import org.krams.tutorial.service.PersonService;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
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.ResponseBody;
import javax.annotation.Resource;

/**
 * REST service provider
 * 
 * Only GET and POST will return values
 * PUT and DELETE will not.
 */
@Controller
@RequestMapping("/provider")
public class RestProviderController {

 protected static Logger logger = Logger.getLogger("controller");
 
 @Resource(name="personService")
 private PersonService personService;
 
 @RequestMapping(value = "/person/{id}", 
        method = RequestMethod.GET,
        headers="Accept=image/jpeg, image/jpg, image/png, image/gif")
 public @ResponseBody byte[] getPhoto(@PathVariable("id") Long id) {
  
  // Call service here
  try {
   // Retrieve image from the classpath
   InputStream is = this.getClass().getResourceAsStream("/bella.jpg"); 
   
   // Prepare buffered image
   BufferedImage img = ImageIO.read(is);
   
   // Create a byte array output stream
   ByteArrayOutputStream bao = new ByteArrayOutputStream();
   
   // Write to output stream
   ImageIO.write(img, "jpg", bao);
   
   logger.debug("Retrieving photo as byte array image");
   return bao.toByteArray();
   
  } catch (IOException e) {
   logger.error(e);
   throw new RuntimeException(e);
  }
 }
    
    @RequestMapping(value = "/person/{id}", 
        method = RequestMethod.GET, 
        headers="Accept=application/html, application/xhtml+xml")
 public String getPersonHTML(@PathVariable("id") Long id, Model model) {
     logger.debug("Provider has received request to get person with id: " + id);
  
  // Call service to here
  model.addAttribute("person",personService.get(id));
  
  return "getpage";
 }
    
 @RequestMapping(value = "/persons", 
        method = RequestMethod.GET, 
        headers="Accept=application/xml, application/json")
 public @ResponseBody PersonList getPerson() {
  logger.debug("Provider has received request to get all persons");
  
  // Call service here
  PersonList result = new PersonList();
  result.setData(personService.getAll());
  
  return result;
 }
 
    @RequestMapping(value = "/person/{id}", 
           method = RequestMethod.GET, 
           headers="Accept=application/xml, application/json")
 public @ResponseBody Person getPerson(@PathVariable("id") Long id) {
     logger.debug("Provider has received request to get person with id: " + id);
     
     // Call service here
  return personService.get(id);
    }
    
    @RequestMapping(value = "/person", 
           method = RequestMethod.POST, 
           headers="Accept=application/xml, application/json")
 public @ResponseBody Person addPerson(@RequestBody Person person) {
     logger.debug("Provider has received request to add new person");
     
     // Call service to here
     return personService.add(person);
    }
    
    
    @RequestMapping(value = "/person/{id}", 
           method = RequestMethod.PUT, 
           headers="Accept=application/xml, application/json")
 public @ResponseBody String updatePerson(@RequestBody Person person) {
     logger.debug("Provider has received request to edit person with id: " + id);
     
     // Call service here
     person.setId(id);
     return personService.edit(person).toString();
    }
    
    
    @RequestMapping(value = "/person/{id}", 
           method = RequestMethod.DELETE,
           headers="Accept=application/xml, application/json")
 public @ResponseBody String deleteEmployee(@PathVariable("id") Long id) {
     logger.debug("Provider has received request to delete person with id: " + id);
 
     // Call service here
     return personService.delete(id).toString();
    }
}

The URI Templates
Our controller has seven methods available. The first four are GET methods while the last three are POST, PUT, and DELETE methods.

The four GET methods correspond to the following:

1. Retrieving a single image based on a specific id
URL: http://localhost:8080/spring-rest-provider/krams/person/{id} 
Method: GET
Accept Header: image/jpeg, image/jpg, image/png, image/gif

2. Retrieving an HTML page based on a specific id
URL: http://localhost:8080/spring-rest-provider/krams/person/{id}
Method: GET
Accept Header: application/html, application/xhtml+xml

3. Retrieving an XML or JSON containing a list of persons
URL: http://localhost:8080/spring-rest-provider/krams/person
Method: GET
Accept Header: application/xml, application/json

4. Retrieving an XML or JSON containing a single person
URL: http://localhost:8080/spring-rest-provider/krams/person/{id}
Method: GET
Accept Header: application/xml, application/json

The last three methods correspond to the remaining CRUD services:

5. Adding a new person via XML and JSON
URL: http://localhost:8080/spring-rest-provider/krams/person
Method: POST
Accept Header: application/xml, application/json

6. Editing an existing person via XML and JSON
URL: http://localhost:8080/spring-rest-provider/krams/person/{id}
Method: PUT
Accept Header: application/xml, application/json

7. Deleting an existing person via its id
URL: http://localhost:8080/spring-rest-provider/krams/person/{id}
Method: DELETE
Accept Header: application/xml, application/json

HTTP Methods
Notice for most of the methods, we're just reusing the same URL http://localhost:8080/spring-rest-provider/krams/person and the only part that differs are the suffix {id} and the HTTP methods:

Method Purpose
GET Retrieves a representation of the requested resource
POST Creates a new representation of the requested resource
PUT Updates an existing representation of the requested resource
DELETE Deletes an existing representation of the requested resource

The Service Layer

The service layer is the one that does the actual processing of data. Here we're just managing an in-memory list to make the tutorial simpler to understand. Translating this to a real database isn't really that difficult

PersonService.java
package org.krams.tutorial.service;

import java.util.ArrayList;
import java.util.List;
import org.apache.log4j.Logger;
import org.krams.tutorial.domain.Person;
import org.springframework.stereotype.Service;

@Service("personService")
public class PersonService {

 protected static Logger logger = Logger.getLogger("service");
 
 // In-memory list
 private List<Person> persons = new ArrayList<Person>();
 
 public PersonService() {
  logger.debug("Init database");
  
  // Create in-memory list
  Person person1 = new Person();
  person1.setId(0L);
  person1.setFirstName("John");
  person1.setLastName("Smith");
  person1.setMoney(1000.0);
  
  Person person2 = new Person();
  person2.setId(1L);
  person2.setFirstName("Jane");
  person2.setLastName("Adams");
  person2.setMoney(2000.0);
  
  Person person3 = new Person();
  person3.setId(2L);
  person3.setFirstName("Jeff");
  person3.setLastName("Mayer");
  person3.setMoney(3000.0);
  
  persons.add(person1);
  persons.add(person2);
  persons.add(person3);
 }
 
 /**
  * Retrieves all persons
  */
 public List<Person> getAll() {
  logger.debug("Retrieving all persons");
  
  return persons;
 }
 
 /**
  * Retrieves a single person
  */
 public Person get( Long id ) {
  logger.debug("Retrieving person with id: " + id);
  
  for (Person person:persons) {
   if (person.getId().longValue() == id.longValue()) {
    logger.debug("Found record");
    return person;
   }
  }
  
  logger.debug("No records found");
  return null;
 }
 
 /**
  * Adds a new person
  */
 public Person add(Person person) {
  logger.debug("Adding new person");
  
  try {
   // Find suitable id
   Long newId = 0L;
   Boolean hasFoundSuitableId = false;
   while(hasFoundSuitableId == false) {
    for (int i=0; i <persons.size(); i++) {
     if (persons.get(i).getId().longValue() == newId.longValue()) {
      newId++;
      break;
     }
     
     // Exit while loop
     if(i==persons.size()-1) {
      logger.debug("Assigning id: " + newId);
      hasFoundSuitableId = true;
     }
    }
   }
   
   // Assign new id
   person.setId(newId);
   // Add to list
   persons.add(person);
   
   logger.debug("Added new person");
   return person;
  } catch (Exception e) {
   logger.error(e);
   return null;
  }
 }
 
 /**
  * Deletes an existing person
  */
 public Boolean delete(Long id) {
  logger.debug("Deleting person with id: " + id);
  
  try {
   for (Person person:persons) {
    if (person.getId().longValue() == id.longValue()) {
     logger.debug("Found record");
     persons.remove(person);
     return true;
    }
   }
   
   logger.debug("No records found");
   return false;
   
  } catch (Exception e) {
   logger.error(e);
   return false;
  }
 }
 
 /**
  * Edits an existing person
  */
 public Boolean edit(Person person) {
  logger.debug("Editing person with id: " + person.getId());
  
  try {
   for (Person p:persons) {
    if (p.getId().longValue() == person.getId().longValue()) {
     logger.debug("Found record");
     persons.remove(p);
     persons.add(person);
     return true;
    }
   }
   
   logger.debug("No records found");
   return false;
   
  } catch (Exception e) {
   logger.error(e);
   return false;
  }
 }
}

Configuration

Configuring REST support in Spring isn't really different from configuring your usual Spring MVC. That's because REST in Spring are additional "features to Spring MVC itself" (See Rest in Spring 3: @MVC blog).

Here are all the XML configurations we're using for this project.

web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app id="WebApp_ID" version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
 
 <servlet>
  <servlet-name>spring</servlet-name>
  <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
  <load-on-startup>1</load-on-startup>
 </servlet>
 
 <servlet-mapping>
  <servlet-name>spring</servlet-name>
  <url-pattern>/krams/*</url-pattern>
 </servlet-mapping>

 <listener>
  <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
 </listener>
 
</web-app>

spring-servlet.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xmlns:p="http://www.springframework.org/schema/p" 
 xsi:schemaLocation="http://www.springframework.org/schema/beans 
      http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
 
 <!-- Declare a view resolver -->
 <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver" 
      p:prefix="/WEB-INF/jsp/" p:suffix=".jsp" />

</beans>

applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
 xmlns:context="http://www.springframework.org/schema/context"
 xmlns:mvc="http://www.springframework.org/schema/mvc"
 xsi:schemaLocation="http://www.springframework.org/schema/beans 
      http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
      http://www.springframework.org/schema/context
      http://www.springframework.org/schema/context/spring-context-3.0.xsd
   http://www.springframework.org/schema/mvc 
   http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd">
 
 <!-- Activates various annotations to be detected in bean classes -->
 <context:annotation-config />
 
 <!-- Scans the classpath for annotated components that will be auto-registered as Spring beans.
  For example @Controller and @Service. Make sure to set the correct base-package-->
 <context:component-scan base-package="org.krams.tutorial" />
 
 <!-- Configures the annotation-driven Spring MVC Controller programming model.
 Note that, with Spring 3.0, this tag works in Servlet MVC only!  -->
 <mvc:annotation-driven />

</beans>

Run the Application

To run the application, you'll need a client application, like a browser. Also you must access directly the URLs to reach a specific action.

Browser Issues

By default, you can only send a GET request in your browser without resorting to special plugins or tools. When you type a URL in the browser's address field, you're actually specifying a GET request. Using a browser we can only retrieve XML and HTML representations of our GET request (again without resorting to special plugins). Try it out and see what your browser will return.

On Chrome, typing the following URL
http://localhost:8080/spring-rest-provider/krams/person/1
yields an XML document:

On Firefox, typing the following URL
http://localhost:8080/spring-rest-provider/krams/person/1
yields an HTML document:

Testing with RESTClient

Using a browser we can only test the GET portion of the REST service. To fully test all methods, either we write a client application or reuse an existing client. Luckily for us there's a great Java client: RESTClient

What is RESTClient?
RESTClient is a Java application to test RESTful webservices. It can be used to test variety of HTTP communications. From version 2.3 Beta 1, it has two executable Jars:

- GUI version (restclient-ui-X.jar download)
- Cli version for batch execution of .rcq files (restclient-cli-X.jar download)

Source: http://code.google.com/p/rest-client/

Let's start by running RESTClient

Retrieve a single record (GET method)

1. To retrieve a record, select the GET method:

2. Click the Headers tab and enter the following information:
Key:  Accept
Value: application/xml or application/json


Make sure to hit the plus button to enter the values:

3. Enter the following URL:
http://localhost:8080/spring-rest-provider/krams/person/1
You should see the following results depending on the Accept header you provided earlier:

XML result

JSON result

Add a new record (POST method)

1. Under the Method tab, select the POST method.

2. Under the Headers tab, enter the following information:
Key:  Accept
Value: application/xml or application/json

3. Under the body tab, enter the following content (depending on the value field in step #2)
XML:
<person>
    <firstName>Roy</firstName>
    <lastName>Jones</lastName>
    <money>5000</money>
</person>
JSON:
{
  "firstName":"Roy"
  "lastName":"Jones"
  "money":5000
}

4. Enter the following URL:
http://localhost:8080/spring-rest-provider/krams/person
You should see the following results depending on the Accept header you provided earlier:
XML:
<?xml version="1.0" encoding="UTF-8"?>
<person>
    <firstName>Roy</firstName>
    <lastName>Jones</lastName> 
    <money>5000.0</money>
</person>
JSON:
{
  "firstName" : "Roy",
  "lastName" : "Jones",
  "money" : 5000.0
}

Update an existing record (PUT method)

1. Under the Method tab, select the PUT method.

2. Under the Headers tab, enter the following information:
Key:  Accept
Value: application/xml or application/json

3. Under the body tab, enter the following content (depending on the value field in step #2)
XML:
<person>
    <firstName>Roy</firstName>
    <lastName>Jones</lastName>
    <money>5000</money>
</person>
JSON:
{
  "firstName":"Roy",
  "lastName":"Jones",
  "money":5000
}

4. Enter the following URL:
http://localhost:8080/spring-rest-provider/krams/person
You should see the following results depending on the Accept header you provided earlier:
XML:
true
JSON:
true
This means we've successfully updated record #1 with the new information we've provided. To verify if the record has been updated, create a GET request with the following URL:
http://localhost:8080/spring-rest-provider/krams/provider/person/1
Notice the number 1 at the end. That's the same number we used in the PUT method. You should see the updated record.

Delete an existing record (DELETE method)

1. Under the Method tab, select the DELETE method.

2. Under the Headers tab, enter the following information:
Key:  Accept
Value: application/xml or application/json

3. Enter the following URL:
http://localhost:8080/spring-rest-provider/krams/person/1
You should see the following results depending on the Accept header you provided earlier:
XML:
true
JSON:
true
This means we've successfully deleted record #1. To verify if the record has been deleted, create a GET request with the following URL:
http://localhost:8080/spring-rest-provider/krams/provider/person/1

Notice the number 1 at the end. That's the same number we used in the DELETE method. You should see an empty result.

Conclusion

That's it. We've managed to create a REST service using Spring 3. We've also shown how we can retrieve different representations of our resource by using a unified URL with varying HTTP methods. We've also tested the application using RESTClient. In Part 2 of the tutorial, we'll explore how to develop a client application using Spring's RestTemplate support.

To see Part 2 of this tutorial, click the following link: Spring 3: REST Web Service Provider and Client Tutorial (Part 2)

Download the project
You can access the project site at Google's Project Hosting at http://code.google.com/p/spring-rest-guide/

You can download the project as a Maven build. Look for the spring-rest-provider.zip in the Download sections.

You can run the project directly using an embedded server via Maven.
For Tomcat: mvn tomcat:run
For Jetty: mvn jetty:run

If you want to learn more about Spring MVC and integration with other technologies, feel free to read my other tutorials in the Tutorials section.
StumpleUpon DiggIt! Del.icio.us Blinklist Yahoo Furl Technorati Simpy Spurl Reddit Google I'm reading: Spring 3: REST Web Service Provider and Client Tutorial (Part 1) ~ Twitter FaceBook

Subscribe by reader Subscribe by email Share

233 comments:

  1. Hi Karam,

    please provide RestClient(part 2) application with Json object
    its very urgent for me


    ** Restful webservices with Json ***



    Thanks
    venkat

    ReplyDelete
  2. This comment has been removed by the author.

    ReplyDelete
  3. One more question is how to handle One to Many relation ships in JAXB? If I have two JPA entities, with One to Many relation ship how to write JAXB annotaions on these entities?

    ReplyDelete
  4. @Srinivas, I believe you just need to write the @XmlRootElement annotation at the top of the class. @ResponseBody will marshall them to their equivalent XML form.

    ReplyDelete
  5. This comment has been removed by the author.

    ReplyDelete
  6. I haven't seen any of the MessageConverter configured (MappingJacksonHttpMessageConverter,MarshallingHttpMessageConverter), Jaxb2Marshaller.
    Don't we require this configuration?

    ReplyDelete
  7. Hi,

    why i need to declare a viewResolver in spring-servlet.xml if i dont need the .jsp pages but just wanna retrive data as xml ??

    ReplyDelete
  8. @whiteshade, the simple answer is you don't need to if your application doesn't need one.

    ReplyDelete
  9. This comment has been removed by the author.

    ReplyDelete
  10. Excellent tutorial ! Keep up the good work and thank you.

    ReplyDelete
  11. hi can you add src of this project?
    Great totorial...

    ReplyDelete
  12. one stupid question.. I'm using maven and what kind of project i need to create? and with which architype? Thanks....

    ReplyDelete
  13. Great showcase Krams!

    I can get the GET and DELETE to work. But when it comes to PUT and POST I keep getting HTTP Status 415 - The server refused this request because the request entity is in a format not supported by the requested resource for the requested method.

    I guess what it is saying is part of the request was in an unsupported format.

    Does this have something to do with the HTTP request headers when posting. I read somewhere that clients should only send Content-type headers on POST and PUT requests.

    Anyway I'll keep fiddling to see if I can get it to work.

    ReplyDelete
  14. My Bad! I had to add a Request Header Content-Type application/xml. =)

    ReplyDelete
  15. Thank you for everything!!! Great job!!!

    ReplyDelete
  16. Hi,

    I am getting the following exception with this example. Am I missing any particular JARs or is there any other reason for this error ??
    Please advise.

    The error stack is:

    org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'restProviderController' defined in file [C:\Program Files\IBM\WebSphere\AppServer\profiles\AppSrv01\installedApps\sapanigr-wxpNode01Cell\PersonDataServiceSpringRestful.ear\TableDataServiceSpringRestful.war\WEB-INF\classes\com\cisco\bic\services\controller\RestProviderController.class]: Post-processing failed of bean type [class com.cisco.bic.services.controller.RestProviderController] failed; nested exception is java.lang.TypeNotPresentException: Type javax.annotation.Resource not present
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyMergedBeanDefinitionPostProcessors(AbstractAutowireCapableBeanFactory.java:803)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:493)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:456)
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:291)

    ReplyDelete
  17. Hi,

    I am getting the JAXB error while stting up the application.

    Please help. The error stack is--

    [12/10/11 14:12:34:366 IST] 00000020 ServletWrappe E SRVE0068E: Uncaught exception thrown in one of the service methods of the servlet: spring. Exception thrown : org.springframework.web.util.NestedServletException: Request processing failed; nested exception is org.springframework.http.converter.HttpMessageConversionException: Could not instantiate JAXBContext for class [class com.bic.services.model.CountryList]: 1 counts of IllegalAnnotationExceptions; nested exception is com.sun.xml.bind.v2.runtime.IllegalAnnotationsException: 1 counts of IllegalAnnotationExceptions
    Class has two properties of the same name "data"
    this problem is related to the following location:
    at public java.util.List com.bic.services.model.CountryList.getData()
    at com.bic.services.model.CountryList
    this problem is related to the following location:
    at public java.util.List com.cisco.bic.services.model.CountryList.data
    at com.cisco.bic.services.model.CountryList

    ReplyDelete
  18. @Saroj, take a carefull look at the exception. It says "Class has two properties of the same name "data"". Make sure to rename one of them.

    ReplyDelete
  19. Great tutorial on both client and provider - simple and works great!!!! Thank you much for this. Saved me a lot of work.

    Ade.

    ReplyDelete
  20. Hi everyone,Thank you very much for this tuto. I want to know how tu use this REST for an android client side.thank you for everything

    ReplyDelete
  21. @xavi, I haven't looked at Android development yet. But you should watch the latest video for Spring Android development which contains samples for accessing services via RestTemplate. See www.springsource.org. Here's the direct link: http://www.springsource.org/node/3505

    ReplyDelete
  22. Very Good!!!
    Thx!!!

    ReplyDelete
  23. This is a fantastic tutorial! All of the books on Spring WS are useless. This tutorial is far better then any book. Excellent work!

    ReplyDelete
  24. Hi krams, very nice tutorial. May I ask if it is possible to get the server's response header in the controller? Can you please provide an example? Kindly please email me at dcrow_14@yahoo.com.ph. Many thanks! :)

    ReplyDelete
  25. Hi karams i like the tutorial ,But is it possible to use a database here
    i need to register the data in database .can you hel me .thanks a lot .

    ReplyDelete
    Replies
    1. sarah, sure you can. You just need to change the PersonService implementation and call your data access layer, i.e DAO or Repository. If you want you can also make your JDBC calls within the PersonService

      Delete
  26. Add a new record (POST method)
    1. Under the Method tab, select the POST method.

    2. Under the Headers tab, enter the following information:

    Key: Accept
    Value: application/json


    3. Under the body tab, enter the following content

    {
    "firstName":"Roy"
    "lastName":"Jones"
    "money":5000
    }


    4. Enter the following URL:

    http://localhost:8080/spring-rest-provider/krams/person

    i get the following output

    {"id":25,"money":null,"lastName":null,"firstName":null}

    please help.. All the values are comng null.

    ReplyDelete
    Replies
    1. But if i submit data with "application/x-www-form-urlencoded" format, it works
      {"id":27,"money":10.0,"lastName":"pat","firstName":"hirale"}

      Delete
    2. Url
      http://localhost:8080/automation_console_version_1/provider/person

      POST

      Content-Type: application/json

      {
      "firstName" : "jATIN",
      "lastName" : "PATEL",
      "money" : 25000.0
      }

      WORKED

      Delete
  27. hi after inserting or updating records how to pass like "isSucess" : true
    in restclent ui can any one give idea

    ReplyDelete
  28. Hi,
    I am new here, tried to follow this nice tutorial, adding an xml user (POST) works, but adding a json user (POST) is not working :

    Add a new record (POST method)
    1. Under the Method tab, select the POST method.

    2. Under the Headers tab, enter the following information:

    Key: Accept
    Value: application/json


    3. Under the body tab, enter the following content

    {
    "firstName":"Roy"
    "lastName":"Jones"
    "money":5000
    }


    4. Enter the following URL:

    http://localhost:8080/spring-rest-provider/krams/person

    Status : HTTP/1.1 400 Bad Request

    ...
    The request sent by the client was syntactically incorrect ().
    ....

    Please your help is appreciated.

    ReplyDelete
    Replies
    1. Hello,

      You're missing the commas in the XML. Try this:

      {
      "firstName":"Roy",
      "lastName":"Jones",
      "money":5000
      }

      Delete
  29. Hi,

    I am getting the JAXB error while stting up the application.

    Please help. The error stack is--

    .springframework.web.util.NestedServletException: Request processing failed; nested exception is org.springframework.http.converter.HttpMessageConversionException: Could not instantiate JAXBContext for class [class com.sample.provider.PersonList]: 1 counts of IllegalAnnotationExceptions; nested exception is com.sun.xml.bind.v2.runtime.IllegalAnnotationsException: 1 counts of IllegalAnnotationExceptions
    Class has two properties of the same name "list"
    this problem is related to the following location:
    at public java.util.ArrayList com.sample.provider.PersonList.getList()
    at com.sample.provider.PersonList
    this problem is related to the following location:
    at public java.util.ArrayList com.sample.provider.PersonList.list
    at com.sample.provider.PersonList

    Could you please help on this.which class property I need to change.

    ReplyDelete
  30. please provide a example using hibernate ...need to retrive data from table and also insert data in table using web service in spring...the request data will come as a xml, then this xml data need to insert in db..

    ReplyDelete
  31. Hi

    I am able to compile and deploy this application using maven,but when I enter url http://localhost:8080/spring-rest-provider/krams/person/1 in crome I get 404 error.

    Kindly help me in resolving this issue as I have already spent lot of time on it.

    ReplyDelete
  32. Hi good stuff. But i want to have webservice using Mysql database. What are the changes to do for this example. Its very urgent . Can you please tell me or suggest me a link where i can get info.

    ReplyDelete
  33. Hi karams i like the tutorial ,But i need to register the data in database .can you help me. Please post what are the changes in personservice and controller class. I am using Mysql . Please post.I am very glad if u post.

    ReplyDelete
  34. Hi Karam, Very helpful Tutorial. Also I have implemented ACL in my Java/Spring web application. Now I would like to implement REST with ACL. If user have access READ rights, then user can access GET, if user have access ADD,EDIT then user can access PUT,POST. I dont want to create new ACL database, same database I would like to use in REST web services.

    I would be appreciated if you help me.

    ReplyDelete
  35. Hi! First of all I would like to state the fact that you actually have built a cool resource. And there is also one thing I would like to ask you. Do you have an idea to write in a professional way or owning a blog is just a hobby of yours?

    ReplyDelete
  36. I think most people would do the same when they are headed with the situation.

    ReplyDelete
  37. how can we get the response depending upon our requirement in a browser like json or xml.

    ReplyDelete
  38. This is so good to see that you are in the press. This is so good for your promotion. You want to see more of this in the future. Namitha hot

    ReplyDelete
  39. To those getting this error:
    Class has two properties of the same name "data"

    Just remove the annotation on the class members (instance variables and methods) and you're good to go.

    ReplyDelete
  40. hi.....very nice article.....can you please provide the client code to consume it....it would be very helpful for me....

    ReplyDelete
  41. Thank you very much

    ReplyDelete
  42. I am getting below error

    HTTP Status 405 - Request method 'GET' not supported

    only first method i am able to execute.

    ReplyDelete
  43. I followed all the steps as mentioned above but getting Http status -404 . please help me to solve this problem.

    ReplyDelete
  44. Great work!
    Is there a way to find out the clients url in my service provider?
    Cheers,
    Magnus

    ReplyDelete
  45. Well said, the post is really the freshest on this valuable topic. I fit in with your conclusions and will thirstily look forward to your next updates host a website | hosting

    ReplyDelete
  46. A web development company can offer your business not only web development services but, also a range of other services which can take your company to the very top. However, most importantly, these companies can offer you with a team of highly skilled web designers who can design the very best page for your company.

    ReplyDelete
  47. This is so good to see that you are in the press. This is so good for your promotion. You want to see more of this in the future..


    website designing companies | website development company

    ReplyDelete
  48. Application Service Provider- RKM IT services is one of the leading application service provider company located in India. We offer federal Communications Commission, Internet service provider, VoIP service providers, apps provider and much more at affordable rates.

    ReplyDelete
  49. Wow..its the great information for my developer team so i have a shared my team because its the useful information thank you for sharing the great information..
    Web Design Services Bangalore | Web Development Services Bangalore

    ReplyDelete
  50. Hi karams i just like the tutorial ,But i need to register the data in database .can you facilitate me. Please post what are the changes in personservice and controller category. I am using Mysql . Please post.I am terribly glad if u post.
    10 extra earning apps

    ReplyDelete
  51. Application Service Providers -An ASP (Application Service Provider) is a firm that provide applications - software - through the Internet and charges a monthly/ annually fee. Mostly, software is sold. You physically get a CD or DVD and you install it on your hard drive or your office's server. ASPs don't work this way. They deliver software as a monthly/ annually service and use the Internet as the medium.

    ReplyDelete
  52. Thanks for sharing this very nice discussion. While choosing a good web hosting services for your business lots of things to consider and this blog very well explained it. You must Continue posting such great information about web hosting and related stuffs. best web hosting.

    ReplyDelete
  53. Thanks for sharing your info. I really appreciate your efforts and I will be waiting for your further write
    Kizi 123|
    Friv 234|
    Friv|

    ReplyDelete
  54. Accuratesolutions Mobile-Anwendung Entwicklungsunternehmen . Eastern Apps ist ein führender mobile Anwendungen Entwicklungsunternehmen hoch Know-how in iPhone, Windows und Android- Apps.

    ReplyDelete
  55. Application Service Provider - Application Services Providers are changing the face of the meeting planning software and IT industry providing software as a service rather than a product. If you need any kind of Application Services then contact us.

    ReplyDelete
  56. Nice post. I learn something more challenging on different blogs every day. It will always be stimulating to read content from other writers and practice a little something from their store

    ReplyDelete
  57. Thank you for sharing the valuable information about website design and development services..

    Best Website Designing Services Bangalore | Best Website Development Companies Bangalore

    ReplyDelete
  58. Thanks for sharing about Spring 3 rest web services providers...........

    CompAddicts

    ReplyDelete

  59. Delhi is a center of delights for fun lovers and for those who want to enjoy each and every moment of life. If are you planning for a holiday celebration around Delhi then you have reached the very right place. ResortsNearDelhi.co.in, a Division of ‘COMFORT YOUR JOURNEY PVT LTD’ avails you the options for Weekend Getaways Near Delhi.
    visit: http://www.bestholidaystrip.com/

    ReplyDelete
  60. New Year 2017 is an event of pleasures. So we should praise it together with charming and a brilliant flavoring of move gathering, boundless beverages, mixed drink, barkeeps, bucketful of snacks, commencement to be the most energizing one and exquisite scrumptious food stuff with New Year bundles close Delhi.
    visit: http://newyearpackagesneardelhi.com/

    ReplyDelete
  61. Observe New Year's Eve in style by heading out to experience it in one of the world's most energizing goals with British Airways. Mark the commencement to 2017 with a New Year's Eve break to one of the numerous urban areas we travel to overall, for example, Edinburgh, New York, Rio or Sydney, and wake up to a radical new view on New Year's Day. Visit: New year Packages Near Delhi

    ReplyDelete
  62. Observe New Year's Eve in style by heading out to experience it in one of the world's most energizing goals with British Airways. Mark the commencement to 2017 with a New Year's Eve break to one of the numerous urban areas we travel to overall, for example, Edinburgh, New York, Rio or Sydney, and wake up to a radical new view on New Year's Day. visit: New year Packages 2017

    ReplyDelete
  63. New Year 2017 is an event of pleasures. So we should praise it together with charming and a brilliant flavoring of move gathering, boundless beverages, mixed drink, barkeeps, bucketful of snacks, commencement to be the most energizing one and exquisite scrumptious food stuff with New Year bundles close Delhi.
    Visit: New Year Packages

    ReplyDelete
  64. Making tracks in an opposite direction from the furious life in the city for the most part requires a ton of arranging. You have to take some time off work, make appointments furthermore make sense of what you need to do amid your get-away. All things considered, not any longer. Visit: Day Packages Around Delhi

    ReplyDelete
  65. Games are games of human intelligence.
    Join experienced talent with me yet! What are you waiting for?
    age of war 2
    gold Miner 2
    unfair Mario 2
    cubefield 2
    tanki Online 2

    ReplyDelete

  66. Tree House Resort, Jaipur - World's biggest, most special, 5 Star and Luxury Tree House. Situated on "trees", the tree have a few live branches going through the rooms making nature all inclusive in the Lap of extravagance at Tree House Jaipur. Jaipur Airport is 40 km from Tree House Resort. The eco-accommodating resort, arranged in the foothills of Syari Valley, with a flawless perspective of Aravalli Mountains.
    visit: Tree House Resorts Jaipur

    ReplyDelete

  67. Tree House Resort, Jaipur - World's greatest, most extraordinary, 5 Star and Luxury Tree House. Arranged on "trees", the tree have a couple live branches experiencing the rooms making nature comprehensive in the Lap of indulgence at Tree House Jaipur. Jaipur Airport is 40 km from Tree House Resort. The eco-obliging resort, masterminded in the foothills of Syari Valley, with an immaculate viewpoint of Aravalli Mountains. Visit: Tree House Jaipur

    ReplyDelete
  68. I haven't seen any of the MessageConverter configured (MappingJacksonHttpMessageConverter,MarshallingHttpMessageConverter), Jaxb2Marshaller.
    Don't we require this configuration

    ReplyDelete
  69. Great post. This article is really very interesting and enjoyable. I think its must be helpful and informative for us. Thanks for sharing your nice post. Web Technology Company in Chennai

    ReplyDelete
  70. The blog or and best that is extremely useful to keep I can share the ideas of the future as this is really what I was looking for, I am very comfortable and pleased to come here. Thank you very much.

    FORZA HORIZON 3 PC TORRENT

    ReplyDelete
  71. Thank you for sharing such an informative news with us. Keep on sharing Contents like this. You can also share this content on various sites like the Automation Associates LLC site.

    ReplyDelete
  72. Great post, and I am glad that you shared this useful info with us. This blog is very helpful. You can also share this Information on many other sites for example like Free Samples, a clean business site like OS Business Opportunities swiftly followed by Jfissures and Asaimjapan and also the Johny Adams site.

    ReplyDelete
  73. Beautiful post I've come across today. Worth the time. You can also share these post in different social medias to get a higher ground like Facebook, the famous media Twitter and in the LinkedIn profiles joined by Google Plus and the Infographic sharing Site Pinterest.

    ReplyDelete
  74. Thanks for sharing this imformative blog..... Click To Call services provider in India enable the business to enhance leads through the website visitors. Through this service, you can interact with the right customer service agent and website visitors, instantly and serve as an efficient customer service provider.

    ReplyDelete
  75. great article, I was very impressed about it, wish you would have stayed next share
    Facebook Lite | Baixar Facebook | whatsapp baixar| Outlook Entrar

    ReplyDelete
  76. Thanks for sharing this data. Return again for all the more fascinating stuff like this post. You can share this enlightening post in Social Media sites like the overall celebrated Facebook, the unsurpassed most loved Twitter and a fascinating Google Plus website, business web page Linkedin and furthermore to the Infographic website Pinterest to produce more traffic to your blog entry.

    ReplyDelete
  77. The post is exceptionally useful. It is a joy understanding it. I have also bookmarked you for checking out new posts. You can likewise share this significant substance on different platforms, for example, Blogspot, the popular Wordpress website, the inventive Tumblr web page and furthermore the sites like Medium and the well known Live Journal website.

    ReplyDelete
  78. This comment has been removed by the author.

    ReplyDelete
  79. Nice post. Thanks for sharing and providing such a helpful information. This is really useful.
    IT Company in Lucknow | Software Company in Lucknow

    ReplyDelete
  80. The Representational State Transfer ignores the details of component implementation and protocol syntax and also is a style of software architecture for distributed hypermedia systems such as the World Wide Web.
    But, anyways thanks for this useful information.
    webhostingsuggest.in

    ReplyDelete
  81. Thanks for sharing the needful information!!
    Web hosting

    ReplyDelete
  82. Awesome! This may be one of the most helpful things on the subject I’ve ever read.

    softwareskey.net
    sharesoftware.net
    crackedtools.net
    fulserialkey.com

    ReplyDelete
  83. Hi,

    Thanks for sharing a very interesting article about Spring 3: REST Web Service Provider and Client Tutorial (Part 1). This is very useful information for online blog review readers. Keep it up such a nice posting like this.

    From,
    Maestro Infotech,
    Web Design Company Bangalore

    ReplyDelete
  84. This comment has been removed by the author.

    ReplyDelete
  85. It is my first time I visit here. I found so many entertaining stuff in your blog, Keep sharing.!!
    Advertising Agency

    ReplyDelete
  86. This is the best rest services that you are providing. Thanks. IDM Crack

    ReplyDelete
  87. Nice article. Your effort must be appreciated. Read more: Python training institute in Chennai

    ReplyDelete
  88. thank you admin for sharing this kind of information

    Freemake Video Converter Key

    ReplyDelete
  89. Nice and good article. It is very useful for me to learn and understand easily. Thanks for sharing your valuable information and time. Please keep updatingmulesoft online training

    ReplyDelete
  90. Amazing Article ! I have bookmarked this article page as i received good information from this. All the best for the upcoming articles. I will be waiting for your new articles. Thank You ! Kindly Visit Us @ Coimbatore Travels | Ooty Travels | Coimbatore Airport Taxi | Coimbatore taxi | Coimbatore Taxi

    ReplyDelete
  91. THANKS FOR INFORMATION

    you can search low-cost website with high-quality website functions.
    Today Join Us
    Call: +91 - 8076909847

    responsive website designing company in delhi

    levantro
    interior designer delhi


    livewebindia
    website designing company

    best seo services in delhi

    Best It Service Provider:

    1. Website Designing And Development.
    2. SEO Services.
    3. Software Development.
    4. Mobile App Development.

    ReplyDelete
  92. Very informative link and very well written. You choose best topic and good information provide.Thank for sharing..
    web development company in noida

    ReplyDelete
  93. Thanks for sharing."
    "Very very informative article and clearly understandable.
    Ad agency | Branding agency

    ReplyDelete
  94. Useful article, If you have any requirement then contact the best provider of Web design services in Bangalore.

    ReplyDelete
  95. Assuredly beneficial piece of content published by you. I am sure this might turn out to be advantageous for many visitors. Professional Web design services are provided by W3BMINDS- Website designer in Lucknow.
    Web development Company | Web design company

    ReplyDelete
  96. First this is a really Creative and Unique Article. Well, the main reason of me sharing my post here is that, We being the Digital Marketing Company In India are open for Partnerships with Mobile App Development, Website Development and Graphics related company !

    Get in touch with the Digital Marketing Services In India for more information

    ReplyDelete
  97. This comment has been removed by the author.

    ReplyDelete
  98. Fabulous post, many of new and important information you are sharing in this article. i learn many new points in this article. Website maker in india | website developer in india | website design company in india

    ReplyDelete
  99. Hey Thanks for sharing this valuable information with us to grow a Successful Business Online. This nice sharing of knowledge will help me in establishing my business online. I will come back to your site and keep sharing this information with us.
    Laboratory glassware

    ReplyDelete
  100. The post is really good, we will use above mentioned strategy in our ecommerce website development company in Bangalore

    ReplyDelete
  101. Music has always been a significant part of human life. Over time, the technologies for creating music have changed, solocareer itself has also changed.

    ReplyDelete
  102. I am following your blog consistently and got extraordinary data. Continue Sharing !!
    Advertising Agencies in Gurgaon

    ReplyDelete
  103. This comment has been removed by the author.

    ReplyDelete
  104. I have read many of your post and this post is wonderful.... all of your post are just awesome
    Please do visit my website hope you'll like it:
    Best Restraunt in Lucknow
    Best tiffin service near me
    Best Tiffin service in Lucknow
    Best Tiffin Service
    Best Homemade Food

    ReplyDelete
  105. This is really a very good blog post and thanks for sharing it with the community!
    web design company in chennai

    ReplyDelete
  106. Thank You.

    Freshpani is providing online water delivery service currently in BTM, Bangalore you can find more details at Freshpani.com
    Online Water Delivery | Bangalore Drinking Water Home Delivery Service | Packaged Drinking Water | Bottled Water Supplier

    ReplyDelete
  107. very useful post.keep going. all the best for your next article.for further reference refer Web development courses in coimbatore

    ReplyDelete
  108. Thank you for your post here i provide a web service provider that is Tihalt Technologies who is top web designers in Bangalore

    ReplyDelete
  109. This comment has been removed by the author.

    ReplyDelete
  110. This comment has been removed by the author.

    ReplyDelete
  111. Nice! you are sharing such helpful and easy to understandable blog in decoration. i have no words for say i just say thanks because it is helpful for me.

    robotic process automation companies in us
    Robotic Process Automation in us
    machine maintanance in us
    erp in chennai
    mobility software companies in chennai
    erp providers in us

    ReplyDelete
  112. I am looking spring 3 web service do I need to make any changes to code?
    Arooba,
    WEBSITE DEVELOPMENT COMPANY USA

    ReplyDelete
  113. Thank you so much for this wonderful Post and all the best for your future. I hope to see more post from you. I am satisfied with the arrangement of your post.
    shot blasting machine
    shotblasting
    sandblasting
    sand blasting machine
    steel shots distributors
    Sandblasting Abrasive media

    ReplyDelete

  114. Jeewangarg is a one-stop solution for all of your digital marketing needs whether to build your online presence or establish your own brand. We are specialized in building a website, doing Effective SEO for websites and providing the best Google Adwords Services and Digital Marketing Agency to our valuable clients. Though, there are numerous factors that separate us from any other SEO Services in Delhi, here are a few that we believe would not be too much to mention.

    ReplyDelete
  115. Jeewangarg is one of the Best Digital Marketing Agencies where you can find each and every solution under one roof. We are efficient enough to provide our clients the best seo services in Delhi & PPC Services in Delhi at the same place. Moreover, we are the best website designing company in delhi ncr.

    ReplyDelete

  116. Servo Star is a prominent Servo Stabilizer manufacturer, providing a wide range of Servo Voltage stabilizers in India and an array starting from 5 KVA to 5000 KVA for residential, industrial and medical use.

    Isolation Transformer
    Step Down Transformer

    ReplyDelete
  117. Crack Software Free
    Thanx for sharing all latest software. good work man.

    ReplyDelete
  118. Nice Post! Thanks for sharing such an amazing article, really informative,it helps me a lot. For latest Marathi news and updates please visit our website:Marathi Media News

    ReplyDelete
  119. Nice information. Thanks for sharing such an amazing article. For Latest News and updates please visit our website: TV9 Marathi Media News

    ReplyDelete
  120. Nice commenting sites..http://www.webiinnovation.com/website-design-company-bangalore/

    ReplyDelete
  121. I have visited this blog for the first time. but really very good information. thanks for sharing all the good stuff. Technology Company in India

    http://www.webiinnovation.com/

    ReplyDelete
  122. Kerala is the dream destination of all the tourists, adventurers, honeymooners, and visitors. If you also want to book kerala tour packages for family then explore the range of best kerala tour packages with price by Indian Travel Store and select one among a wide range of kerala tour packages which suits your budget and requirements.
    goa tour packages

    ReplyDelete
  123. Great post I would like to thank you for the efforts you have made in writing this interesting and knowledgeable article. We are top CRM Software | CRM Software Mumbai | CRM Software Provider | CRM Software Pune | Field Management Software | CRM Software India

    ReplyDelete
  124. I think Power BI and web based SOAP services are the best when it comes to providing some crucial tools for analyzing complex business problems.

    Powerbi Read Soap

    ReplyDelete
  125. I am so proud of you and your efforts and work make me realize that anything can be done with patience and sincerity. Well I am here to say that your work has inspired me without a doubt. Here is i want to share
    about mulesoft training online with Free Bundle videos .




    ReplyDelete
  126. This comment has been removed by the author.

    ReplyDelete
  127. Thanks For Sharing wonderful blog & good post. It is really helpful to me, waiting for more new posts.
    Node JS Online training
    Node JS training in Hyderabad



    ReplyDelete
  128. I think Spring,REST API and SOAP are the best tools developed in the IT world to solve extreme and complex IT problems very easily.

    SQL Server Load Soap Api

    ReplyDelete
  129. Thank you for sharing such a great information.Its really nice and informative.hope more posts from you. I also want to share some information recently i have gone through and i had find the one of the best mulesoft tutorial videos

    ReplyDelete
  130. Hey would you mind letting me know which web host you're utilizing? I've loaded your blog in 3 completely different browsers and I must say this blog loads a lot faster then most. Can you suggest a good hosting provider at a honest price? Cheers, I appreciate it!
    San Diego videography

    ReplyDelete
  131. This post is really nice and informative. The explanation given is really comprehensive and informative. mulesoft training hyderabad and mule esb trainingby 08+ years experienced facult.

    ReplyDelete
  132. Iogoos Solution offers the best SEO Services in India with full satisfaction Services. Increase organic traffic to rank your website top on Google search Engine Result Page. We are the top rated SEO Company in India.

    Website Designing Services
    Shopify Development Services
    Digital Marketing Services in India

    ReplyDelete
  133. Altorum Leren, a leading IT, Services Company, specializes in Software Development, Cloud Computing, UX/UI Design, IoT, Artificial Intelligence, Blockchain, DevOps, Front End Web Development, Back End Web Development, Web & Mobile App Development and more. https://www.altorumleren.com/

    ReplyDelete
  134. This is very beautiful blot and nice article thanks. We are the best for Fridge repair Dubai | Refrigerator repair Dubai Abu Dhabi.

    ReplyDelete
  135. All the contents you mentioned in post is too good and can be very useful. I will keep it in mind, thanks for sharing the information keep updating, looking forward for more posts. Thanks.

    Base Metal Tips

    ReplyDelete
  136. I have read your articles many times and I am always inspired by your tips and knowledge. Thank you for sharing.

    Best Equity Cash Tips Provider

    ReplyDelete
  137. thanks for sharing great article blog with us.keep posting like this.We at Fuel digital marketing give you the best eCommerce website development services in Chennai which will give you and your customers a one-stop solution and best-in-class services. We take your ideas and convert it into something simple and professional and that is what makes us one of the top-rated e-commerce development company in Chennai. We help you in gaining new marketing strategies, increase the range of your products which will, in turn, lead to the generation of more sales

    e commerce website development services in chennai | best woocommerce development company | best ecommerce website design company in coimbatore |ecommerce website designing company in chennai and coimbatore | opencart development company in coimbatore | opencart development company in chennai | woocommerce development company in chennai | woocommerce website designing company in chennai

    ReplyDelete
  138. The top course office suite software is effectively regarded to every person. Microsoft Office 2010 Cracks may be to assist all sorts of features and accomplish office linked operations. Its predominant goal is to try to make the office get the job done less difficult. Numerous tools for getting ready the document, shows, excel sheets, notes and so forth. are offered under the software. These tools confirm to generally be useful in lots of office, college, or small business relevant performs. It's turn into a requirement to the current occasions. Still, many people absence the education of its perks and do not activate it. But, it is the most suitable option for each and every office similar give good results. For that reason, it is recommended to acquire it on the system. Which is why it's good to have Microsoft Office 2010 Product key, and right here it is actually at no cost for you personally. https://freeprosoftz.com/microsoft-office-2010-product-key-full-version/

    ReplyDelete
  139. We are an experienced team in one of the Best software company and product specialist for software development and implementation. Sovereign provides Website Design, Web Development and Mobile App Development, Digital marketing and SEO Services.

    Android Development

    ReplyDelete
  140. We are an experienced team in one of the Best software company and product specialist for software development and implementation. Sovereign provides Website Design, Web Development and Mobile App Development, Digital marketing and SEO Services.

    Web Development

    ReplyDelete
  141. Best blog i have ever sean thanks for sharing also read new year party near delhi

    ReplyDelete

  142. I love what you guys tend to be up too. This sort of clever work
    and reporting! Keep up the wonderful works guys I’ve included you
    guys to my personal blogroll.
    corel videostudio crack
    photofiltre studio x crack
    synfig studio crack
    cubase pro crack with keygen free download

    ReplyDelete