| Interface | Description |
|---|---|
| Authenticator |
An authenticator of user credentials.
|
| AuthService |
An authentication service interface.
|
| Messages |
The internationalization constants used by this package.
|
| ServerProvider<T> |
Provides access to a
Server object. |
| ServiceBase |
The base interface for all stateful web services.
|
| SessionFactory<T> |
A session (data object) factory.
|
| Class | Description |
|---|---|
| AuthServiceImpl<T> |
An authentication service implementation.
|
| Client |
A client node for stateful communication.
|
| ClientContext |
The client context which the client must supply as an argument to
every stateful remote call.
|
| FixedAuthenticator |
An authenticator which accepts a single pair of user name/password
credentials.
|
| RemoteCall<T> |
An implementation wrapper for stateful services.
|
| RemoteCaller<S,T> |
An implementation wrapper for stateful services.
|
| RemoteRunner<S> |
An implementation wrapper for stateful services.
|
| Server<SessionClazz> |
A server node for stateful communication.
|
| ServiceBaseImpl<T> |
The base class for all stateful web services, which retains an
optional session manager.
|
| SessionHolder<T> |
A session holder.
|
| SessionManager<T> |
A session manager.
|
Web services infrastructure.
See the test classes of
the org.marketcetera.util.ws.sample package.
Below are limitations/known issues with the current implementation of web services. All limitations are due to the underlying third-party libraries used to implement web services (Apache CXF and JAXB).
Every class that needs to be marshalled must have an empty
constructor. Any classes marshalled by an exception (e.g. as
properties of an exception) must have a public empty
constructor; for all other classes, that empty constructor can be
private. For custom exceptions (custom replacements
of RemoteException), a
single-argument String constructor also works, and is
supplied the fault message during unmarshalling. Property getters and
setters must be public
A class C that needs to be marshalled and that has
a type parameter T may not have T[]
properties. Also, in certain instances, the marshaller can get
confused when such classes are used in the context of arrays
(e.g. use C[] instead of C<?>[]
or C<Foo>[]) or nested generics
(e.g. use Bar<C>[] instead
of Bar<C<?>>[]
or Bar<C<Foo>>[]).
Generally, be cautious about generics because the actual type
to which T is bound is not available at run-time. For
example, assume C has a property of type T,
and T has a lower bound of,
say, Map<?,?>. You can write code that
binds T to a TreeMap<?,?>. However, as
discussed below, the marshaller will always send across the wire a
tree map as a hash map, and will only create a tree map again if
the runtime introspection of C tells the
marshaller that the property must be a tree map. But the runtime
introspection will yield a Map<?,?> (the lower
bound), and so you will get a hash map assigned to a variable which
will now execute in the context of code that expects a tree
map.
Extending the previous point, consider this pitfall as well: a
service has an argument of type A<B>
declared as A<T extends BaseT> (and thus
B is a descendant of BaseT), then
JAXB will not create a support class for B
because run-time reflection of A will trigger the
creation of a BaseT support class, not a
B one. Hence marshalling will encounter problems unless
there is some method (or property) anywhere within the same service
interface that makes direct use of B which thereby forces
JAXB to create a support class for B (this can be
accomplished using the @XmlSeeAlso annotation,
instead). Note that such errors will occur only at run-time and when
the argument above is operated upon in such a manner
that B comes into play.
@XmlTransient, unlike regular annotations, is
inherited. This means that a parent class which has annotated a
property as transient will prevent a child class from marshalling a
property by the same name.
A class that needs to be marshalled may not have a property whose type is a non-static inner class.
If the marshaller marshals an object of type B
(e.g. a class has a property of type B), then the
unmarshalled object will always be of type B, even
if the actual runtime type of the object originally supplied to the
marshaller is of a class derived from B. To enable
support of inherited classes, you need to add some method (or
property) anywhere within the same service interface that makes direct
use of each inherited class (or use the @XmlSeeAlso
annotation).
The previous point also applies to exceptions thrown by service
methods. However, for exceptions, it is possible to add multiple
classes in the throws clause of a method, incl. classes which may be
related by super/subclass relationships. In that case, the actual
exception class will be unmarshalled if it is one of the classes in
the clause. Unlike regular objects, adding an exception
subclass D (extending B) in a
different method of the same service interface (or using
the @XmlSeeAlso annotation) will not enable marshalling
of a D exception as a D within a method
whose throws clause lists only B explicitly.
Character objects (meaning Character,
not char primitives) are sometimes treated as integers,
and hence are not marshalled properly; strings (provided they do not
contain certain illegal characters like ) and char
primitives (of all values) are properly marshalled. Specifically,
Character objects as method arguments/results have problems when used
in maps.
Date objects are sometimes treated as calendars, and hence
are not marshalled properly. Specifically, Date objects as method
arguments/results have problems when used in maps. Worse, even
outside maps, JAXB does not marshall dates correctly in certain
time zones, including GMT: it adds an hour to the marshalled
date. Hence, wrap Date objects by a DateWrapper which
remedies the above shortcomings.
Collections and maps undergo special handling during
marshalling. When a set needs to get marshalled, it is always
converted to a HashSet; a collection to
an ArrayList; and a map to a HashMap. During
unmarshalling, if the desired type is the generic collection/set/map
interface, there is no need for further processing. However, if the
desired type is, say, a tree set, then an empty tree set is created,
and then stuffed with the elements of the
transferred HashSet. A drawback of this process is that
it is not possible to transfer sorted collections/maps of elements
that do not implement Comparable because the comparator
itself is not marshalled.
Maps (the Map interface or HashMap
or TreeMap) cannot be used as method arguments or results;
but they can be used as properties. To pass a map as a method
argument/result, use MapWrapper.
Copyright © 2015. All Rights Reserved.