SpringBoot 整合 dwr ,實(shí)現(xiàn) js 直接調(diào)用后端 Service.
前一段時(shí)間由于工作需要接觸到了dwr,使用dwr將mq接收到的消息推送到前臺(tái)厌衙,最近項(xiàng)目改用springboot隆判,因此又去重新回爐了一下。
1.新建springboot項(xiàng)目,添加下面dwr的依賴文件
<!-- DWR -->
<dependency>
<groupId>org.directwebremoting</groupId>
<artifactId>dwr</artifactId>
<version>3.0.2-RELEASE</version>
</dependency>
2.添加spring.xml,配置dwr掃描
spring.xml 內(nèi)容:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:dwr="http://www.directwebremoting.org/schema/spring-dwr"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.directwebremoting.org/schema/spring-dwr http://www.directwebremoting.org/schema/spring-dwr-3.0.xsd">
<dwr:annotation-config/>
<dwr:annotation-scan scanRemoteProxy="false" base-package="com.hikvision.lcc.dwr"/>
<dwr:configuration/>
</beans>
springboot 需要加載spring.xml罐寨,在啟動(dòng)類中做如下配置:
@SpringBootApplication
@ImportResource("classpath*:spring/spring.xml")
public class Demo2Application {
public static void main(String[] args) {
SpringApplication.run(Demo2Application.class, args);
}
}
- 之前項(xiàng)目用到的是dwr.xml進(jìn)行配置自沧,在springboot中我們需要用Java代碼進(jìn)行配置,配置類如下:
@Configuration
public class DwrConfig {
/**
* 加入 DWR servlet明刷,相當(dāng)于在xml中配置
* @return
*/
@Bean
public ServletRegistrationBean servletRegistrationBean() {
DwrSpringServlet servlet = new DwrSpringServlet();
ServletRegistrationBean registrationBean = new ServletRegistrationBean(servlet, "/dwr/*");
//設(shè)置成true使DWR能夠debug和進(jìn)入測試頁面婴栽。
registrationBean.addInitParameter("debug", "true");
//pollAndCometEnabled 設(shè)置成true能增加服務(wù)器的加載能力,盡管DWR有保護(hù)服務(wù)器過載的機(jī)制辈末。
registrationBean.addInitParameter("pollAndCometEnabled", "true");
registrationBean.addInitParameter("activeReverseAjaxEnabled", "true");
registrationBean.addInitParameter("maxWaitAfterWrite", "60");
return registrationBean;
}
}
4.基本配置結(jié)束愚争,先寫個(gè)小小的demo一下映皆。新建一個(gè)service類
@Service
@RemoteProxy // spring 的注解,相當(dāng)于暴露服務(wù)
public class DemoDwr {
//TODO 這塊可以注入服務(wù)
@RemoteMethod
public String hello(){
return "hello dada " ;
}
@RemoteMethod
public String echo(String string){
return "hello " + string ;
}
}
接著寫一個(gè)簡單的html來個(gè)階段性測試轰枝。
demo.html
<html>
<head>
<title></title>
<script type='text/javascript' src='/dwr/engine.js'></script>
<script type='text/javascript' src='/dwr/interface/DemoDwr.js'></script>
</head>
hello
<script>
DemoDwr.echo('叫我小司馬', function (str) {
alert(str);
});
</script>
</html>
運(yùn)行項(xiàng)目捅彻,刷新一下頁面就可以感受到自己的勞動(dòng)成果了。
*****************************************我是華麗的分割線******************************************
你以為這就結(jié)束了鞍陨,萬里長征才走了幾米遠(yuǎn).... 接著我們進(jìn)入進(jìn)階測試步淹。
5.接著我簡單演示一下如何從后端推送到前端消息。
先寫一個(gè)DWR工具類DwrScriptSessionManagerUtil诚撵,可以直接拷貝缭裆,一般變化不大。
public class DwrScriptSessionManagerUtil extends DwrServlet {
private static final long serialVersionUID = -7504612622407420071L;
public void init(final String key, final String value) throws ServletException {
Container container = ServerContextFactory.get().getContainer();
ScriptSessionManager manager = container.getBean(ScriptSessionManager.class);
ScriptSessionListener listener = new ScriptSessionListener() {
public void sessionCreated(ScriptSessionEvent ev) {
HttpSession session = WebContextFactory.get().getSession();
//String userId = ((User) session.getAttribute("userinfo")).getHumanid() + "";
System.out.println("a ScriptSession is created!");
ev.getSession().setAttribute(key, value);
}
public void sessionDestroyed(ScriptSessionEvent ev) {
System.out.println("a ScriptSession is distroyed");
}
};
manager.addScriptSessionListener(listener);
}
}
假如你已經(jīng)有一個(gè)加收消息的類DemoConsumer寿烟,如果mq不熟悉的建議先補(bǔ)一補(bǔ)去幼驶,在這我就不細(xì)說了。我的消費(fèi)者代碼大概如下韧衣,牽扯到業(yè)務(wù)會(huì)自行略去盅藻。
@Service
@RemoteProxy
public class Demo2Consumer extends AbstractSpringNotifyConsumer {
//保存scriptSession , 這個(gè)方法需要在頁面剛已加載的時(shí)候調(diào)用畅铭,為了前端和后端建立連接氏淑。
@RemoteMethod
public void onPageLoad(String tag) {
//獲取當(dāng)前的ScriptSession
try {
ScriptSession scriptSession = WebContextFactory.get().getScriptSession();
if(scriptSession != null){
scriptSession.setAttribute("tag", tag);
}
DwrScriptSessionManagerUtil dwrScriptSessionManagerUtil = new DwrScriptSessionManagerUtil() ;
dwrScriptSessionManagerUtil.init("tag",tag);
} catch (Exception e) {
}
System.out.println("onPageLoad 被調(diào)用 :" + tag);
}
// mq接受到消息會(huì)觸發(fā)這個(gè)方法
@Override
public void onMessage(TextNotifyMessage message) throws NotifyException {
System.out.println(" 收到消息 " + message.getData());
System.err.println(" 收到消息 " + message.getData());
// 下面代碼變化不大,主要是給前端推送
Browser.withAllSessionsFiltered(new ScriptSessionFilter() {
public boolean match(ScriptSession session) {
/* 這塊判斷是否合法 硕噩,可以在這塊驗(yàn)證用戶的合法性假残,為了簡單我直接返回true*/
return true;
/* if (session.getAttribute("userId") == null) {
return false;
} else {
return (session.getAttribute("userId")).equals(userId);
}*/
}
}, new Runnable() {
private ScriptBuffer script = new ScriptBuffer();
public void run() {
//設(shè)定前臺(tái)接收消息的方法和參數(shù) 在前臺(tái)js里定義getmessage (data) 的方法,就會(huì)自動(dòng)被調(diào)用
script.appendCall("getmessage", message.getData());
Collection<ScriptSession> sessions = Browser.getTargetSessions();
for (ScriptSession scriptSession : sessions) {
scriptSession.addScript(script);
}
System.out.println("dwrtool showmessage 調(diào)用 ");
}
});
}
}
- 現(xiàn)在再來改改原來的html炉擅,
<html>
<head>
<title></title>
<script type='text/javascript' src='/dwr/engine.js'></script>
<script type='text/javascript' src='/dwr/interface/Demo2Consumer.js'></script>
<script>
function onpage(){
// 頁面加載直接調(diào)用這個(gè)函數(shù)辉懒,我這塊使用點(diǎn)擊按鈕
Demo2Consumer.onPageLoad("123456");
}
// 后端會(huì)調(diào)用這個(gè)函數(shù)
function getmessage(data){
alert(data);
}
</script>
</head>
hello
<input type="button" onclick="onpage()" value="onpage" >
</html>
效果展示:點(diǎn)擊onpage 按鈕后會(huì)一直對(duì)話框彈出,顯示的就是mq接收到的消息谍失。
7.補(bǔ)充眶俩,和前端聊了聊以后,前端給建議不需要調(diào)用onpage記載快鱼,也可以調(diào)用dwr的js函數(shù)颠印,這塊我貼上供大家參考
<script>
// 激活ajax
dwr.engine.setActiveReverseAjax(true)
// 頁面未加載的時(shí)候是否發(fā)送通知
dwr.engine.setNotifyServerOnPageUnload(true,true)
// 出現(xiàn)錯(cuò)誤后的處理方法
dwr.engine.setErrorHandler(function(){})
function getmessage(data){
if (window.eventBus) {
window.eventBus.$emit('getDwr',data);
}
}
</script>