Download Apartado 3.5: Caso de estudio
Document related concepts
no text concepts found
Transcript
3.5 Caso de estudio: diseño e implementación de un servicio/cliente SOAP con JAX-RPC Estructura de paquetes del caso de estudio Subsistema Movies es.udc.ws.movies client model service rest soap proxy servicedef wsdl wsdlutil xml Visión de la estructura de paquetes en capas Cliente Servidor Interfaz de Usuario Implementación del Servicio es.udc.ws.movies.client es.udc.ws.movies.xml es.udc.ws.movies.service.soap.wsdl es.udc.ws.movies.service.soap.wsdlutil Acceso al Servicio es.udc.ws.movies.service es.udc.ws.movies.service.soap.proxy es.udc.ws.movies.service.soap.wsdl es.udc.ws.movies.service.soap.wsdlutil Lógica de Negocio es.udc.ws.movies.model Al igual que en el ejemplo JAXRPCTutorial es.udc.ws.movies.service.soap.servicedef: sólo se utiliza para definir la interfaz del servicio (a partir de la cual se obtiene el documento WSDL con Java2WSDL) es.udc.ws.movies.service.soap.wsdl: contiene las clases e interfaces generadas por WSDL2Java, y la implementación del servicio (MovieInformationProviderSoapBindingImpl) es.udc.ws.movies.service.soap.wsdl [Capas de Acceso e Implementación del Servicio] (1) <<interface>> java.rmi.Remote <<interface>> MovieInformationService + + + + findMoviesByReleaseDate(releaseDate : Calendar) : MovieInformationWTO[] addMovie(movieInformation : MovieInformationWTO) : Long updateMovie(movieInformation : MovieInformationWTO) : void removeMovie(identifier : Long) : void MovieInformationWTO <<interface>> java.io.Serializable - identifier : Long title : String runtime : short releaseDate : Calendar directorNames : String[] actorNames : String[] genres : String[] synopsis : String + Constructor + Métodos get/set es.udc.ws.movies.service.soap.wsdl [Capas de Acceso e Implementación del Servicio] (2) public interface MovieInformationProvider extends Remote { public MovieInformationWTO[] findMoviesByReleaseDate( Calendar releaseDate) throws RemoteException; public long addMovie(MovieInformationWTO movieInformation) throws RemoteException; public void updateMovie(MovieInformationWTO movieInformation) throws MovieNotFoundException, MovieException, RemoteException; public void removeMovie(Long identifier) throws MovieNotFoundException, MovieException, RemoteException; } es.udc.ws.movies.service.soap.wsdl [Capas de Acceso e Implementación del Servicio] (3) Obsérvese que a diferencia de los tipos definidos en es.udc.ws.movies.service Se usan vectores ([]) en vez de listas No se utilizan enumerados Las operaciones declaran excepciones análogas y java.rmi.RemoteException La diferencia se debe a que los tipos son generados por WSDL2Java Los tipos del paquete es.udc.ws.movies.soap.servicedef tampoco usaban vectores ni enumerados porque no son tipos válidos JAX-RPC es.udc.ws.movies.service.soap.wsdl [Capas de Acceso e Implementación del Servicio] (y 4) En un caso real, la diferencia sería aún mayor El cliente partiría de un documento WSDL escrito/generado por los desarrolladores del servicio El cliente utilizaría WSDL2Java y obtendría las clases e interfaces necesarias para comunicarse con el servicio (es.udc.ws.movies.service.soap.wsdl) La interfaz del servicio diferiría (quizás notablemente) de la esperada por el cliente Precisamente uno de los objetivos de las abstracciones definidas en es.udc.ws.movies.service es ofrecer una vista sencilla del servicio, para así facilitar la implementación del cliente es.udc.ws.movies.service.soap.proxy.MovieInformationServiceSOAPProxy [Capa de Acceso al Servicio] (1) es.udc.ws.movies.service <<interface>> MovieInformationService MovieInformationServiceSOAPProxy es.udc.ws.movies.service.soap.wsdlutil CommonWSDLTypeConversor es.udc.ws.movies.service.soap.wsdl MovieInformationProvider CommonWSDLTypeConversor proporciona operaciones para facilitar la conversión de “tipos Java” (los definidos en es.udc.ws.movies.service) a/desde “tipos WSDL” (los definidos en es.udc.ws.movies.service.soap.wsdl) es.udc.ws.movies.service.soap.proxy.MovieInformationServiceSOAPProxy [Capa de Acceso al Servicio] (2) public class MovieInformationServiceSOAPProxy implements MovieInformationService { private final static String ENDPOINT_ADDRESS_PARAMETER = "MovieInformationServiceSOAPProxy/endpointAddress"; private static String endpointAddress; private MovieInformationProvider movieInformationProvider; public MovieInformationServiceSOAPProxy() throws ServiceException { try { MovieInformationProviderService movieInformationProviderService = new MovieInformationProviderServiceLocator(); movieInformationProvider = movieInformationProviderService. getMovieInformationProvider(); ((Stub)movieInformationProvider)._setProperty( Stub.ENDPOINT_ADDRESS_PROPERTY, getEndpointAddress()); } catch (Exception e) { throw new ServiceException(e); } } Lee la URL de la configuración es.udc.ws.movies.service.soap.proxy.MovieInformationServiceSOAPProxy [Capa de Acceso al Servicio] (y 3) public Long addMovie(MovieInformationTO movieInformation) throws MovieInformationException, ServiceException { try { return movieInformationProvider.addMovie( CommonWSDLTypeConversor.toWSDL(movieInformation)); } catch (MovieException e) { throw CommonWSDLTypeConversor.toMovieInformationException( e); } catch (Exception e) { throw new ServiceException(e); } } // ... } es.udc.ws.movies.service.soap.wsdl.MovieInformationProviderSoapBindingImpl [Capa de Implementación del Servicio] (1) <<interface>> MovieInformationProvider El interfaz generado por WSDL2Java MovieInformationProviderSoapBindingImpl es.udc.ws.movies.service.soap.wsdlutil CommonWSDLTypeConversor es.udc.ws.movies.model MovieInformationFacade es.udc.ws.movies.service.soap.wsdl.MovieInformationProviderSoapBindingImpl [Capa de Implementación del Servicio] (y 2) public class MovieInformationProviderSoapBindingImpl implements MovieInformationProvider { // ... public long addMovie(MovieInformationWTO movieInformation) throws MovieException { try { return MovieInformationFacade.getInstance().addMovie( CommonWSDLTypeConversor.fromWSDL(movieInformation)); } catch (MovieInformationException e) { throw CommonWSDLTypeConversor.toMovieException(e); } } // .. } es.udc.ws.movies.service.soap.wsdl.util.CommonWSDLTypeConversor [Capas de Acceso e Implementación del Servicio] (1) public final class CommonWSDLTypeConversor { public final static MovieInformationException toMovieInformationException(MovieException e) { return new MovieInformationException(e.getError()); } public final static MovieInformationWTO toWSDL( MovieInformationTO info) { MovieInformationWTO newInfo = new MovieInformationWTO(); newInfo.setIdentifier(info.getIdentifier()); newInfo.setTitle(info.getTitle()); newInfo.setRuntime(info.getRuntime()); newInfo.setReleaseDate(info.getReleaseDate()); newInfo.setDirectorNames(info.getDirectorNames().toArray( new String[0])); newInfo.setActorNames(info.getActorNames().toArray( new String[0])); newInfo.setGenres(GenreOperations.toListOfString( info.getGenres()).toArray(new String[0])); newInfo.setSynopsis(info.getSynopsis()); return newInfo; } es.udc.ws.movies.service.soap.wsdl.util.CommonWSDLTypeConversor [Capas de Acceso e Implementación del Servicio] (y 2) public final static MovieException toMovieException( MovieInformationException e) { return new MovieException(e.getMessage()); } public final static MovieInformationTO fromWSDL( MovieInformationWTO info) { Long identifier = info.getIdentifier(); String title = info.getTitle(); short runtime = info.getRuntime(); Calendar releaseDate = info.getReleaseDate(); List<String> directorNames = Arrays.asList(info.getDirectorNames()); List<String> actorNames = Arrays.asList(info.getActorNames()); List<String> genres = Arrays.asList(info.getGenres()); String synopsis = info.getSynopsis(); return new MovieInformationTO(identifier, title, runtime, releaseDate, directorNames, actorNames, GenreOperations.toListOfGenres(genres), synopsis); } // ... }