servlet3.0 反向ajax的操作模板
1.servlet
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Queue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.servlet.*;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
*
* @author Administrator
*/
@WebServlet(name = "ChatRoom", urlPatterns = {"/ChatRoom"},asyncSupported=true)
public class ChatRoom extends HttpServlet {
//在并发链接队列中存放异步交互上下文
private static final Queue<AsyncContext> queue=new ConcurrentLinkedQueue<AsyncContext>();
//在阻塞队列中存放消息(链接阻塞队列)
private static final BlockingQueue<String> messageQueue=new LinkedBlockingQueue<String>();
//javascript 发送至iframe中
private static final String BEGIN_SCRIPT_TAG = "<script type='text/javascript'>\n";
private static final String END_SCRIPT_TAG = "</script>\n";
private Thread notifierThread=null;
@Override
public void init(ServletConfig config) throws ServletException {
Runnable notifierRunnable=new Runnable() {
@Override
public void run() {
boolean done = false;
while (!done) {
String cMessage = null;
try {
cMessage = messageQueue.take();
for (AsyncContext ac : queue) {
try {
PrintWriter acWriter = ac.getResponse().getWriter();
acWriter.println(cMessage);
acWriter.flush();
} catch(IOException ex) {
System.out.println(ex);
queue.remove(ac);
}
}
} catch(InterruptedException iex) {
done = true;
System.out.println(iex);
}
}
}
};
notifierThread = new Thread(notifierRunnable);
notifierThread.start();
}
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html");
response.setHeader("Cache-Control", "private");
response.setHeader("Pragma", "no-cache");
final AsyncContext ac = request.startAsync();
ac.setTimeout(10 * 60 * 1000);
ac.addListener(new AsyncListener() {
@Override
public void onComplete(AsyncEvent event) throws IOException {
queue.remove(ac);
}
@Override
public void onTimeout(AsyncEvent event) throws IOException {
queue.remove(ac);
}
@Override
public void onError(AsyncEvent event) throws IOException {
queue.remove(ac);
}
@Override
public void onStartAsync(AsyncEvent event) throws IOException {
}
});
queue.add(ac);
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
try {
response.setContentType("text/html;charset=UTF-8");
response.setHeader("Cache-Control", "private");
request.setCharacterEncoding("UTF-8");
String name=request.getParameter("name");
String script="window.parent.alert('"+name+"')";
String cMessage=BEGIN_SCRIPT_TAG+script +END_SCRIPT_TAG;
messageQueue.put(cMessage);
} catch (InterruptedException ex) {
Logger.getLogger(ChatRoom.class.getName()).log(Level.SEVERE, null, ex);
}
}
@Override
public void destroy() {
queue.clear();
notifierThread.interrupt();
}
}
2.html
<!DOCTYPE html>
<html>
<head>
<title></title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<script type="text/javascript" src="js/jquery-1.7.min.js"></script>
<script type="text/javascript" src="js/application.js"></script>
</head>
<body >
<div id="form">
<label>输入姓名</label>
<input type="text"/>
<input type="button" value="提交"/>
</div>
<iframe id="comet-frame" style="display: none;"></iframe>
</body>
</html>
3.javascript
application.js 使用了jquery1.7
var app={
post:function(){
$.post("ChatRoom", {name:$("#form input[type='text']").val()},"html")
}
}
$(document).ready(function() {
var count=0;
var url = 'ChatRoom'+'?'+count;
$('#comet-frame').attr("src", url)
count++;
$("#form input[type='button']").click(function(){
app.post();
})
});