From: kkolinko Date: Sat, 17 Apr 2010 01:59:56 +0000 (+0000) Subject: Improve the ChatServlet comet example. X-Git-Url: https://git.internetallee.de/?a=commitdiff_plain;h=a4be94db7ed30f8c88ec659af75440252dba27bd;p=tomcat7.0 Improve the ChatServlet comet example. 1. Fix possible deadlock in ChatServlet$MessageSender, similar to BZ 48843. 2. Properly wake up ChatServlet$MessageSender when the servlet is destroyed. 3. Filter special characters when printing the message in ChatServlet. 4. Provide an explicit charset everywhere. 5. Fix frames layout. Fix redirections. Use target="" attribute in HTML to send request to a particular frame. 6. Fix DTDs. Use frameset DTD for the page containing frames. 7. Add "xxx joined the chat" message at startup. 8. Rename chat.jsp -> index.jsp, so that the entry point to this example is more visible. 9. Corrected the link that opens a new chat window. It referenced an undefined JavaScript function. Now it is implemented just by using target="_blank". 10. Added submit button to the form pages. 11. Minor message tweaks. git-svn-id: https://svn.apache.org/repos/asf/tomcat/trunk@935105 13f79535-47bb-0310-9956-ffa450edef68 --- diff --git a/webapps/examples/WEB-INF/classes/chat/ChatServlet.java b/webapps/examples/WEB-INF/classes/chat/ChatServlet.java index 1b8a61968..a60135d38 100644 --- a/webapps/examples/WEB-INF/classes/chat/ChatServlet.java +++ b/webapps/examples/WEB-INF/classes/chat/ChatServlet.java @@ -41,6 +41,8 @@ public class ChatServlet private static final long serialVersionUID = 1L; + private static final String CHARSET = "UTF-8"; + protected ArrayList connections = new ArrayList(); protected MessageSender messageSender = null; @@ -82,7 +84,7 @@ public class ChatServlet if ("login".equals(action)) { String nickname = request.getParameter("nickname"); request.getSession(true).setAttribute("nickname", nickname); - response.sendRedirect("post.jsp"); + response.sendRedirect("index.jsp"); event.close(); return; } @@ -114,15 +116,20 @@ public class ChatServlet HttpServletRequest request, HttpServletResponse response) throws IOException { log("Begin for session: " + request.getSession(true).getId()); - + + response.setContentType("text/html; charset=" + CHARSET); + PrintWriter writer = response.getWriter(); - writer.println(""); + writer.println(""); writer.println("JSP Chat"); + writer.println("
Welcome to the chat. Click here to reload this window
"); writer.flush(); synchronized(connections) { connections.add(response); } + + messageSender.send("Tomcat", request.getSession(true).getAttribute("nickname") + " joined the chat."); } protected void end(CometEvent event, HttpServletRequest request, HttpServletResponse response) @@ -136,7 +143,6 @@ public class ChatServlet writer.println(""); event.close(); - } protected void error(CometEvent event, HttpServletRequest request, HttpServletResponse response) @@ -170,10 +176,12 @@ public class ChatServlet protected void service(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { // Compatibility method: equivalent method using the regular connection model + response.setContentType("text/html; charset=" + CHARSET); PrintWriter writer = response.getWriter(); - writer.println(""); + writer.println(""); writer.println("JSP Chat"); - writer.println("Chat example only supports Comet processing"); + writer.println("Chat example only supports Comet processing. "); + writer.println("Configure a connector that supports Comet and try again."); writer.println(""); } @@ -192,6 +200,9 @@ public class ChatServlet public void stop() { running = false; + synchronized (messages) { + messages.notify(); + } } public void send(String user, String message) { @@ -209,34 +220,29 @@ public class ChatServlet // Loop until we receive a shutdown command while (running) { - // Loop if endpoint is paused - - if (messages.size() == 0) { + String[] pendingMessages; + synchronized (messages) { try { - synchronized (messages) { + if (messages.size() == 0) { messages.wait(); } } catch (InterruptedException e) { // Ignore } + pendingMessages = messages.toArray(new String[0]); + messages.clear(); } synchronized (connections) { - String[] pendingMessages = null; - synchronized (messages) { - pendingMessages = messages.toArray(new String[0]); - messages.clear(); - } for (int i = 0; i < connections.size(); i++) { try { PrintWriter writer = connections.get(i).getWriter(); for (int j = 0; j < pendingMessages.length; j++) { - // FIXME: Add HTML filtering - writer.println(pendingMessages[j] + "
"); + writer.println("
"+filter(pendingMessages[j]) + "
"); } writer.flush(); } catch (IOException e) { - log("IOExeption sending message", e); + log("IOException sending message", e); } } } @@ -247,7 +253,38 @@ public class ChatServlet } + /** + * Filter the specified message string for characters that are sensitive + * in HTML. + * + * @param message The message string to be filtered + * @author Copied from org.apache.catalina.util.RequestUtil#filter(String) + */ + protected static String filter(String message) { + if (message == null) + return (null); - - + char content[] = new char[message.length()]; + message.getChars(0, message.length(), content, 0); + StringBuilder result = new StringBuilder(content.length + 50); + for (int i = 0; i < content.length; i++) { + switch (content[i]) { + case '<': + result.append("<"); + break; + case '>': + result.append(">"); + break; + case '&': + result.append("&"); + break; + case '"': + result.append("""); + break; + default: + result.append(content[i]); + } + } + return (result.toString()); + } } diff --git a/webapps/examples/jsp/chat/chat.jsp b/webapps/examples/jsp/chat/chat.jsp deleted file mode 100644 index 12f9a6794..000000000 --- a/webapps/examples/jsp/chat/chat.jsp +++ /dev/null @@ -1,32 +0,0 @@ - - - - - JSP Chat - - - - - - - - - - - - diff --git a/webapps/examples/jsp/chat/index.jsp b/webapps/examples/jsp/chat/index.jsp new file mode 100644 index 000000000..e0b37298a --- /dev/null +++ b/webapps/examples/jsp/chat/index.jsp @@ -0,0 +1,32 @@ +<%@page contentType="text/html; charset=UTF-8" %> +<% if (session.getAttribute("nickname") == null) { + response.sendRedirect("login.jsp"); + return; +} +%> + + + + + JSP Chat + + + + + + diff --git a/webapps/examples/jsp/chat/login.jsp b/webapps/examples/jsp/chat/login.jsp index 298a2faa1..551ca3426 100644 --- a/webapps/examples/jsp/chat/login.jsp +++ b/webapps/examples/jsp/chat/login.jsp @@ -1,4 +1,5 @@ - + +<%@page contentType="text/html; charset=UTF-8" %>