JavaEE Training Note - Day 04
Today’s first topic is the bi-directional communication with
WebSocket using Spring Framework. By using the SockJS
library as well as support on
server side, some other techniques including the XHR polling and
XHR streaming are provided as fallbacks. The STOMP is a sub-protocol
under the WebSocket protocol, which use Pub/Sub pattern to manage messages.
Another topic of today is integration of Hibernate into Spring MVC.
Simple WebSocket using Spring
Begin from version 4 and later, the Spring Framework add some new components to support
WebSocket. First add related dependencies to project. If using Gradle as build tool,
add the following dependency: compile 'org.springframework:spring-websocket:4.3.6.RELEASE'
(alternate the version number accordingly).
On the server side, WebSocketHandler
can handle the data sent from client and
send data back to client. Create a new class that extends the TextWebSocketHandler
as a starting point. The following code shows a simple WebSocket handler that echo
to client what it is received.
|
|
Then, register the handler to Spring in dispatcher-servlet.xml
.
|
|
Then add some client JavaScript to interact with the server using standard WebSocket API.
Add the JavaScript to a webpage contains the following element, then the Spring server can response to client when the data is received.
|
|
Serving Frontend Resource with WebJars
Before the configuration of other features relating to WebSocket in Spring, there is some preparation work that requires to be done. Since the WebSocket requires both the client and server to work together to exchange data bidirectionally, some browser side components are also vital in the whole program. Therefore, prepare and serve the client side library is the first thing need to done.
Even though there already are several JavaScript based options to choose, there are also Java based solutions with tighter integration to Spring server, which including the awesome WebJars project.
Basic setup
WebJars project repack the frontend library into JARs and manage the dependency relationships
of the packages with maven. For example, the jQuery library can be acquired from the
following maven coordination: org.webjars:jquery:3.1.0
. Add it to build configuration
or download the jar package to classpath (while in this method, the dependencies will not be
able to resolve automatically).
Next, to access these resources in Spring MVC, use the following pattern:
And add the resources mapping in Spring MVC configuration file: dispatcher-servlet.xml
.
|
|
Version agnostic path
Since the frontend packages always update frequently, the WebJars provides a version agnostic path resolver that automatically finds a suitable version of package.
First, add the following package into project: org.webjars:webjars-locator:0.32
.
In a recent update to Spring Framework, the WebJars Locator can be automatically
loaded by Spring. Thus, without no further configuration, just remove the version
number form the package then the magic works.
|
|
Using SockJS
As mentioned in the beginning, add SockJS
to project to support more browser with some
fallback techniques when native WebSocket is not available.
First add the client library to project with maven coordination: compile 'org.webjars:sockjs-client:1.0.2'
.
Then load it into web page with following tag:
Next update the server to enable support to SockJS protocol. The SockJS protocol add an extra
step before the handshake of WebSocket to report client capability and negotiate the protocol to
use. This is done by accessing to an endpoint which append /info
to the end of the declared endpoint.
Then the server reply the specific endpoint for suitable protocol to access. The updated handler
registration will be similar to the following one.
|
|
As a important philosophy of SockJS
is to follow the WebSocket
API as close as
possible, there are not much update required to the previous code.
Then replace the WebSocket
with SockJS
in the client script to meet the server configuration.
|
|
STOMP and Message Architecture
The WebSocket is a relative lightweight framework that provides few definitions for formatting and framing message, controlling and managing the connection, etc., which is just like the bare TCP protocol that is not quite easy to use. Just like the HTTP protocol on top of the TCP protocol which provides more functions then the TCP and is being used by more users, some sub-protocols are also defined to manage message on WebSocket. In the following examples, the STOMP (Simple Text Oriented Message Protocol) sub-protocol is used as application level protocol.
The STOMP protocol create a Pub/Sub (Publisher/Subscriber) pattern across the client and server. After a client create a session (a connection between client and server) with the server, it can sent message to or subscribe to some message queue labeled by destination. When a message is pushed into a destination, all of the connected subscribers of a destination will receive the message.
To manage the different queues of messages defined in STOMP protocol, Spring
use message broker to wrap the original based WebSocket or SockJS. Then the message can be
maintained by a simple-broker
provided by Spring or redirect to full featured
message broker like RabbitMQ
. Here, for simplicity, the simple-broker
is used.
Since all of the subscribers of a destination will receive the message published in it,
the simple-broker
use some conversion to transform the destination name to distinguish
different level of message including broadcast, single-user or point-to-point(single session).
Some rules are listed below:
Each mapped name within the server can be prefixed in order to prevent conflict with other queue name. This can be configured with key
application-destination-prefix
forwebsocket:message-broker
. For example, a message handler is mapped to/hello
in server will handle message sent to/app/hello
destination when the prefix is configured as/app
;The prefix
/topic
is used to indicate a broadcast message. By default, the return value of a message handler mapped to/hello
without extra configuration will be push to destination/topic/hello
which can be subscribed by client;The prefix
/queue
is used to indicate a point to point message.
As Spring document illustrated, the prefixed destination have the relationships show in following diagram:
|
|
Using STOMP
To use STOMP in Spring, first add the configuration at the dispatcher-servlet.xml
.
The following code are used to configure the simple broker.
Some other packages are required, including Jackson and STOMP client library.
Since the message are encoded in JSON, the Jackson library is used to
manage the conversion with POJO. The maven coordinations required are
com.fasterxml.jackson.core:jackson-core:2.8.7
and
com.fasterxml.jackson.core:jackson-databind:2.8.7
The latter can be acquired from WebJars. The maven coordination required
is org.webjars:stomp-websocket:2.3.3
.
Then the message can be handled in general Spring MVC Controller.
Apart from making response to incoming message, application can
publish message at any point of the program by using an injected
SimpMessagingTemplate
instance. The following controller shows te
|
|
The client JavaScript also need to update to utilize the new message model.
Currently, any connected client can receive message from server when any client publish one to the queue or submit it via web from.
Hibernate with Spring MVC
(This is continued on the progress of the last day.)
Layered Architecture
The general used pattern of Spring MVC application split the application into multiple layers from top to bottom listed as follows: (That is form the layer closest to the user client to server)
the representation layer: including the Spring MVC controller and the JSP pages (or other view technologies). Control the appearance of the whole application;
the business layer: including the logic for core functionalities of the application. These logic are sharable to multiple controllers and generally named as Service;
the persistence layer: including the data access object (DAO) and directly interact with the server;
the entity: object model that holds the data in memory.
Hibernate as persistence layer
Some beans are required to integrate Hibernate into Spring MVC. The xml definition are listed as follows:
|
|
Sample service
Service process data and interact with DAOs.
|
|
Sample DAO
A DAO manage actions related to one table.