您的位置:首页 > 编程语言 > Java开发

使用maven搭建XML风格的Spring MVC+WebSocket+sockjs+STOMP+ActiveMQ应用

2016-01-21 18:46 429 查看
Spring4开始支持WebSocket,也支持通过STOMP协议连接JMS消息服务器如ActiveMQ等。Spring4官方给出了这么一个STOMP例子,不过是使用注解风格的,官方例子没有我们熟悉的web.xml,没有spring.xml,这个跟Spring3差别很大,一时有点接受不了,经过自己的尝试把官方例子改成了XML风格的。

项目的目录结构如下:



我使用的是4.2.4.RELEASE版本的Spring,pom.xml配置如下:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> <modelVersion>4.0.0</modelVersion>
<groupId>net.aty.springmvc</groupId>
<artifactId>SpringMvcDemo</artifactId>
<packaging>war</packaging>
<version>1.0-SNAPSHOT</version>
<name>SpringMvcDemo Maven Webapp</name>
<url>http://maven.apache.org</url>

<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<spring.version>4.2.4.RELEASE</spring.version>
</properties>

<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${spring.version}</version>
</dependency>

<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-websocket</artifactId>
<version>${spring.version}</version>
</dependency>

<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-messaging</artifactId>
<version>${spring.version}</version>
</dependency>

<!--required when the "stomp-broker-relay" profile is enabled. -->
<dependency>
<groupId>io.projectreactor</groupId>
<artifactId>reactor-net</artifactId>
<version>2.0.7.RELEASE</version>
</dependency>

<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-all</artifactId>
<version>4.0.33.Final</version>
</dependency>

<!-- 解决错误:Whoops! Lost connection to undefined -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.6.4</version>
</dependency>

<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>provided</scope>
</dependency>

</dependencies>

<build>
<finalName>SpringMvcDemo</finalName>
</build>
</project>


maven下载的jar如图所示:



java代码如下:

package net.aty.service;

import org.springframework.stereotype.Service;

@Service
public class MyService {

public MyService() {
System.out.println("bean MyService");
}

public String process(String name) {
return name.toLowerCase();
}
}
package net.aty.springmvc;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.messaging.handler.annotation.MessageMapping;
import org.springframework.messaging.simp.SimpMessagingTemplate;
import org.springframework.stereotype.Controller;

@Controller
public class ChatController {

@Autowired
private SimpMessagingTemplate template;

@MessageMapping("/hello")
public String send(String message) {

String text = "[" + System.currentTimeMillis() + "]:" + message;

template.convertAndSend("/topic/greetings", text);

return text;
}
}
package net.aty.springmvc;

import net.aty.service.MyService;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

@Controller
public class FirstController {

@Autowired
private MyService service;

public FirstController()
{
System.out.println("I am a controller.");
}

@RequestMapping("/mvc/first/hello.do")
@ResponseBody
public String hello(@RequestParam("userName") String userName) {
return service.process(userName);
}

}


spring配置文件root-context.xml如下:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">

<context:component-scan base-package="net.aty.service" />

</beans>


spring mvc配置文件如下:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:context="http://www.springframework.org/schema/context"
xmlns:websocket="http://www.springframework.org/schema/websocket"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd http://www.springframework.org/schema/websocket http://www.springframework.org/schema/websocket/spring-websocket.xsd">

<mvc:annotation-driven />

<context:component-scan base-package="net.aty.springmvc" />

<mvc:resources location="/" mapping="/**/*.html" />
<mvc:resources location="/" mapping="/**/*.js" />
<mvc:resources location="/" mapping="/**/*.css" />
<mvc:resources location="/" mapping="/**/*.png" />
<mvc:resources location="/" mapping="/**/*.gif" />

<websocket:message-broker
application-destination-prefix="/app">
<websocket:stomp-endpoint path="/stomp">
<websocket:sockjs />
</websocket:stomp-endpoint>

<websocket:stomp-broker-relay prefix="/topic,/queue"
relay-host="127.0.0.1" relay-port="61613" heartbeat-receive-interval="20000"
heartbeat-send-interval="20000" />

</websocket:message-broker>

</beans>


web.xml配置如下:
<?xml version="1.0" encoding="UTF-8"?>

<web-app version="3.0" xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"> 
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring/root-context.xml</param-value>
</context-param>

<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

<servlet>
<servlet-name>dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring/spring-dispatcher.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>

</web-app>


客户端使用了sockjs+stomp.js,代码如下:

<!DOCTYPE html>
<html>
<head>
<title>Hello WebSocket</title>
<script src="js/sockjs-0.3.4.js"></script>
<script src="js/stomp.js"></script>
<script type="text/javascript">
var stompClient = null;

function setConnected(connected) {
document.getElementById('connect').disabled = connected;
document.getElementById('disconnect').disabled = !connected;
document.getElementById('conversationDiv').style.visibility = connected ? 'visible' : 'hidden';
document.getElementById('response').innerHTML = '';
}

function connect() {
var socket = new SockJS('/SpringMvcDemo/stomp');
stompClient = Stomp.over(socket);
stompClient.connect({}, function(frame) {
setConnected(true);
console.log('Connected: ' + frame);
stompClient.subscribe('/topic/greetings', function(greeting){
showGreeting(greeting.body);
});
});
}

function disconnect() {
if (stompClient != null) {
stompClient.disconnect();
setConnected(false);
console.log("Disconnected");
}
}

function sendName() {
var name = document.getElementById('name').value;
stompClient.send("/app/hello", {}, name);
}

function showGreeting(message) {
var response = document.getElementById('response');
var p = document.createElement('p');
p.style.wordWrap = 'break-word';
p.appendChild(document.createTextNode(message));
response.appendChild(p);
}
</script>
</head>
<body onload="disconnect()">
<noscript><h2 style="color: #ff0000">Seems your browser doesn't support Javascript! Websocket relies on Javascript being enabled. Please enable
Javascript and reload this page!</h2></noscript>
<div>
<div>
<button id="connect" onclick="connect();">Connect</button>
<button id="disconnect" disabled="disabled" onclick="disconnect();">Disconnect</button>
</div>
<div id="conversationDiv">
<label>What is your name?</label><input type="text" id="name" />
<button id="sendName" onclick="sendName();">Send</button>
<p id="response"></p>
</div>
</div>
</body>
</html>


上述web工程打war包后部署到支持J2EE7的容器中,如Tomcat7.0.62版本。有一点需要注意:activeMQ默认没有开启对STOMP协议的支持,需要在{activemq_home}/conf/activemq.xml开启stomp协议:

<transportConnector name="stomp" uri="stomp://0.0.0.0:61613?maximumConnections=1000&wireformat.maxFrameSize=104857600"/>


运行ActiveMQ服务器和Tomcat,可以看到能够正常地发送和接收消息:



最后提一下自己在尝试过程中遇到的错误:

1. 忘记开启activeMQ对stomp协议的支持,这会导致建立连接报错。

2.缺少jar包,我们再pom.xml中配置的是netty-all和jackson-databind,会传递依赖好几个jar。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息