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, majdservice,port:portType(interfész) ésbinding(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
finalvagyabstract - Default public constructor-nak lennie kell, nem lehet
finalize, nem tárolhat állapotot - Metódusai nem lehetnek
staticvagyfinal 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
WebMethodcsak további konfigurációkra való - A
wsimportgenerá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/appinfotag-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) @WebServiceannotációtargetNamespaceattribútuma adja meg a névteret, amúgy a package alapján@RequestWrapper,@ResponseWrapperWebParam.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 AsyncHandlerResponsewsimport -extension: SOAP 1.2 esetén- Overload-olt metódusok esetén problémás
Dynamic Invocation Interface (DII)
- Dispatcher, Provider
@WebServiceProviderpublic 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:
BindingTypeannotá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ó, vangetRequestContextmetó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); @MTOMannotá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:portvagywsdl11:bindingtag-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
SOAPMessagelétrehozásánál létrehozza aPart-ot,Envelope-ot ésHeader-t - Attachment Part, mime headers, Content
SOAPConnection- Attachment:
Content-Type,-Id,-Location - Attachment
setContent:String, stream,javax.xml.transform.Sourcevagyjavax.activation.DataHandler - A SOAP 1.1 specifikáció közvetlenül a header-ben csak a következő
attribútumokat engedi:
actorésmustUnderstand - A SOAP 1.2 spec. ellenben:
role(actor új neve),mustUnderstand, ésrelay - Ha van
SOAPFaultaBody-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 (
@Pathannotá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
@Providerannotá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.JAXBContextpé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!
@Contextannotá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 aMessageBodyReader,Writer-ekhez,ContextResolver-hez,ExceptionMapper-hez, azaz amit a@Providerannotá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
@HttpMethodannotáció egy metaannotáció, mely rajta van a@GET, stb. metódusokon HEADkérés esetén először@HEADmetódust keres, ha nincs, akkor a@GET-et hívja, csak nem ad Response-tOPTIONSkérés először@OPTIONSmetódust keres, ha nincs választ generál az annotációk alapján -> WADL@ApplicationPathglobá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
@Pathannotá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á
@Pathannotá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@MatrixParaminjection.@PathParamList<PathSegment>formában @FormParameseté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
Stringparamétert váró konstruktora, vagy statikusvalueOfmetódusaStringparaméterrel - Van automatikus collection konverzió
@HeaderParam,@CookieParammappelési hiba esetén 400-as hiba, amúgy 404@DefaultValueannotációval adhatjuk meg az alapértelmezett értékeket@Encodedannotá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 ésWriter-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,ReaderFile,byte[],String,char[]is használható input/output paraméterként- Activation
DataSourceis kezelendő MultivaluedMap<String, String>form értékekhez, dekódolja a provider, használható az@Encodedannotációjavax.xml.transform.Source, aDocument-et nem definiálja a specifikáció- JAXB:
XmlRootElement,XmlTypeannotációval jelölt osztályok ésJAXBElementpéldányba burkolt objektumok leképzését is támogatja JAXBContext-et tud példányosítani, de felüldefiniálhatjukContextResolver<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,@Providerannotáció,@Producesannotáció MessageBodyReader,@Provider,@Consumesannotá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ó aResponse- ` 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é
ExceptionMappera kivételek kezelésére, generikussal paraméterezhető, mindig a kivételre legjobban illeszkedőt keresiExceptionMapper-t a@Providerannotá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
UriBuilderURI-k összeállítására, template paraméter is használható- Az
UriBuilderegy 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
CacheControlosztályon keresztül, nincs rá annotáció EntityTagosztály azETagkezelésére- Szerver oldalon kezelni a
If-Modified-SincevagyETagheadereket:Requestinterfész (injektálható)evaluatePreconditionsmetó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 azApplication-t, aware konténerben azApplicationtehető közvetlenül aweb.xml-be. Java EE 6-nál nem kell semmi az xml-be, classpath-t bejárja, és nézi az annotációkat. @Contextannotációval aServletContextés aServletConfiginjektá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@Contextannotá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