이 블로그 검색

Spring 3 RESTful Web Services

Spring 3 provides support for RESTful Web services. In this tutorial we will show you how to implement a RESTful Web service in Spring or, if you want, to expose an existing Spring service as aRESTful Web service. To make things more interesting we are going to continue from where we left of at our previous article aboutSpringGWTHibernateJPAInfinispanHornetQ integration. We are going to use our GWTSpringInfinispanHornetQ project and expose our “employeeService” CRUD functionality as a RESTful Web service. Of course you can follow this article just to be informed on how to expose your Spring services as RESTful Web services.The most popular approach for implementing RESTful Web services is Sun'sJAX-RS specification. There are several projects available that support JAX-RS such asCXF,Jersey,RESTEasy andRestlet. Most of them provide Spring support also. Spring does not directly supportJAX-RS, instead RESTful functionality is added to featureSpring MVC itself.If you are not familiar withSpring MVC framework please consult the appropriate chapter ofSpring documentationhere. For the impatient a brief overview follows.Spring MVC stands for Model View Controller. It helps in building flexible and loosely coupled web applications. The Model – View – Controller design pattern insures separation of concerns (business logic, presentation logic and navigation logic) in a multi-tier web application. "Controllers" are responsible for receiving the request from the user and calling the back – end services. Models are responsible for encapsulating the application data. Views render response back to the user with using the model object. In short :When a request is sent to theSpring MVC Framework the following sequence of events happen.

The “DispatcherServlet” first receives the request

The “DispatcherServlet” consults the “HandlerMapping” and invokes the "Controller" associated with the request

The "Controller" process the request by calling the appropriate service methods and returns a “ModeAndView” object to the “DispatcherServlet”. The “ModeAndView” object contains the model data and the view name

The “DispatcherServlet” sends the view name to a “ViewResolver” to find the actual “View” to invoke

The “DispatcherServlet” passes the model object to the “View” to render the result

The “View” with the help of the model data renders the result and return it back to the user

Enough talk! Lets get our hands dirty!We will need the “cglib” bytecode generation library and “asm” bytecode manipulation framework in order forSpring to properly apply AOP aspects to “Controller” objects. We will use “cglib” version 2.2 that you can download fromhere and “asm” binary distribution that you can download fromhere. Locate asm-all-3.3.jar under /lib/all folder of the “asm” binary distribution and place both asm-all-3.3.jar and cglib-2.2.jar under /war/WEB-INF/lib folder of your project.Finally we will need JacksonJSON processor. We will use version 1.5.3 of the “core” and “mapper” distributions that you can download fromhere. Place both jackson-core-asl-1.5.3.jarand jackson-mapper-asl-1.5.3.jar under /war/WEB-INF/lib folder of your project.We have to take care of dependences for ourEclipse project. The following jars should be included in the Java build path of the project :

org.springframework.web-3.0.1.RELEASE-A.jar

As stated above the “DispatcherServlet” is a single servlet that manages the entire request – handling process. Like any other servlet it needs to be configured in the web deployment descriptor or our application. Locate the “web.xml” file under /war/WEB-INF folder and add the following :

By default the “DispatcherServlet” will look for a file named as “{servlet-name}–servlet.xml” to load theSpring MVC configuration. In our case “dispatcher-servlet.xml”. Here we use the url – pattern as "/restServices/*" in order for the “DispatcherServlet” to handle all incoming requests under the designated pattern only. Create a “dispatcher–servlet.xml” file and place it under /war/WEB-INF folder as shown below :

We set the base-package attribute of the “context:component-scan” configuration element to where ourSpring MVC annotated classes will reside

We use the “tx:annotation-driven” configuration element in order to be able to inject transactional behavior to our MVC classes

The “mvc:annotation-driven” is aSpring 3 configuration element that greatly simplifiesSpring MVC setup. This tag registers the “HandlerMapping” and “HandlerAdapter” required to dispatch requests to your @Controller annotated classes. In addition, it applies sensible defaults based on what is present in your classpath. Such defaults include (among others) :

Support for formatting Number fields with @NumberFormat annotation

Support for formatting Date, Calendar, andJoda Time fields with @DateTimeFormat annotation, if Joda Time is on the classpath

Support for validating @Controller annotated class inputs with @Valid annotation, if aJSR-303 Provider is on the classpath

Create an “endpoints” subpackage under the “server” package of your project. As far asGWT is concerned service endpoints are server side components so all classes must be placed under the “server” package. Under “endpoints” subpackage place the “EmployeeServiceController” class as shown below :

As you can see the “EmployeeServiceController” acts as a wrapper class for the “employeeService” class. We take a reference of the actual service and implement methods that invoke directly the service functionality. To inject “EmployeeServiceController” class with “Controller” functionality we just have to annotate it as such. The @Controller annotation designates that the annotated class is a “Controller” class available for the “DispatcherServlet” to delegate requests to it.At the beginning of this tutorial we spoke of how the “DispatcherServlet” uses “HandlerMappings” to select the appropriate “Controllers” so as to delegate user requests. The @RequestMapping annotation is used for mapping Web requests onto specific handler classes and/or handler methods. So by using the @RequestMapping("/employeeService") annotation at type level we instruct “DispatcherServlet” to delegate all Web requests under the “/employeeService” resource URI to the “EmployeeServiceController” instance. Furthermore we use the @RequestMapping annotation at method level to narrow “DispatcherServlet” delegation to specific operations based on the requested resource URI. You should have noticed the use of the @PathVariable annotation. InSpring 3 the use of URI templates through the @PathVariable annotation is introduced. A URI template is a URI – like string, containing one or more variable names. When these variables are substituted for values, the template becomes a URI. Thus a client HTTP GET request for the “/employeeService/1” resource URI will be delegated to “findEmployee” operation of our “EmployeeServiceController” instance and the value of “employeeId” parameter will be set to 1.NOTE: @RequestMapping will only be processed if a corresponding “HandlerMapping” (for type level annotations) and/or “HandlerAdapter” (for method level annotations) is present in the dispatcher. Thanks toSpring 3 MVC simplifications, the use of “mvc:annotation-driven” configuration element in “dispatcher-servlet.xml” handles all of our configuration needs.At the beginning of this tutorial we spoke of how the “Controller” processes each request by calling the appropriate service methods and returns a “ModeAndView” object to the “DispatcherServlet”. The “ModeAndView” object contains the model data and the view name in order to be properly rendered back to the client. This behavior is not always desirable. In our example for instance we want to serialize service responses right to the HTTP response body. The @ResponseBody annotation can be put on a method and indicates that the return type should be written straight to the HTTP response body (and not placed in a Model, or interpreted as a view name). According to client accepted content type(s) (information derived from the “Accept” HTTP Header field of client request) we will return XML orJSON representations of service replies. For that we use theJAXB marshaller and unmarshaller throughSpring OXM module and the JacksonJSON processor.Lastly, you should notice the “saveEmployee” and “updateEmployee” operations. These two are not @ResponseBody annotated, and return the “redirect:/restServices/employeeService/ + employeeId” String. A “Controller” method can return a “special” String value that issues commands to the “DispatcherServlet”. With the aforementioned redirect command the “DispatcherServlet” will redirect the call to the “Controller” method associated with the specified URI resource (in our case the “findEmployee” operation). Thus when a client issues a “saveEmployee” or “updateEmployee” command will receive as a reply the XML orJSON representation of the “employeeDTO” object just inserted or updated.Below we present the DTO class.

The only thing to notice here is that we have annotated the DTO class with @XmlRootElement annotation in order to be properly marshaled byJAXB marshaller.Thats it! To deploy the web application just copy the /war folder inApache – Tomcat “webapps” folder. You can change the name of the war folder to whatever you like, preferably rename it after the project name e.g. GWTSpringInfinispanHornetQRemotingPrior lunching the application do not forget to create the database schema, here “javacodegeeks”.For this example we have used Apache Derby Database version 10.6.1.0. You can download the binary distributionhere. Locate derby.jar under /lib directory of the distribution and place it under /war/WEB-INF/lib directory of your project. To configure the embedded database withSpring, add the following configuration code to your applicationContext.xml under /war/WEB-INF directory :