Вы находитесь на странице: 1из 74

Spring MVC

Remote Services & Rest APIs

Ging vin hng dn: ThS. Nguyn Trc Thc


Nhm 11: Trn Thanh Hng 14520354
Phan nh Lun 14520495
Nguyn Minh Hiu 14520287
Introduction
WORKING WITH REMOTE SERVICES CREATING REST APIS
o How to expose application objects as remote WITH SPRING MVC
services. How to build RESTful services
o How to transparently access remote services that are focused on
as though theyre any other object in your application resources using
application. Spring MVC.
o Exploring various remoting technologies,
including RMI, Hessian/Burlap, and SOAP web
services with JAX-WS.
1 Working with remote services
Accessing and exposing RMI services
Using Hessian and Burlap services
Working with Springs HTTP invoker
Using Spring with web services
Remote procedure call (RPC) model
Remote Method Hessian or Burlap HTTP invoker JAX-RPC and JAX-
Invocation (RMI) WS

Accessing / Accessing/exposing Accessing/exposing Accessing /


exposing Java- Java-based services Spring-based exposing
based services over HTTP when services when platform-neutral,
when network network constraints network constraints SOAP-based web
constraints such are a factor. are a factor and you services.
as firewalls Hessian is a binary desire Java
arent a factor. protocol, whereas serialization over
Burlap is XML-based. XML or proprietary
serialization.
RMI
Configuring an RMI service in Spring
o Traditional RMI: all of those methods in SpitterService and
in SpitterServiceImpl would need to throw
java.rmi.RemoteException.
Easier way to publish RMI services:
o Instead of writing RMI-specific classes with methods that throw
RemoteException, you write a POJO that performs the
functionality of your service. Spring handles the rest.
o RMI service using Springs RmiServiceExporter, so the
existing implementations will do fine.
Wiring an RMI service
1. Declare the RMI service as a Spring-managed bean,
using RmiProxyFactoryBean.
2. Wire it as a dependency into another bean.
3. Then invoke methods on it as if it were a local bean.
RMIs pros and cons
o The client code doesnt even o RMI has difficulty working
know its dealing with an RMI across firewalls
service. o RMI is Java-based both the
o Easily swap out the remote client and the service must be
service bean with another written in Java
implementation of the service. o RMI uses Java serialization
the types of the objects being
sent across the network must
have the exact same version of
the Java runtime on both sides
of the call.
Hessian and Burlap
Exporting a Hessian service
o Similar to implementing an RMI service in Spring, using
HessianServiceExporter:
it exposes the public methods of a POJO as methods of a
Hessian service
o Different from how RmiServiceExporter exports
POJOs as RMI services
o Dont need to get a serviceName property because
Hessian doesnt have a registry.
Configuring the Hessian controller
o Hessian is HTTP-based, HessianServiceExporter is
implemented as a Spring MVC controller.
Need to perform two additional configuration steps:
Configure a Spring DispatcherServlet in web.xml, and deploy
your application as a web application.
Configure a URL handler in your Spring configuration to
dispatch Hessian service URLs to the appropriate Hessian
service bean.
Configure Springs DispatcherServlet and URL handlers
and Exporting a Burlap service
o First, you need a DispatcherServlet and a servlet
mapping that catches *.service URLs.
o You can configure DispatcherServlet
1. By implementing WebApplicationInitializer
2. By extending AbstractDispatcherServletInitializer or
AbstractAnnotationConfigDispatcherServletInitializer
o The only differences between this bean and its Hessian
counterpart are the bean method and the exporter class.
Accessing Hessian/Burlap services
o Switching from an RMI client to a Hessian client is
extremely easy, requiring no changes to the clients
Java code.
o Use Springs HessianProxyFactoryBean instead of
RmiProxyFactoryBean.
Hessian/Burlap VS RMI
o Hessian/Burlap are based on HTTP.
they dont suffer from the same firewall issues as RMI
when it comes to serializing objects that are sent in
RPC messages, Hessian/Burlap are better
o Hessian/Burlap use a proprietary serialization
mechanism, RMI uses Javas own serialization
mechanism.
If data model is complex, RMI is better
Springs HttpInvoker
Exposing beans as HTTP services
o Like the other services mentioned before, we use
HttpInvokerServiceExporter to export an HTTP
invoker service.
o HttpInvokerServiceExporter is a Spring MVC
controller set up a URL handler to map an HTTP
URL to the service.
o Map DispatcherServlet with a *.service
extension.
Accessing services via HTTP
o To wire the HTTP invoker-based service, configure a
bean that proxies it using
HttpInvokerProxyFactoryBean.
o HttpInvokerProxyFactoryBean is like the other remote
service proxy factory beans.
HttpInvokers limitations
o Its a remoting solution offered by the Spring
Framework only
Both the client and the service must be Spring-enabled
applications.
Both the client and the service must be Java-based.
o Because Java serialization is being used
Both sides must have the same version of the classes
and the same version of the Java runtime (much like
RMI).
Web services
Publishing and consuming web services
o SOA is the idea that applications can and should be
designed to lean on a common set of core services
instead of reimplementing the same functionality for
each application.
o Spring comes with some capable support for publishing
and consuming SOAP web services using the Java API
for XML Web Services (JAX-WS).
Creating Spring-enabled JAX-WS endpoints
Autowiring JAX-WS endpoints in Spring

o The JAX-WS programming model involves using


annotations to declare a class and its methods as web
service operations.
o A class thats annotated with @WebService is
considered a web service endpoint, and its methods
annotated with @WebMethod are the operations.
Autowiring JAX-WS endpoints in Spring
o A JAX-WS endpoint will likely depend on other objects
to do its work JAX-WS endpoints could benefit from
dependency injection.
o The secret to wiring JAX-WS endpoints is to extend
SpringBeanAutowiringSupport you can annotate
an endpoints properties with @Autowired, and its
dependencies will be met.
Exporting standalone JAX-WS endpoints
o Springs SimpleJaxWsServiceExporter
Like the others, it publishes Spring-managed beans as service
endpoints in a JAX-WS runtime
Unlike the others, it publishes all beans that are annotated with
JAX-WS annotations as JAX-WS services
Proxying JAX-WS services on the client side
o JaxWsPortProxyFactoryBean produces a proxy that
knows how to talk to a SOAP web service.
o The proxy is created to implement the services
interface.
JaxWsPortProxyFactoryBean makes it possible to
wire and use a remote web service as if it were any other
local POJO.
Creating REST APIs
2 with Spring MVC
Writing controllers that serve REST resources
Representing resources in XML, JSON, and other formats
Consuming REST resources
Getting REST
REST - Representational State Transfer
o Representational: REST resources can be represented
in virtually any form, whatever form best suits the
consumer of those resources.
o State: more concerned with the state of a resource than
with the actions taken against resources.
o Transfer: REST involves transferring resource data, in
some representational form, from one application to
another.
How Spring supports REST
o Controllers can handle requests for all HTTP methods.
o The @PathVariable annotation enables controllers to handle requests for
parameterized URLs.
o Resources can be represented in a variety of ways.
o The representation best suited for the client can be chosen using
ContentNegotiatingViewResolver.
o View-based rendering can be bypassed altogether using the @ResponseBody
annotation and various HttpMethodConverter implementations.
o Similarly, the @RequestBody annotation, along with HttpMethodConverter
implementations, can convert inbound HTTP data into Java objects passed in
to a controllers handler methods.
o Spring applications can consume REST resources using RestTemplate.
Creating your first
REST endpoint
RESTs representation
o The resource doesnt change only how its represented.
o JSON and XML are often sufficient representations expected by most clients.
o Controllers usually dont concern how resources are represented but deal
with resources in terms of the Java objects that define them.
o After the controller has finished its work, the resource is transformed into a
form that best suits the client.
o Two options to transform a resources Java representation into the
representation thats shipped to the client:
Content negotiation: A view is selected that can render the model into a
representation to be served to the client.
Message conversion: A message converter transforms an object returned from
the controller into a representation to be served to the client.
Content negotiation
o The view needs not only to match the view name, but also to be
chosen to suit the client.
o Springs ContentNegotiatingViewResolver takes the
content type that the client wants into consideration.
o The content-negotiation two-step:
1. Determine the requested media type(s).
2. Find the best view for the requested media type(s).
Step 1: Determining the requested media types
o If the URL has a file extension on the end,
ContentNegotiatingViewResolver tries to figure out the
desired type based on that extension.
o If the file extension doesnt produce any usable clues for the
media type, then the Accept header in the request is considered:
Accept headers value indicates the MIME type(s) that the client
wants
o If there is no Accept header and the extension is no help,
ContentNegotiatingViewResolver falls back to/as the
default content type.
Step 2: Influencing how media types are chosen
There are three ways to configure a
ContentNegotiationManager:
Directly declare a bean whose type is ContentNegotiationManager.
Create the bean indirectly via
ContentNegotiationManagerFactoryBean.
Override the configureContentNegotiation() method of
WebMvcConfigurerAdapter.
The benefits and limitations of
ContentNegotiatingViewResolver
o The key benefit: it layers REST resource representation
on top of the Spring MVC with no change in controller
code.
o Content negotiation is a convenient option when
theres a great deal of overlap between your human
and non-human interfaces.
o The serious limitation: it only has an opportunity to
determine how a resource is rendered to a client
Message conversion
o A more direct way.
o DispatcherServlet doesnt bother with ferrying
model data to a view.
o Only data produced by the controller and a resource
representation produced when a message converter
transforms that data.
Returning resource state in the response body
o Suppose that you need a way for a client to submit a new Spittle
to be saved. You can write the controller method to handle such
a request like this:
Defaulting controllers for message
conversion
Defaulting controllers for message
conversion
Annotations
o @ResponseBody tells Spring that you want to send the
returned object as a resource to the client.
o @ResquestBody tells Spring to find a message
converter to convert a resource representation coming
from a client into an object.
o @RestController used instead of @Controller, tells
Spring to apply message conversion to all handler
methods.
Serving more than resources
Communicating errors to the client
o Lets start by adding a new handler method to
SpittleController to serve a single Spittle:
Communicating errors to the client
o Spring offers a few options for dealing with such
scenarios:
Status codes can be specified with the @ResponseStatus
annotation.
Controller methods can return a ResponseEntity that
carries more metadata concerning the response.
An exception handler can deal with the error cases, leaving
the handler methods to focus on the happy path.
Setting headers in the response
Consuming REST resources
Exploring RestTemplates operations
Exploring RestTemplates operations
Exploring RestTemplates operations
Most of the operations in the table are overloaded into
three method forms:
One that takes a java.net.URI as the URL specification
with no support for parameterized URLs
One that takes a String URL specification with URL
parameters specified as a Map
One that takes a String URL specification with URL
parameters specified as a variable argument list
GETting resources
o The signatures of the three getForObject() methods look
like:

o The signatures of the getForEntity() methods are as follows:


Retrieving resources

o fetchFacebookProfile() starts by constructing an instance of


RestTemplate (an alternate implementation might use an
injected instance instead).
o Then it invokes the getForObject() method to retrieve a
Facebook profile, asking for the result as a Profile object.
o Upon receiving that Profile object, the method returns it to the
caller.
Retrieving resources
o Alternatively, you could place the id parameter into a Map with a
key of id and pass in that Map as the last parameter to
getForObject():
Extracting response metadata
o The getForEntity() methods work much the same as the
getForObject() methods but return that same object carried
in a ResponseEntity.
o You can use the getHeaders() method like this:

o The getHeaders() method returns an HttpHeaders object


that provides several convenience methods for retrieving
response headers, including getLastModified(), which
returns the number of milliseconds since January 1, 1970.
Extracting response metadata

o In addition to getLastModified(), HttpHeaders includes the


following methods for retrieving header information:
Extracting response metadata

o If youre interested in the responses HTTP status code, then


youll want to call the getStatusCode() method. For example,
consider this method that fetches a Spittle:
PUT
o The put() method comes in three forms:

o In all versions of put(), the second argument is the Java object


that represents the resource being PUT to the server at the given
URI.
o The content type into which the object will be converted
depends largely on the type being passed in to put().
DELETE
o Much like the put() methods, the delete() methods
have only three versions:

o The delete() methods are the simplest of all the


RestTemplate methods.
o The only thing you need to supply them with is the URI
of the resource to be deleted.
POST
o RestTemplate comes with three different kinds of methods for
sending POST requests three variants that each is overridden
into nine methods for POSTing data to the server
o The postForObject() and postForEntity() methods work
with POST requests in a way thats similar to how
getForObject() and getForEntity() work for sending GET
requests.
o The other method, postForLocation(), is unique for POST
requests.
Receiving object responses from POST requests
o One way of POSTing a resource to the server is to use
RestTemplates postForObject() method. The three varieties
of postForObject() have the following signatures:
Receiving object responses from POST requests
o One way of POSTing a resource to the server is to use
RestTemplates postForObject() method. The three varieties
of postForObject() have the following signatures:
Receiving object responses from POST requests
o As with the getForObject() methods, you may want to
examine some of the metadata that comes back with the request.
In that case, postForEntity() is the preferred method.
postForEntity() comes with a set of signatures that mirror
those of postForObject():
Receiving object responses from POST requests
o Suppose that, in addition to receiving the Spitter resource in
return, youd also like to see the value of the Location header in
the response. In that case, you can call postForEntity() like
this:
Receiving a resource location after a POST request
o It has the following three method signatures:

o To demonstrate postForLocation(), lets try POSTing a Spitter


again. This time, you want the resources URL in return:
Exchanging resources
o Like all the other methods in RestTemplate, exchange() is
overloaded into three signature forms. One takes a
java.net.URI to identify the target URL, whereas the other
two take the URL in String form with URL variables, as shown
here:
Exchanging resources
o One way to retrieve a Spitter resource from the server is to
use RestTemplates getForEntity() method like this:

o As you can see in the next snippet of code, exchange() is also


up to the task:
Exchanging resources
o Without specifying the headers, exchange() sends the GET
request for a Spitter with the following headers:
Exchanging resources
o Setting request headers is a simple matter of constructing the
HttpEntity sent to exchange() with a MultiValueMap
loaded with the desired headers:

o Now you can call exchange(), passing in the HttpEntity:


Exchanging resources
o On the surface, the results should be the same. You should
receive the Spitter object that you asked for. Under the
surface, the request is sent with the following headers:
3 Summary
Working with remote services
Creating REST APIs with Spring MVC
Thanks!
Any questions ?

Вам также может понравиться