See: Description
Interface | Description |
---|---|
CsrfToken |
This is the interface for a security token to prevent cross site request forgery (CSRF) and
potentially other attacks.
|
RemoteInvocationCall |
This is the marker interface for a single remote invocation.
|
Class | Description |
---|---|
DefaultCsrfToken |
This is the default implementation of
CsrfToken it simply uses a string value
as payload. |
Exception | Description |
---|---|
RemoteInvocationCallFailedException |
This exception is thrown if
RemoteInvocationCall has failed. |
Annotation Type | Description |
---|---|
Login |
This annotation for a
RemoteInvocationCall that provides the login
operation. |
byte[]
you will end up with OutOfMemoryError
s
on the server side as all concurrent BLOBs are loaded entirely in main memory. Instead a streaming API like
OutputStream
is required. But how should this work in a limited environment such as a GWT client?@Path("/disposition/{dispositionId}/calculateTotal") @POST @Consumes("application/json") @Produces("application/json") public Amount calculateTotal( @PathParam("dispositionId") Long dispositionId, State dispositionState);You can see that there are a lot of considerations to care about. Also such approach is leading to redundancies if you have a large amount of services. Even worse, if your client is also written in Java the calling code is not directly related to the service operation. You have to manually ensure consistency so everything fits and works together. The latter is better with JAX-WS but SOAP is also causing a lot of problems and limitations. Also during development and maintenance it is hard to trace calls from the client to the server side implementation.
spring-remoting
make your life a lot easier but still require you to configure every service
on server- and client-side. Also it does not address all the questions we listed above.
mmm-service
will make your life a lot easier.
Technically it is based on existing solutions like spring-remoting
(HttpInvoker
, hessian
),
GWT-RPC, and others. Conceptional it defines a generic service via which all remote invocations are send and that
has to be setup and configured only once. All services you define and implement are declared via
CDI
and therefore automatically registered on the server side.
This offers the following advantages:
serializable
(If you want to support
GWT-RPC this has the additional implication that fields are not declared as final and a non-arg constructor is is
present - but does not have to be public).Security
are already build-in.
If you have both secured and public service operations, you can configure how this is detected.
By default JavaEE security annotations (JSR250) as well as spring-security
are supported.queue
that collects invocations and allows to bundle them into a single request to save overhead and boost your performance.
The queuing of invocations can be configured independently of the code that actually triggers the remote invocations.mmm-service
API for the desired protocol."obfuscated"
according to the executing environment.mmm-client
but can also be used standalone.RemoteInvocationService
. Further, you create an server-side implementation for
that interface. If you are using CDI
you only have to annotate the
implementation with Named
and that is all. RemoteInvocationServiceCaller
to
get a stub of your service interface
while providing a callback that receives the result asynchronously and invoke a corresponding method on the stub.
This way you can use your favorite IDE to directly step from the client-side service call to the server-side service
implementation. For its simplicity and compliance with java service design this is the favorite approach.
Here is a simple (undocumented and stupid) example that will show "Hi John" in a popup window:
public interface HelloWorldService extendsRemoteInvocationService
{ String sayHi(String name); } @Named
public class HelloWorldService extends AbstractRemoteInvocationService implements HelloWorldService { public String sayHi(String name) { return "Hi " + name; } } public class ClientComponent { public void doSomething() {RemoteInvocationServiceCaller
caller = getCaller(); HelloWorldService service = caller.getServiceClient
(HelloWorldService.class, String.class, message -> showPopup(message)); service.sayHi("John"); } }
RemoteInvocationCommand
s that represent a single service operation. This
corresponds to a method of a RemoteInvocationService
in RPC style and is a
container for all method parameters. On the server-side you create a corresponding implementation of
RemoteInvocationCommandHandler
. If you are using CDI
you only have to annotate the implementation with Named
and that is all. RemoteInvocationCommandCaller
to
call a command
. This is entirely type-safe due to the
generic type <RESULT> of RemoteInvocationCommand
.
As a further advantage it allows better optimization of serialization (e.g. in GWT the compiler needs to know which
classes can be part of the invocation what can be any Serializable
in RPC while in command style only
classes reachable from a RemoteInvocationCommand
are candidates). Finally it does
not require code generation (for client stubs) in GWT environment where no reflection (dynamic proxies) is available.
Here is a simple (undocumented and stupid) example that will show "Hi John" in a popup window:
public class HelloWorldCommand implementsRemoteInvocationCommand
<String> { private static final long serialVersionUID = 1L; private String name; public HelloWorldCommand(String name) { super(); this.name = name; } public String getName() { return this.name; } } @Named
public class HelloWorldCommandHandler implementsRemoteInvocationCommandHandler
<String, HelloWorldCommand> { public Stringhandle
(HelloWorldCommand command) { return "Hi" + command.getName(); } public Class <HelloWorldCommand>RemoteInvocationCommandHandler.getCommandClass()
{ return HelloWorldCommand.class; } } public class ClientComponent { public void doSomething() {RemoteInvocationCommandCaller
caller = getCaller(); HelloWorldCommand command = new HelloWorldCommand("John"); caller.callCommand
(command, message -> showPopup(message)); } }
Copyright © 2001–2016 mmm-Team. All rights reserved.