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