iteración 2

9
Iteración 2. API REST para la aplicación de gestión de reservas FJRP CCIA2011 Date: Noviembre2011 Índice General Pasos previos: configuración del proyecto Netbeans Implementar el API REST de acceso a los clientes Desplegar y probar el ejemplo TAREAS A REALIZAR API REST para acceso a los Hoteles API REST para acceso a las Reservas Documentación a entregar Pasos previos: configuración del proyecto Netbeans IMPORTANTE: Problemas con GlassFish v3.1 La versión de GlassFish que se distribuye con Netbeans 7.0 tiene una implementación del API CDI (Java Contexts and Dependency Injection) con varios bugs que complican el despligue de algunas aplicaciones (más información ). En la versión de GlassFish 3.1.1 (que se distribuye con Netbeans 7.0.1) se emplea la versión 1.1.1‐Final del proyecto Weld que resuelve el problema. SOLUCIONES: 1. Trabajar con Netbeans 7.0.1 y GlassFish 3.1.1 2. Deshabilitar el soporte CDI en el proyecto GestionReservasrest Bastará con eliminar el fichero de configuración de CDI (beans.xml) 1. En el proyecto GestionReservasrest, dentro de Configurarion Files, seleccionar beans.xml, [botón derecho] + Delete 2. Reiniciar el servidor GlassFish (adicionalmente se puede eliminar [undeploy] la aplicación GestionReservas desde la pestaña de servidores de Netbeans), limpiar y reconstruir el proyecto principal y volver a desplegarlo (Deploy) Se trabajará sobre el subproyecto Java Web GestionReservasrest, incialmente vacío. Este proyecto está vinculado como módulo al proyecto Java EE GestionReservas, de modo que al desplegar el proyecto principal también quedará desplegado y accesible el subproyecto REST. La URL donde recibirá las peticiones HTTP este subproyecto (context path) es http://localhost:8080/GestionReservas‐ rest/) 1. Incluir el JAR del proyecto GestionReservasejb para tener disponibles los .class de las entidades JPA y de los interfaces de los EJBs Sobre el proyecto ''GestionReservas‐rest'' ‐> [botón derecho] ‐> seleccionar ''Properties''

Upload: ben-avraham

Post on 18-Dec-2015

12 views

Category:

Documents


2 download

DESCRIPTION

tip

TRANSCRIPT

  • 16/4/2015 Iteracin2.APIRESTparalaaplicacindegestindereservas

    http://ccia.ei.uvigo.es/docencia/SCS/1112/jee/ejemploJAXRS/ 1/9

    Iteracin2.APIRESTparalaaplicacindegestindereservas

    FJRPCCIA2011

    Date:Noviembre2011

    ndiceGeneral

    Pasosprevios:configuracindelproyectoNetbeansImplementarelAPIRESTdeaccesoalosclientesDesplegaryprobarelejemploTAREASAREALIZAR

    APIRESTparaaccesoalosHotelesAPIRESTparaaccesoalasReservasDocumentacinaentregar

    Pasosprevios:configuracindelproyectoNetbeans

    IMPORTANTE:ProblemasconGlassFishv3.1

    LaversindeGlassFishquesedistribuyeconNetbeans7.0tieneunaimplementacindelAPICDI(JavaContextsandDependencyInjection)convariosbugsquecomplicaneldespliguedealgunasaplicaciones(msinformacin).

    EnlaversindeGlassFish3.1.1(quesedistribuyeconNetbeans7.0.1)seemplealaversin1.1.1FinaldelproyectoWeldqueresuelveelproblema.

    SOLUCIONES:

    1. TrabajarconNetbeans7.0.1yGlassFish3.1.12. DeshabilitarelsoporteCDIenelproyectoGestionReservasrest

    BastarconeliminarelficherodeconfiguracindeCDI(beans.xml)

    1. EnelproyectoGestionReservasrest,dentrodeConfigurarionFiles,seleccionarbeans.xml,[botnderecho]+Delete

    2. ReiniciarelservidorGlassFish(adicionalmentesepuedeeliminar[undeploy]laaplicacinGestionReservasdesdelapestaadeservidoresdeNetbeans),limpiaryreconstruirelproyectoprincipalyvolveradesplegarlo(Deploy)

    SetrabajarsobreelsubproyectoJavaWebGestionReservasrest,incialmentevaco.

    EsteproyectoestvinculadocomomduloalproyectoJavaEEGestionReservas,demodoquealdesplegarelproyectoprincipaltambinquedardesplegadoyaccesibleelsubproyectoREST.LaURLdonderecibirlaspeticionesHTTPestesubproyecto(contextpath)eshttp://localhost:8080/GestionReservasrest/)

    1. IncluirelJARdelproyectoGestionReservasejbparatenerdisponibleslos.classdelasentidadesJPAydelosinterfacesdelosEJBs

    Sobreelproyecto''GestionReservasrest''>[botnderecho]>seleccionar''Properties''

  • 16/4/2015 Iteracin2.APIRESTparalaaplicacindegestindereservas

    http://ccia.ei.uvigo.es/docencia/SCS/1112/jee/ejemploJAXRS/ 2/9

    En''Libraries'',pulsarbotn''AddProject''yseleccionar''GestionReservasejb''[AddProjectJARfiles]+[OK]

    2. CrearelApplicationPath(razdelosURIsdelAPIREST)Sobre''sourcespackages''crearunnuevopaqueteJavadenombre''rest''CrearunaclaseJava''GestionReservasAplicacionREST''queherededejavax.ws.rs.core.Application.

    Paraesteejemploserunaclasevaca,cuyanicautilidadesestablecerelcontextodelosrecursosRESTconlaanotacin@javax.ws.rs.ApplicationPath

    (ennuestrocasolaraizdelosrecursosRESTserhttp://localhost:8080/GestionReservasrest/rest/)

    packagerest;

    @javax.ws.rs.ApplicationPath("rest")publicclassGestionReservasAplicacionRESTextendsjavax.ws.rs.core.Application{}

    3. CrearlaclasedeimplementacindelosrecursosREST.

    SerunEJBdesesinlocalsininterfaz.SehaceasparapoderusarelsoportedeinyeccindedependenciasparaaccederalosEJBsdelproyectoGestionReservasejb

    Sobreelpaquete''rest'',[botnderecho],New Other JavaEE SessionBean

    EJBName:GestionReservasClienteRESTPackage:restSessionType:StatelessNoseleccionarningninterfaz

    AnotarlaclasedelEJBcon@Path(''clientes'')paraespecificarelpathdedondecolgarnlosrecursosRESTcon@Produces({''application/xml'',''application/json''})paraespecificareltipodecontenidopermitdoenlosmensajesHTTPderespuestacon@Consumes({''application/xml'',''application/json''})paraespecificareltipodecontenidoadmitidoenlaspeticionesHTTPrecibidas

    @Stateless@LocalBean@Path("/clientes")@Produces({"application/xml","application/json"})@Consumes({"application/xml","application/json"})publicclassGestionReservasClienteREST{...}

    ImplementarelAPIRESTdeaccesoalosclientes1. CrearlasclasesJAXBquesoportarnlaserializacindedatosenXML/JSON(porejemploClienteREST)

    1. Sobre''sourcespackages''crearunnuevopaqueteJavadenombre''jaxb''2. Sobreelpaquete''rest''>[botnderecho]>New>Other>JavaClass

    Anotarlacon@XmlRootElementeincluirlosatributosamanejarenlosdocumentosXML/JSONaintercambiar.

    Sedeclararncomoprivateyseanotarncon@XmlElementparaqueJABXlosincluyaenlosXMLgenerados

    SeusarlaconvencindeserializarlosatributosiddelasentidadesencomoatributosXML(anotacin@XmlAttribute)enlugardecomoelementosXML.Debeincluirseunconstructorvacoycrearmtodosget()yset()paratodoslosatributos[importante]

    Sehaincluidounconstructor''deconveniencia''quetomalaentidadClienteoriginalyunStringconlaURIbasedondeestdesplegadoelrecursoyaaprtirdeellossecopian/construyenlosatributosdeClienteRESTNota:OtraalternativapodrahacersidoutilizardirectamentelasentidadesJPAdelpaqueteentidades,aadindoleslascorrespondientesanotacionesJAXByevitandoenelmapeolasreferenciascircularesentreentidades.

    packagejaxb;

    importjavax.xml.bind.annotation.XmlAttribute;

  • 16/4/2015 Iteracin2.APIRESTparalaaplicacindegestindereservas

    http://ccia.ei.uvigo.es/docencia/SCS/1112/jee/ejemploJAXRS/ 3/9

    importjavax.xml.bind.annotation.XmlRootElement;

    @XmlRootElementpublicclassClienteREST{privateLongid;privateStringnombre;privateStringapellidos;privateStringnif;privateStringdomicilio;privateStringlocalidad;privateStringcodPostal;privateStringprovincia;privateStringtelefono;

    privateStringURI;//AlamcenaelURIdelrecurso

    publicClienteREST(){}

    publicClienteREST(entidades.Clientecliente,StringURIbase){this.id=cliente.getId();this.nombre=cliente.getNombre();this.apellidos=cliente.getApellidos();this.nif=cliente.getNif();this.domicilio=cliente.getDomicilio();this.localidad=cliente.getLocalidad();this.codPostal=cliente.getCodPostal();this.provincia=cliente.getProvincia();this.telefono=cliente.getTelefono();this.URI=URIbase+this.id;//ConstruyeelURI}

    @XmlAttribute//ParaserializarelIDcomoatributoXMLynocomoelementopublicStringgetId(){ returnthis.id;}...}

    3. CrearlosmtodosqueatendernlaspeticionesRESTymapearlasURIsymtodosHTTP1. InyectarlasreferenciasalosEJBsautilizar.

    @Stateless@LocalBean@Path("/clientes")@Produces({"application/xml","application/json"})@Consumes({"application/xml","application/json"})publicclassEjemploREST{@EJBClienteDAOLocalclienteDAO;...}

    2. InyectarunareferenciaalobjetogestordeURIsdelAPIJAXRS(mediantelaanotacin@Contextaplicadaaunobjetojavax.ws.rs.core.UriInfo)

    @Stateless@LocalBean@Path("/clientes")@Produces({"application/xml","application/json"})@Consumes({"application/xml","application/json"})publicclassEjemploREST{@EJBClienteDAOLocalclienteDAO;

    @ContextprivateUriInfouriInfo;//Info.sobrelaURIdondeservidordespliegaelrecurso...}

    3. ImplementarlospuntosfinalesdelasURIsymtodosREST.ConsultaalEJBclienteDAOyconviertelasentidadesClienteenunalistadeobjetosClienteRESTque

  • 16/4/2015 Iteracin2.APIRESTparalaaplicacindegestindereservas

    http://ccia.ei.uvigo.es/docencia/SCS/1112/jee/ejemploJAXRS/ 4/9

    sernenviadosalcliente.

    @GETpublicListlistaClientes(){Listlista=newArrayList();

    StringuriBase=uriInfo.getBaseUri().toString();

    for(Clientec:clienteDAO.buscarTodos()){lista.add(newClienteREST(c,uriBase));}

    returnlista;}

    ObtienelosdatosdelClientecuyoIDseindicaenelpathdelURI

    @Path("/{id}")@GETpublicClienteRESTclientePorId(@PathParam("id")Longid){Clientec=clienteDAO.buscarPorId(id);return(newClienteREST(c,uriInfo.getBaseUri().toString()));}

    BorraelClientecuyoIDseindicaenelpathdelURI

    @Path("/{id}")@DELETEpublicvoidborrarCliente(@PathParam("id")Longid){Clientec=clienteDAO.buscarPorId(id);clienteDAO.eliminar(c);}

    CreaunnuevoclienteconlosdatosrecibidosydevuelvelaURIdelrecursocreado

    @POST@TransactionAttribute(TransactionAttributeType.NEVER)//ParaqueelclienteDAO//gestione(ytermine)//supropiatransaccinpublicResponsecrearCliente(JAXBElementclienteJAXB){ClienteRESTclienteREST=clienteJAXB.getValue();

    Clientenuevo=newCliente();

    nuevo.setNombre(clienteREST.getNombre());nuevo.setApellidos(clienteREST.getApellidos());nuevo.setNif(clienteREST.getNif());nuevo.setDomicilio(clienteREST.getDomicilio());nuevo.setCodPostal(clienteREST.getCodPostal());nuevo.setProvincia(clienteREST.getProvincia());nuevo.setTelefono(clienteREST.getTelefono());nuevo=clienteDAO.crear(nuevo);URInuevoURI=uriInfo.getAbsolutePathBuilder().path(nuevo.getId().toString()).build();returnResponse.created(nuevoURI).build();}

    Desplegaryprobarelejemplo1. SobreelproyectoprincipalGestionReservas,desplegarlaaplicacin(conloqueseincluyeeldespliegedelmdulo

    GestionReservasrest)

    2. ProbarelaccesoalasURIsdefinidasdesdeunnavegadoroconlaherramientadelineadecomandoscurl

    curlvhttp://localhost:8080/GestionReservasrest/rest/clientescurlvXGETH"Accept:application/json"http://localhost:8080/GestionReservasrest/rest/clientes

    curlvhttp://localhost:8080/GestionReservasrest/rest/clientes/4curlvXGETH"Accept:application/json"http://localhost:8080/GestionReservasrest/rest/clientes/4

    curlvXPOSThttp://localhost:8080/GestionReservasrest/rest/clientes\

  • 16/4/2015 Iteracin2.APIRESTparalaaplicacindegestindereservas

    http://ccia.ei.uvigo.es/docencia/SCS/1112/jee/ejemploJAXRS/ 5/9

    HContenttype:application/xml\data"\\Lucas\GrijanderGrijander\33333333C\SucasaSantiago\15333ACorua\981333333\"

    TAREASAREALIZARAmpliarelAPIRESTdefinidoconfuncionalidadesparaelaccesoaHotelesyReservasdeacuerdoalasiguienteespecificacin

    Nota:Sedeberndefinirlasclasesadicionalesencargadasde''portar''losdatosqueseintercambiaranenformatoXMLoJSONalaccederalosrecursosmediantelosmtodosREST.

    Sonnecesariaslasclases:HotelREST,TipoHabitacionREST,ReservaRESTTodasestarnanotadascon@XmlRootElementTodasseguirnconvencionessimilaresalasdelejemploanterior:unconstructorapartirdelaclaseEntidadasociada,juntoconlaURIbase,ysuIDseserializarcomounatributoXML(anotacin@XmlAttibute).

    APIRESTparaaccesoalosHoteles

    CrearunanuevaclaseparagestionarlosrecursosRESTdentrodel''path''@Path("hoteles")

    (URI:http://localhost:8080/GestionReservasrest/rest/hoteles)

    ImplementarlacomounEJBsinestadoconinterfazlocal:anotaciones@Statelessy@LocalBean+mtodospblicos.

    MtodosRESTasoportar

    Mtodo1Mtodo:GETPath:/hotelesDevuelvelalistadeobjetosHotelRESTconlosdatosdeloshotelesdisponibles.Ejemplo:http://localhost:8080/GestionReservasrest/rest/hoteles

    2estrellas32004HotelRestaurantePepeAsLagoasOurenseHotelPepeOurense988333333http://localhost:8080/GestionReservasrest/rest/hoteles/1

    2estrellas32008HostalResidenciaLucasAPonteOurenseHostalLucasOurense988777777http://localhost:8080/GestionReservasrest/rest/hoteles/2...

    Mtodo2Mtodo:GETPath:/hoteles/{localidad:[azAZ_]+}

  • 16/4/2015 Iteracin2.APIRESTparalaaplicacindegestindereservas

    http://ccia.ei.uvigo.es/docencia/SCS/1112/jee/ejemploJAXRS/ 6/9

    DevuelvelalistadeobjetosHotelRESTconlosdatosdeloshotelesdisponiblesenlalocalidadindicada.Ejemplo:http://localhost:8080/GestionReservasrest/rest/hoteles/Ourense

    Mtodo3Mtodo:GETPath:/hoteles/{id:[09]+}DevuelveunobjetoHotelRESTconlosdatosdelhotelindicado.Ejemplo:http://localhost:8080/GestionReservasrest/rest/hoteles/2

    2estrellas32008HostalResidenciaLucasAPonteOurenseHostalLucasOurense988777777http://localhost:8080/GestionReservasrest/rest/hoteles/2

    Mtodo4Mtodo:GETPath:/hoteles/{id:[09]+}/habitacionesDevuelvelalistadeobjetosTipoHabitacionRESTconlosdatosdelostiposdehabitacindelhotelindicado.Ejemplo:http://localhost:8080/GestionReservasrest/rest/hoteles/2/habitaciones

    2HabitacindobleeconmicaconTVybaoDoble35.0http://localhost:8080/GestionReservasrest/rest/hoteles/2/habitaciones/4http://localhost:8080/GestionReservasrest/rest/hoteles/2

    1HabitacinindividualeconmicaconTVIndividual25.0http://localhost:8080/GestionReservasrest/rest/hoteles/2/habitaciones/5http://localhost:8080/GestionReservasrest/rest/hoteles/2...

    Posibleimplementacin:

    @GET@Path("{id:[09]+}/habitaciones")publicListgetHabitacionesPorHotel(@PathParam("id")Longid){StringuriBase=uriInfo.getBaseUri().toString();

    Hotelh=hotelDAO.buscarPorId(id);

    Listlista=newArrayList();

    for(TipoHabitaciont:h.getTiposHabitacion()){lista.add(newTipoHabitacionREST(t,uriBase));}

    returnlista;}

    Mtodo5Mtodo:GETPath:/hoteles/{id:[09]+}/disponibilidadQueryParams:fechaInicio,fechaFinDevuelvelalistadeobjetosTipoHabitacionRESTconlosdatosdelostiposdehabitacindelhotelindicadoqueestndisponiblesenlasfechasindicadascomoQueryParams:?fechaInicio=dd/MM/yyyy&fechaFin=dd/MM/yyyyy.Ejemplo:

    http://localhost:8080/GestionReservasrest/rest/hoteles/2/disponibilidad?fechaInicio=1/1/2011&fechaFin=2/2/2011

  • 16/4/2015 Iteracin2.APIRESTparalaaplicacindegestindereservas

    http://ccia.ei.uvigo.es/docencia/SCS/1112/jee/ejemploJAXRS/ 7/9

    Notas:PordefectoenelAPIJAXRSsemanejanlasfechasenformatomes/da/ao(elformatopordefectodeJava).Obienseutilizaeseformato,capturandolosQueryParamdirectamentecomoobjetosDate

    @GET@Path("{id:[09]+}/disponibilidad2)publicListgetHabitacionesPorHotelYFecha(@PathParam("id")Longid,@QueryParam("fechaInicio")DatefechaInicio,@QueryParam("fechaFin")DatefechaFin){...}

    ObiensecapturanlosQueryParamcomoStringenformatodd/MM/yyyyyyseusaunobjetoSimpleDateFormatparaconvertirlosaobjetosDate

    @GET@Path("{id:[09]+}/disponibilidad")publicListgetHabitacionesPorHotelYFecha(@PathParam("id")Longid,@QueryParam("fechaInicio")StringstrInicio,@QueryParam("fechaFin")StringstrFin)throwsParseException{

    SimpleDateFormats=newSimpleDateFormat("dd/MM/yyyy");DatefechaInicio=s.parse(strInicio);DatefechaFin=s.parse(strFin);...}

    Mtodo6Mtodo:GETPath:/hoteles/{id:[09]+}/reservasDevuelvelalistadeobjetosReservaRESTconlosdatosdelasreservasdelhotelindicado.Ejemplo:http://localhost:8080/GestionReservasrest/rest/hoteles/2/reservas

    120100208T00:00:00+01:0020100204T00:00:00+01:00442Marcos135.0http://localhost:8080/GestionReservasrest/rest/reservas/3

  • 16/4/2015 Iteracin2.APIRESTparalaaplicacindegestindereservas

    http://ccia.ei.uvigo.es/docencia/SCS/1112/jee/ejemploJAXRS/ 8/9

    DevuelvelalistadeobjetosReservaRESTconlosdatosdetodaslasreservas.Ejemplo:http://localhost:8080/GestionReservasrest/rest/reservas

    120100203T00:00:00+01:0020100201T00:00:00+01:00311Luis145.0http://localhost:8080/GestionReservasrest/rest/reservas/1

    120100207T00:00:00+01:0020100205T00:00:00+01:00311Luis145.0http://localhost:8080/GestionReservasrest/rest/reservas/2

    ......

    Mtodo2Mtodo:GETPath:/reservas/{id:[09]+}DevuelveunobjetoReservaRESTconlosdatoslareservaindicada.Ejemplo:http://localhost:8080/GestionReservasrest/rest/reservas/4

    Mtodo1Mtodo:DELETEPath:/reservas/{id:[09]+}Eliminalosdatosdelareservaindicada.Ejemplo:curlvXDELETEhttp://localhost:8080/GestionReservasrest/rest/reservas/4

    Mtodo1Mtodo:POSTPath:/reservasCreaunanuevareservaconlosdatosdelobjetoReservaRESTenviadoenlapeticinPOSTEjemplo:

    curlvXPOSThttp://localhost:8080/GestionReservasrest/rest/reservas\HContenttype:application/xml\data"\\1\20101221\20101227\4\1\1\prubaREST\1\45.0\""

    Posibleimplementacin:(presuponequeelEJBHotelDAOincluyeunmtodobuscarTipoHabitacion()quedevuelveunobjetoTipoHabitacinapartirdesuID)

    @POST@TransactionAttribute(TransactionAttributeType.NEVER)//FuerzaaquereservaDAOgestione(ytermine)supropiatransaccion

  • 16/4/2015 Iteracin2.APIRESTparalaaplicacindegestindereservas

    http://ccia.ei.uvigo.es/docencia/SCS/1112/jee/ejemploJAXRS/ 9/9

    publicResponsecrearReserva(JAXBElementreservaJAXB){ReservaRESTreservaREST=reservaJAXB.getValue();

    Reservanueva=newReserva();nueva.setFechaInicio(reservaREST.getFechaInicio());nueva.setFechaFin(reservaREST.getFechaFin());nueva.setCantidad(reservaREST.getCantidad());nueva.setNombreTomador(reservaREST.getNombreTomador());nueva.setOcupacion(reservaREST.getOcupacion());

    nueva.setCliente(clienteDAO.buscarPorId(reservaREST.getIdCliente()));nueva.setTipoHabitacion(hotelDAO.buscarTipoHabitacion(reservaREST.getIdTipoHabitacion()));

    nueva=reservaDAO.crear(nueva);

    URInuevaURI=uriInfo.getAbsolutePathBuilder().path(nueva.getId().toString()).build();returnResponse.created(nuevaURI).build();}

    Documentacinaentregar

    Ladocumentacinyelcdigoaentregarparaesta''iteracin2''seintegrarnconlosdela''iteracin1''.

    SeincluirelproyectoNetbeansGestionReservasrestEnlamemoriaescritaseincluirunapartadoconlasiguienteestructura:

    DescripcinresumidadelAPIRESTofrecido(URIs+MtodosHTTP+Descripcin)tantoparaClientes,comoparaHotelesyReservasDescripcindelospaquetesyclasesaadidas(clasesdemapeoXML+clasesdeimplementacindelosendpointREST)DescripcindelosmtodosqueimplementanelAPIRESTydelainteraccindelasclasesdeimplementacinconlosEJBsdedelproyectoGestionReservasejbqueimplementanlacapadenegocio.

    ribadas20111123