Тайлбар байхгүй

Jay Bryant 7676a968d6 Upgrade to Boot 2.4.2 4 жил өмнө
complete 7676a968d6 Upgrade to Boot 2.4.2 4 жил өмнө
initial 7676a968d6 Upgrade to Boot 2.4.2 4 жил өмнө
test 6828e2ac12 Convert to mvn compile for initial codeset 11 жил өмнө
.gitignore 69bb7ddee3 Add ignores for VSCode 5 жил өмнө
.travis.yml 7676a968d6 Upgrade to Boot 2.4.2 4 жил өмнө
CONTRIBUTING.adoc 4ab0e0f198 Add CONTRIBUTING doc 9 жил өмнө
LICENSE.txt aff42cddc1 Upgrade LICENSE file to comply with standards. 4 жил өмнө
README.adoc 7676a968d6 Upgrade to Boot 2.4.2 4 жил өмнө

README.adoc

:spring_version: current
:jackson: https://wiki.fasterxml.com/JacksonHome
:AtMessageMapping: https://docs.spring.io/spring/docs/{spring_version}/javadoc-api/org/springframework/messaging/handler/annotation/MessageMapping.html
:AtController: https://docs.spring.io/spring/docs/{spring_version}/javadoc-api/org/springframework/stereotype/Controller.html
:AtEnableWebSocketMessageBroker: https://docs.spring.io/spring/docs/{spring_version}/javadoc-api/org/springframework/messaging/simp/config/EnableWebSocketMessageBroker.html
:Stomp_JS: http://jmesnil.net/stomp-websocket/doc/
:AtSendTo: https://docs.spring.io/spring/docs/{spring_version}/javadoc-api/org/springframework/messaging/handler/annotation/SendTo.html
:toc:
:icons: font
:source-highlighter: prettify
:project_id: gs-messaging-stomp-websocket

This guide walks you through the process of creating a "`Hello, world`" application that
sends messages back and forth between a browser and a server. WebSocket is a thin,
lightweight layer above TCP. This makes it suitable for using "`subprotocols`" to embed
messages. In this guide, we use
http://en.wikipedia.org/wiki/Streaming_Text_Oriented_Messaging_Protocol[STOMP] messaging
with Spring to create an interactive web application. STOMP is a subprotocol operating
on top of the lower-level WebSocket.

== What You Will build

You will build a server that accepts a message that carries a user's name. In response,
the server will push a greeting into a queue to which the client is subscribed.

== What You Need

:java_version: 1.8
include::https://raw.githubusercontent.com/spring-guides/getting-started-macros/master/prereq_editor_jdk_buildtools.adoc[]

include::https://raw.githubusercontent.com/spring-guides/getting-started-macros/master/how_to_complete_this_guide.adoc[]

[[scratch]]
== Starting with Spring Initializr

For all Spring applications, you should start with the https://start.spring.io[Spring
Initializr]. The Initializr offers a fast way to pull in all the dependencies you need for
an application and does a lot of the set up for you. This example needs only the Websocket
dependency.

You can get a Maven build file with the necessary dependencies directly from the https://start.spring.io/#!type=maven-project&language=java&platformVersion=2.4.2.RELEASE&packaging=jar&jvmVersion=11&groupId=com.example&artifactId=messaging-stomp-websocket&name=messaging-stomp-websocket&description=Demo%20project%20for%20Spring%20Boot&packageName=com.example.messaging-stomp-websocket&dependencies=websocket[Spring Initializr].
The following listing shows the `pom.xml` file that is created when you choose Maven:

====
[src,xml]
----
include::initial/pom.xml[]
----
====

You can get a Gradle build file with the necessary dependencies directly from the https://start.spring.io/#!type=gradle-project&language=java&platformVersion=2.4.2.RELEASE&packaging=jar&jvmVersion=11&groupId=com.example&artifactId=messaging-stomp-websocket&name=messaging-stomp-websocket&description=Demo%20project%20for%20Spring%20Boot&packageName=com.example.messaging-stomp-websocket&dependencies=websocket[Spring Initializr].
The following listing shows the `build.gradle` file that is created when you choose Gradle:

====
[src,java]
----
include::initial/build.gradle[]
----
====

== Adding Dependencies

The Spring Initializr does not provide everything you need in this case. For Maven, you
need to add the following dependencies:

====
[source,xml]
----

org.webjars
webjars-locator-core


org.webjars
sockjs-client
1.0.2


org.webjars
stomp-websocket
2.3.3


org.webjars
bootstrap
3.3.7


org.webjars
jquery
3.1.1-1

----
====

The following listing shows the finished `pom.xml` file:

====
[src,xml]
----
include::complete/pom.xml[]
----
====

If you use Gradle, you need to add the following dependencies:

====
[source,java]
----
implementation 'org.webjars:webjars-locator-core'
implementation 'org.webjars:sockjs-client:1.0.2'
implementation 'org.webjars:stomp-websocket:2.3.3'
implementation 'org.webjars:bootstrap:3.3.7'
implementation 'org.webjars:jquery:3.1.1-1'
----
====

The following listing shows the finished `build.gradle` file:

====
[src,java]
----
include::complete/build.gradle[]
----
====

[[initial]]
== Create a Resource Representation Class

Now that you have set up the project and build system, you can create your STOMP message
service.

Begin the process by thinking about service interactions.

The service will accept messages that contain a name in a STOMP message whose body is a
JSON object. If the name is `Fred`, the message might resemble the following:

====
[source,json]
----
{
"name": "Fred"
}
----
====

To model the message that carries the name, you can create a plain old Java object with a
`name` property and a corresponding `getName()` method, as the following listing (from
`src/main/java/com/example/messagingstompwebsocket/HelloMessage.java`) shows:

====
[source,java,tabsize=2]
----
include::complete/src/main/java/com/example/messagingstompwebsocket/HelloMessage.java[]
----
====

Upon receiving the message and extracting the name, the service will process it by
creating a greeting and publishing that greeting on a separate queue to which the client
is subscribed. The greeting will also be a JSON object, which as the following listing
shows:

====
[source,json]
----
{
"content": "Hello, Fred!"
}
----
====

To model the greeting representation, add another plain old Java object with a `content`
property and a corresponding `getContent()` method, as the following listing (from
`src/main/java/com/example/messagingstompwebsocket/Greeting.java`) shows:

====
[source,java,tabsize=2]
----
include::complete/src/main/java/com/example/messagingstompwebsocket/Greeting.java[]
----
====

Spring will use the {jackson}[Jackson JSON] library to automatically marshal instances of
type `Greeting` into JSON.

Next, you will create a controller to receive the hello message and send a greeting
message.

== Create a Message-handling Controller

In Spring's approach to working with STOMP messaging, STOMP messages can be routed to
{AtController}[`@Controller`] classes. For example, the `GreetingController` (from
`src/main/java/com/example/messagingstompwebsocket/GreetingController.java`) is mapped to
handle messages to the `/hello` destination, as the following listing shows:

====
[source,java,tabsize=2]
----
include::complete/src/main/java/com/example/messagingstompwebsocket/GreetingController.java[]
----
====

This controller is concise and simple, but plenty is going on. We break it down step by
step.

The {AtMessageMapping}[`@MessageMapping`] annotation ensures that, if a message is sent to
the `/hello` destination, the `greeting()` method is called.

The payload of the message is bound to a `HelloMessage` object, which is passed into
`greeting()`.

Internally, the implementation of the method simulates a processing delay by causing the
thread to sleep for one second. This is to demonstrate that, after the client sends a
message, the server can take as long as it needs to asynchronously process the message.
The client can continue with whatever work it needs to do without waiting for the
response.

After the one-second delay, the `greeting()` method creates a `Greeting` object and
returns it. The return value is broadcast to all subscribers of `/topic/greetings`, as
specified in the {AtSendTo}[`@SendTo`] annotation. Note that the name from the input
message is sanitized, since, in this case, it will be echoed back and re-rendered in the
browser DOM on the client side.

== Configure Spring for STOMP messaging

Now that the essential components of the service are created, you can configure Spring to
enable WebSocket and STOMP messaging.

Create a Java class named `WebSocketConfig` that resembles the following listing (from
`src/main/java/com/example/messagingstompwebsocket/WebSocketConfig.java`):

====
[source,java,tabsize=2]
----
include::complete/src/main/java/com/example/messagingstompwebsocket/WebSocketConfig.java[]
----
====

`WebSocketConfig` is annotated with `@Configuration` to indicate that it is a Spring
configuration class. It is also annotated with
{AtEnableWebSocketMessageBroker}[`@EnableWebSocketMessageBroker`]. As its name suggests,
`@EnableWebSocketMessageBroker` enables WebSocket message handling, backed by a message
broker.

The `configureMessageBroker()` method implements the default method in
`WebSocketMessageBrokerConfigurer` to configure the message broker. It starts by calling
`enableSimpleBroker()` to enable a simple memory-based message broker to carry the
greeting messages back to the client on destinations prefixed with `/topic`. It also
designates the `/app` prefix for messages that are bound for methods annotated with
`@MessageMapping`. This prefix will be used to define all the message mappings. For
example, `/app/hello` is the endpoint that the `GreetingController.greeting()` method is
mapped to handle.

The `registerStompEndpoints()` method registers the `/gs-guide-websocket` endpoint,
enabling SockJS fallback options so that alternate transports can be used if WebSocket is
not available. The SockJS client will attempt to connect to `/gs-guide-websocket` and use
the best available transport (websocket, xhr-streaming, xhr-polling, and so on).

== Create a Browser Client

With the server-side pieces in place, you can turn your attention to the JavaScript client
that will send messages to and receive messages from the server side.

Create an `index.html` file similar to the following listing (from
`src/main/resources/static/index.html`):

====
[source,html]
----
include::complete/src/main/resources/static/index.html[]
----
====

This HTML file imports the `SockJS` and `STOMP` javascript libraries that will be used to
communicate with our server through STOMP over websocket. We also import `app.js`, which
contains the logic of our client application. The following listing (from
`src/main/resources/static/app.js`) shows that file:

====
[source,javascript,tabsize=2]
----
include::complete/src/main/resources/static/app.js[]
----
====

The main pieces of this JavaScript file to understand are the `connect()` and `sendName()`
functions.

The `connect()` function uses https://github.com/sockjs[SockJS] and {Stomp_JS}[stomp.js]
to open a connection to `/gs-guide-websocket`, which is where our SockJS server waits for
connections. Upon a successful connection, the client subscribes to the `/topic/greetings`
destination, where the server will publish greeting messages. When a greeting is received
on that destination, it will append a paragraph element to the DOM to display the greeting
message.

The `sendName()` function retrieves the name entered by the user and uses the STOMP client
to send it to the `/app/hello` destination (where `GreetingController.greeting()` will
receive it).

The `main.css` can be omitted if you like, or you can create an empty
one, just so the `` can be resolved.

== Make the Application Executable

Spring Boot creates an application class for you. In this case, it needs no further
modification. You can use it to run this application. The following listing (from
`src/main/java/com/example/messagingstompwebsocket/MessagingStompWebsocketApplication.java`)
shows the application class:

====
[source,java,tabsize=2]
----
include::complete/src/main/java/com/example/messagingstompwebsocket/MessagingStompWebsocketApplication.java[]
----
====

include::https://raw.githubusercontent.com/spring-guides/getting-started-macros/master/spring-boot-application-new-path.adoc[]

include::https://raw.githubusercontent.com/spring-guides/getting-started-macros/master/build_an_executable_jar_subhead.adoc[]

include::https://raw.githubusercontent.com/spring-guides/getting-started-macros/master/build_an_executable_jar_with_both.adoc[]


Logging output is displayed. The service should be up and running within a few seconds.

== Test the service

Now that the service is running, point your browser at http://localhost:8080 and click the *Connect* button.

Upon opening a connection, you are asked for your name. Enter your name and click *Send*.
Your name is sent to the server as a JSON message over STOMP. After a one-second simulated
delay, the server sends a message back with a "`Hello`" greeting that is displayed on the
page. At this point, you can send another name or you can click the *Disconnect* button to
close the connection.

== Summary

Congratulations! You have just developed a STOMP-based messaging service with Spring.

== See Also

The following guides may also be helpful:

* https://spring.io/guides/gs/serving-web-content/[Serving Web Content with Spring MVC]
* https://spring.io/guides/gs/spring-boot/[Building an Application with Spring Boot]

include::https://raw.githubusercontent.com/spring-guides/getting-started-macros/master/footer.adoc[]