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
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 ?