Oracle Certified Expert, Java EE 6 Web Services Developer segédlet

SOAP webszolgáltatások JAX-WS-sel

  • Java EE 6 2009. dec. 10-én jött ki: JAX-WS 2.2 (JSR 224), JAX-RS 1.1, Web Services Metadata for the Java Platform 2.0 (JSR 181), SOAP with Attachments API for Java (SAAJ) 1.3
  • MEP: Message Exchange Pattern, típusai: request/response, oneway, async callback, async polling
  • SOAP: 1.2-től kezdve nem rövidítés
  • WSDL felépítése: definitions, types: adattípusok definíciója, message: üzenetek defincíciója, message part-(ok)ból áll, portType: operációk halmaza, binding: protokoll és adatformátum specifikációk, pl. soap, ezen belül operáció, input-tal, output-tal, majd service, port: portType (interfész) és binding (implementáció összekapcsolása)
  • WS-I: csak RPC/literal vagy document, de az utóbbinál body-n belül csak max egy elem lehet
  • WS-I Basic Profile 1.1 egy dokumentum, mely a SOAP 1.1 és WSDL 1.1 szabványokat pontosítja

Style és encoding

  • RPC/Literal
    • Paramétereket tartalmaz a híváshoz
    • Mindig wrapped
    • Wrapper element az operation neve
    • Állhat több part-ból az input message
    • Part mindig type attribútummal van deklarálva (szemben a document element-tel)
    • csak a part-ok vannak a types részben leírva
    • Part-nak megfelelő elemek névtér nélkül
    • Válasz neve nem deklarált
  • Document/Literal
    • Dokumentumot tartalmaz a híváshoz
    • Lehet több part
    • Part mindig element-tel van megadva
    • A teljes body tartama a sémában van definiálva
    • Operation neve nem szerepel a soap üzenetben
    • Part-ok közvetlenül a body-ban vannak, nincs wrapper, névtérrel ellátottak
    • Response ugyanígy
  • Document/Literal wrapped
    • input message-nek csak egy gyereke van, a wrapper
    • element-ként leírva, sémával meghatározva
    • konvenció szerint operation neve = wrapper neve
    • ugyanígy a response-nál is, konvenció szerint a wrapper neve az operation neve + “Response”

JAX-WS

  • SEI
  • Kötelező: SIB
  • Nem muszáj a SIB-nek implementálnia a SEI-t, megadható az annotációban is, csak nem biztonságos -> futás idejű hiba
  • Ha annotációban sincs megadva, implicit SEI
  • Opcionális: SEI, WSDL, webservices.xml
  • Osztály, public, nem lehet final vagy abstract
  • Default public constructor-nak lennie kell, nem lehet finalize, nem tárolhat állapotot
  • Metódusai nem lehetnek static vagy final
  • Wsgen, wsimport
  • A JAX-WS 2.1.6-tól változott az implicit esetén, több esetben lesz kiajánlva a metódus
  • Explicit SEI esetén az összes publikus metódust kiajánlja, a WebMethod csak további konfigurációkra való
  • A wsimport generál: SEI, service, fault-hoz tartozó osztályt, ha kell; paraméter osztályokat, ha kell; Async Reponse Bean, ha kell
  • external/embedded binding declaration: SEI, exception, service neve, package neve, wrapper style
  • JAXB: sémában annotation/appinfo tag-en belül
  • JAX-WS kliens: Service.create(url, qname); service.getPort(SEI.class);
  • Deploy JDK-ban: Endpoint.publish, egyszálú
  • Default: Wrapped Document/Literal, RPC: @SOAPBinding(style = Style.RPC)
  • @WebService annotáció targetNamespace attribútuma adja meg a névteret, amúgy a package alapján
  • @RequestWrapper, @ResponseWrapper
  • WebParam.Mode.OUT, Holder
  • Ne wrapper-ek legyenek: customized binding, enableWrapperStyle
  • @SoapBinding(parameterStyle = SOAPBinding.ParameterStyle.BARE)
  • Ha aszinkron klienst akarunk, akkor ismét customized binding: enableAsyncMapping
  • AsyncHandler
  • Response
  • wsimport -extension: SOAP 1.2 esetén
  • Overload-olt metódusok esetén problémás

Dynamic Invocation Interface (DII)

  • Dispatcher, Provider
  • @WebServiceProvider
  • public Source invoke(Source)
  • @ServiceMode: PAYLOAD - csak a tartalom, MESSAGE - az egész http kérés, fejlécestől
  • @BindingType() - http
  • Dispatch - Service.createDispatch
  • Https: HttpsURLConnection, HttpsServer
  • @WebService-t felismeri a Glassfish, de a @WebServiceProvider-t nem

Handler

  • Chain of responsibility tervezési minta
  • Logical handler: Source, JAXB - protokollfüggetlen - csak a payloadhoz tud hozzáférni
  • SOAP/protocol handler: SOAP, SAAJ, hozzáfér a teljes envelope-hoz
  • Kliens oldalon a handler chainben nem csak a konfig sorrend dönt, hanem előbb futnak le a logical handlerek, és csak utána a soap handlerek
  • Programozottan handler hozzáadása: HandlerResolver
  • SOAPFaultException
  • SOAP 1.2: BindingType annotáció
  • SOAP 1.2: mustUnderstand
  • Szerver oldalon: WebServiceContext.getMessageContext -> hozzáférés a context-hez (map), és abból a http header-ökhöz
  • Kliens oldalon: a port BindingProvider-ré cast-olható, van getRequestContext metódusa
  • Dependency injection: WebServiceContext

MTOM

  • MTOM: XSD, @BindingType, publikálásnál: ((SOAPBinding) endpoint.getBinding()).setMTOMEnabled(true);
  • Kliens: activation.DataHandler
  • Kliens file küldés: ((SOAPBinding)((BindingProvider) port).getBinding()).setMTOMEnabled(true);
  • @MTOM annotáció

WSIT

  • Metro: azon része mely az MS-sel való együttműködés: WSIT - Webservice Interoperability Technologies - Security, Reliability, Transaction, bootstrapping, optimalization (régen project Tango)
  • Bootstrapping: WS-MetadataExchange
  • Reliable messaging: egyszeri, pontosan egyszeri üzenettovábbítás - acknowledge-al, sorrend (opcionálisan bekapcsolható)
  • Atomic: AtomicTransaction, Coordination

Security

  • XML and WebServices Security Project (XWSS)
  • WS-Security: message content integrity and confidentality, Prompter, Verifier implements CallbackHandler
  • WS-Security (x) felett: WS-Policy felette WS-SecurityPolicy (x), WS-PolicyAttachment (x), WS-Trust (x), WS-Privacy, afelett WS-Secure Conversation (x), WS-Federation, WS-Authorization
  • WS-Secure conversation - shared security context, több kérés/válasz esetén nem kell mindig az összes security információt küldeni - new security token type
  • Trust: security token
  • SecurityPolicy, mely a Policy-ra épül: security követelmények és tulajdonságok leírására
  • WS-Trust: security token, Security Token Service - STS, az STS SAML tokent küld a kliensnek
  • Signing and encription: WSDL-be plusz tag-ek

WS-Addressing

  • WS-Addressing: protokollfüggetlen címzés
  • Kettő spec van: W3C WS-Addressing, Member Submission WS-Addressing, a Metro mindkettőt támogatja
  • Standard tag-ek: To, From, ReplyTo, FaultTo, MessageID, Action, RealtesTo
  • Végpont referencia: EPR
  • MI header: message information
  • Message Addressing Properties (MAPs)
  • Anonymous uri: nem címezhető, pl. request/response request párja
  • Annotáció: @javax.xml.ws.soap.Addressing, @Action, @FaultAction
  • WSDL-ben: wsdl11:port vagy wsdl11:binding tag-be új tag
  • Kliens oldal: WebServiceFeature -> AddressingFeature
  • BindingProvider.SOAPACTION_URI_PROPERTY-t kell kliens oldalon beállítani
  • Két paraméter: enabled, required

SAAJ

  • Új SOAPMessage létrehozásánál létrehozza a Part-ot, Envelope-ot és Header-t
  • Attachment Part, mime headers, Content
  • SOAPConnection
  • Attachment: Content-Type, -Id, -Location
  • Attachment setContent: String, stream, javax.xml.transform.Source vagy javax.activation.DataHandler
  • A SOAP 1.1 specifikáció közvetlenül a header-ben csak a következő attribútumokat engedi: actor és mustUnderstand
  • A SOAP 1.2 spec. ellenben: role (actor új neve), mustUnderstand, és relay
  • Ha van SOAPFault a Body-n belül, nem lehet más
  • code, string kötelező, lehet actor, SOAP 1.2-nél code, role, reasonText (locale-lal)
  • A kódok QName-ek - SOAP specifikáció definiálja

RESTful

  • Roy Fielding: Architectural Styles and the Design of Network-based Software Architectures, 2000 (HTTP specifikáció egyik írója), Apache Software Foundation egyik alapítója
  • Egyedileg címezhető erőforrások: resource, URI
  • Uniform, constrained interface for manipulate resources
  • Representation-oriented, content negotiation
  • Stateless
  • Hypermedia As The Engine Of Application State (HATEOAS): embedded links

JAX-RS

  • JAX-RS 1.1 (JSR 311)
  • Referencia implementáció: Jersey
  • POJO, annotation alapú
  • Annotációk öröklése: super-class előnyt élvez az interfészen lévővel szemben
  • Ha az implementáción van annotáció, akkor a többi helyen lévő annotációt nem veszi figyelembe
  • Application osztály, kiterjeszteni kell, osztályokat ad vissza, melyet a provider példányosít, illetve példányokat, melyeket singleton-ként használ. Mindkettőn elvégzi az injection-t.
  • Application erőforrásokat (@Path annotációval ellátott osztályokat), és provider-eket adhat vissza
  • A JAX-RS provider cserélhető, erre van a RuntimeDelegate, saját alkalmazásban nem kell használni

Provider

  • A provider, melyen rajta van a @Provider annotáció, és valamilyen JAX-WS interfészt implementál
  • Kell minimum egy publikus konstruktor, akár paraméterezett. Mindig a legtöbb paraméterrel rendelkező konstruktort választja
  • Provider pl. a MessageBodyReader, Writer
  • Provider pl. a ContextResolver, mellyel saját Context, pl. JAXBContext példányosítható
  • ExceptionMapper-ek is provider-ek

Context

  • Per request esetén nincs párhuzamossági probléma
  • Per request esetén attribútum is injektálható
  • Konstruktor paraméter mindig injektálható
  • A három első olvasó, aki ide eljut, vendégem egy sörre a következő JUM-on. Dobj egy e-mailt!
  • @Context annotációval injektálunk
  • A következőkbe injektálhatók: resource, provider, Application leszármazott
  • A következők injektálhatók: Application (önmagába nem), UriInfo, HttpHeaders, Request, SecurityContext, Providers
  • A Providers-en keresztül hozzá tudunk férni a MessageBodyReader, Writer-ekhez, ContextResolver-hez, ExceptionMapper-hez, azaz amit a @Provider annotációval elláthatunk

Erőforrások

  • @Path
  • Root resource class: vagy @Path-tal annotált, vagy van legalább egy Path-tal vagy request method designatorral (@GET, stb.) annotált metódusa
  • Request method: request method designatorral annotált metódus
  • Egy metóduson csak egy @GET, @PUT, stb. annotáció lehet, különben deployment error
  • A @HttpMethod annotáció egy metaannotáció, mely rajta van a @GET, stb. metódusokon
  • HEAD kérés esetén először @HEAD metódust keres, ha nincs, akkor a @GET-et hívja, csak nem ad Response-t
  • OPTIONS kérés először @OPTIONS metódust keres, ha nincs választ generál az annotációk alapján -> WADL
  • @ApplicationPath globális url megadásra, ehhez jön hozzá a resource-onkénti
  • A /{foo} path-ra nem illeszkedik a /foo/bar, de a /{foo: .+} path-ra igen (lásd perjelek értelmezése)
  • Amennyiben egy url több path-ra is illeszkedik, a provider a legpontosabbra próbálja illeszteni. Van egy nem minden esetet lefedő precedencia szabály, mely általában jó. Először a literálok számát nézi, majd a template-ek számát, majd a reguláris kifejezésekkel ellátott template-ek számát.
  • Nem minden karakter megengedett az uri-ban, valamint van, aminek speciális jelentése van. A többit escape-elni kell. A @Path annotációban nem kötelező escape-elni.
  • A subresource olyan POJO, melyhez egy resource POJO továbbítja a kiszolgálást. Nem kell rá @Path annotáció, hiszen nem a root uri-hoz képest figyel, valamint nem kell az Application osztályban regisztrálni.
  • Ha az illeszkedő path-ban két mátrix paraméter ugyanazon a néven szerepel, akkor PathSegment-et kell használni, mert nem egyértelmű a @MatrixParam injection. @PathParam List<PathSegment> formában
  • @FormParam esetén implicit dekódolás van, @Consumes("application/x-www-form-urlencoded")
  • Primitív típus, String mappelésén kívül minden olyan típust mappel, melynek van String paramétert váró konstruktora, vagy statikus valueOf metódusa String paraméterrel
  • Van automatikus collection konverzió
  • @HeaderParam, @CookieParam mappelési hiba esetén 400-as hiba, amúgy 404
  • @DefaultValue annotációval adhatjuk meg az alapértelmezett értékeket
  • @Encoded annotációval adhatjuk meg, hogy mi akarjuk dekódolni, tehát azt kapjuk, amit a HTTP ad, dekódolás nélkül

Content Handlers

  • A következő típusokat standard MessageBodyReader-ek és Writer-ek kezelik, ezek entity provider-ek
  • StreamingInput, StreamingOutput - callback model, általában performancia okokból jobb, ha a provider hív vissza (pl. lehet, hogy új szálon), valamint illeszkedik az aszinkron modellbe.
  • InputStream, Reader
  • File, byte[], String, char[] is használható input/output paraméterként
  • Activation DataSource is kezelendő
  • MultivaluedMap<String, String> form értékekhez, dekódolja a provider, használható az @Encoded annotáció
  • javax.xml.transform.Source, a Document-et nem definiálja a specifikáció
  • JAXB: XmlRootElement, XmlType annotációval jelölt osztályok és JAXBElement példányba burkolt objektumok leképzését is támogatja
  • JAXBContext-et tud példányosítani, de felüldefiniálhatjuk ContextResolver<JAXBContext>-ben (pluggable factories), amit az Application-ben definiálhatunk
  • JSON-höz nem kell speciális kezelés, egyedül a mime type-ot kell application/json-ként jelölni
  • Saját marshallinghoz: MessageBodyWriter, sorbarendezés, legjobb illesztés a mime type-ra, @Provider annotáció, @Produces annotáció
  • MessageBodyReader, @Provider, @Consumes annotáció
  • isWritable, isReadable - a paraméterként adott objektumot tudja-e kezelni (+generikus típus, annotáció, media type)

Response code, response, exception

  • ResponseBuilder-rel előállítható a Response
  • WebApplicationException saját kivétel
  • Megadható benne saját Response
  • Error vagy unchecked exception megy a konténer felé, a többit viszont be kell csomagolni, és úgy megy a konténer felé
  • ExceptionMapper a kivételek kezelésére, generikussal paraméterezhető, mindig a kivételre legjobban illeszkedőt keresi
  • ExceptionMapper-t a @Provider annotációval kell ellátni

Content Negotiation

  • @Produces, @Consumes, tehető resource-ra, metódusra, és a content handlerre is
  • Variant: media type, language, encoding
  • VariantListBuilder: builder

HATEOAS

  • UriBuilder URI-k összeállítására, template paraméter is használható
  • Az UriBuilder egy resource osztályt kapva paraméterként is képes összeállítani az URI-t
  • UriInfo-val is létrehozható UriBuilder, ekkor adott a séma, szerver, port, context
  • Cache-elés a CacheControl osztályon keresztül, nincs rá annotáció
  • EntityTag osztály az ETag kezelésére
  • Szerver oldalon kezelni a If-Modified-Since vagy ETag headereket: Request interfész (injektálható) evaluatePreconditions metódusai.
  • Nem csak cache-elésre használható, hanem konkurrencia kezelésre is, hogy csak akkor történjen a módosítás, ha nem változott az erőforrás

Deploy

  • Deploy: JAX-RS unaware konténerben egy servletet, és annak int-param-ként kell megadni az Application-t, aware konténerben az Application tehető közvetlenül a web.xml-be. Java EE 6-nál nem kell semmi az xml-be, classpath-t bejárja, és nézi az annotációkat.
  • @Context annotációval a ServletContext és a ServletConfig injektálható
  • Java EE 6 konténerben a szokásos dolgok injektálhatók: @Resource, @PersistenceContext, @PersistenceUnit, és @EJB, támogatja Java EE 6-ban a JSR-299 szabványt.
  • Java EE konténer által biztosított autentikáció és authorizáció adott. Programozott esetben a SecurityContext @Context annotációval injektálható

Kliens

  • Szabvány nem szól róla
  • Legegyszerűbb esetben HttpURLConnection
  • setDoOutput - request body-ba is lehet írni
  • Jersey Client API