反向Ajax
正向Ajax由页面发出一个Ajax请求给控制器处理。
反向Ajax与正向Ajax的区别在于推送功能,即可以由控制器主动发起,推送消息到客户端。
反向Ajax实现推送功能
1.为Servlet添加为支持反向Ajax
@WebServlet(urlPatterns = "/message",asyncSupported = true)
2.反向Ajax的处理在于线程,由于用户的所有请求都有doGet()或者doPost()来处理,如果想要线程现成的操作,就必须将每一个用户封装为一个独立的线程类,随后启动该线程以实现推送功能。
实现子线程的控制需要javax.servlet.AsyncContext
类的支持,该类有如下主要方法。
No | 返回值 | 方法 | 描述 |
---|---|---|---|
1 | ServletRequest | getRequest() | 取得当前的request对象 |
2 | ServletResponse | getResponse() | 取得当前的response对象(每一个线程可以单独回应) |
3 | void | complete() | 当前的线程对于本次的轮询操作完成 |
package com.ajax.servlet;
import javax.servlet.AsyncContext;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@SuppressWarnings("serial")
@WebServlet(urlPatterns = "/message",asyncSupported = true)
public class MessageServlet extends HttpServlet {
@Override
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.setCharacterEncoding("UTF-8");
response.setCharacterEncoding("UTF-8");
response.setContentType("text/html");
AsyncContext asc = request.startAsync();//准备启动一个反向Ajax线程对象
asc.start(new MessageThread(asc));//启动新线程
}
@Override
public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doGet(request, response);
}
class MessageThread implements Runnable{
private AsyncContext asc;
public MessageThread(AsyncContext asc){
this.asc = asc;
}
@Override
public void run() {
String msg = this.asc.getRequest().getParameter("msg");
try{
this.asc.getResponse().getWriter().print("ECHO:"+msg);
this.asc.complete();//告诉客户端,本次的输出完成了
}catch(Exception e){
e.printStackTrace();
}
}
}
}
3.在页面使用Ajax轮询处理
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ page pageEncoding="UTF-8" %>
<%
String basePath = request.getScheme()+"://"+request.getServerName()
+":"+request.getServerPort()+request.getContextPath();
String messagePath = basePath+"/message";
%>
<html>
<head>
<title>反向Ajax</title>
</head>
<body>
<div id="div1">
<label>信息:</label>
<input type="text" id="msg" name="msg" />
<input type="button" id="sendBut" value="发送" />
<div id="div2">
<label>返回内容......</label><br>
</div>
<script type="text/javascript">
var xmlHttpRequest;//表示Ajax的主要处理对象
function create(){//函数功能为创建XMLHttpRequest对象
if(window.XMLHttpRequest){//当前浏览器不是IE
xmlHttpRequest = new XMLHttpRequest();//直接创建对象
}else{//如果是IE浏览器,则需要通过ActiveX进行对象创建
xmlHttpRequest = new ActiveXObject("Microsoft.XMLHttp");
}
}
window.onload = function(){
document.getElementById("sendBut").addEventListener("click",function(){
var msg = document.getElementById("msg").value;
alert(msg);
sendMessage(msg);
},false);
};
function sendMessage(msg){
if(msg!=""){
create();
xmlHttpRequest.open("post","<%=messagePath%>?msg="+msg);
xmlHttpRequest.send(null);
xmlHttpRequest.onreadystatechange = function(){
if(xmlHttpRequest.readyState==4&&xmlHttpRequest.status==200){
var retMsg = xmlHttpRequest.responseText;
var pEle = document.createElement("p");
pEle.appendChild(document.createTextNode(retMsg));
document.getElementById("div2").appendChild(pEle);
window.setTimeout(function(){
sendMessage("来自大名狗的警告------");
},2000);
}
}
}
}
</script>
</div>
</body>
</html>
运行程序发送信息,发现推送成功。