📄 appletservlet.java
字号:
/*------------------------------------------------------------------------------Name: AppletServlet.javaProject: xmlBlaster.orgCopyright: xmlBlaster.org, see xmlBlaster-LICENSE file------------------------------------------------------------------------------*/package org.xmlBlaster.protocol.http.appletproxy;import java.util.logging.LogRecord;import java.util.logging.Logger;import java.util.logging.Level;import org.xmlBlaster.util.Global;import org.xmlBlaster.util.XmlBlasterException;import org.xmlBlaster.util.def.ErrorCode;import org.xmlBlaster.util.MsgUnit;import org.xmlBlaster.util.Timeout;import org.xmlBlaster.util.key.MsgKeyData;import org.xmlBlaster.util.log.I_LogListener;import org.xmlBlaster.util.qos.MsgQosData;import org.xmlBlaster.util.def.Constants;import org.xmlBlaster.util.dispatch.ConnectionStateEnum;import org.xmlBlaster.client.I_XmlBlasterAccess;import org.xmlBlaster.client.protocol.http.common.I_XmlBlasterAccessRaw;import org.xmlBlaster.client.protocol.http.common.MsgHolder;import org.xmlBlaster.client.protocol.http.common.ObjectInputStreamMicro;import org.xmlBlaster.client.protocol.http.common.ObjectOutputStreamMicro;import org.xmlBlaster.client.qos.ConnectQos;import org.xmlBlaster.client.qos.PublishReturnQos;import org.xmlBlaster.client.qos.SubscribeReturnQos;import org.xmlBlaster.client.qos.UnSubscribeReturnQos;import org.xmlBlaster.client.qos.EraseReturnQos;import org.xmlBlaster.client.script.XmlScriptClient;import org.xmlBlaster.client.key.SubscribeKey;import org.xmlBlaster.client.key.UnSubscribeKey;import org.xmlBlaster.client.key.EraseKey;import java.io.ByteArrayOutputStream;import java.io.DataInputStream;import java.io.IOException;import java.io.PrintWriter;import java.util.Enumeration;import java.util.Hashtable;import java.util.Properties;import java.util.Vector;import javax.servlet.ServletConfig;import javax.servlet.ServletException;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import javax.servlet.http.HttpSession;import org.apache.commons.codec.binary.Base64;/** * This servlet supports requests from an applet and sends instant message callbacks to it. * <p> * The servlet doesn't leave the doGet() method after an invocation of actionType "connect" * keeping a permanent http connection. * </p> * <p> * The logging output is redirected to the normal servlet log file. * If you use Apache/Jserv, look into /var/log/httpd/jserv.log, for * tomcat 5.x check jakarta-tomcat/logs/catalina.out * </p> * <p> * The file * </p> * <code> * xmlBlaster/demo/http/WEB-INF/web.xml * </code> * <p> * allows to switch on/off logging and to choose any other xmlBlaster client side configuration * like queue sizes etc. * </p> * @see org.xmlBlaster.client.protocol.http.applet.XmlBlasterAccessRaw * @see http.applet.HelloWorld3 * @author Marcel Ruff xmlBlaster@marcelruff.info */public class AppletServlet extends HttpServlet implements I_LogListener{ private static Logger log = Logger.getLogger(HttpServlet.class.getName()); private static final long serialVersionUID = 1L; private Global initialGlobal; private Timeout timeout; public final static String ENCODING = "UTF-8"; public static long requestCounter; /** * This method is invoked only once when the servlet is started. * @param conf init parameter of the servlet */ public void init(ServletConfig conf) throws ServletException { super.init(conf); // Add the web.xml parameters to our environment settings: Enumeration enumer = conf.getInitParameterNames(); Properties props = new Properties(); while(enumer.hasMoreElements()) { String name = (String)enumer.nextElement(); if (name != null && name.length() > 0) props.setProperty(name, conf.getInitParameter(name)); } this.initialGlobal = new Global(); if (this.initialGlobal.init(props) != 0) System.out.println("AppletServlet: Global initialization problem: " + this.initialGlobal.getErrorText()); // Redirect xmlBlaster logs to servlet log file (see method log() below) // Use xmlBlaster/demo/http/WEB-INF/web.xml to configure logging. // To redirect your Logging output into the servlet logfile (jserv.log), // outcomment this line (the logging.properties need the XbNotifyHandler configured): //org.xmlBlaster.util.log.XbNotifyHandler.instance().register(Level.ALL.intValue(), this); log.info("Initialize ..."); initSystemProperties(conf); // Using JacORB and Suns XML parser as a default ... this.timeout = new Timeout("xmlBlaster.appletPinger"); } protected void connect(String ME, Logger log, HttpSession session, String qos, HttpServletRequest req, HttpServletResponse res) throws XmlBlasterException, IOException, ServletException { if (qos == null || qos.length() < 1) throw new XmlBlasterException(this.initialGlobal, ErrorCode.USER_CONFIGURATION, ME, "Missing connect QoS. Pass xmlBlaster.connectQos='<qos> ... </qos>' with your URL in your POST in a hidden form field or in your cookie."); Global glob = this.initialGlobal.getClone(null); ConnectQos connectQos; boolean warnAuth = false; if (qos.toLowerCase().indexOf("securityservice") >= 0) { connectQos = new ConnectQos(glob, glob.getConnectQosFactory().readObject(qos)); // Applet provides authentication } else { connectQos = new ConnectQos(glob); // User servlets default authentication setting warnAuth = true; } ME += connectQos.getSessionName().getLoginName() + "-" + session.getId(); if (warnAuth) log.warning("Login action, applet has not supplied connect QoS authentication information - we login with the servlets default authentication settings"); else log.info("Login action with applet supplied connect QoS authentication information"); I_XmlBlasterAccess xmlBlasterAccess = glob.getXmlBlasterAccess(); PushHandler pushHandler = new PushHandler(req, res, session.getId(), connectQos.getSessionName().getRelativeName(), xmlBlasterAccess, this.timeout); xmlBlasterAccess.connect(connectQos, pushHandler); pushHandler.startPing(); String key = "PushHandler"+getParameter(req, "appletInstanceCount", "0"); session.setAttribute(key, pushHandler); // Don't fall out of doGet() to keep the HTTP connection open log.info("Waiting forever, permanent HTTP connection from " + req.getRemoteHost() + "/" + req.getRemoteAddr() + ", sessionName=" + connectQos.getSessionName().getRelativeName() + " sessionId=" + session.getId() + "', protocol='" + req.getProtocol() + "', agent='" + req.getHeader("User-Agent") + "', referer='" + req.getHeader("Referer") + "', storing PushHandler with key '" + key + "'."); if (log.isLoggable(Level.FINE)) log.fine("user='" + req.getRemoteUser() + "', serverPort='" + req.getServerPort() + "', query='" + req.getQueryString() + "', pathInfo='" + req.getPathInfo() + "', pathTranslated='" + req.getPathTranslated() + "', servletPath='" + req.getServletPath() + "', documentRoot='" + getServletConfig().getServletContext().getRealPath("/") + "', accept='" + req.getHeader("Accept") + "', referer='" + req.getHeader("Referer") + "', authorization='" + req.getHeader("Authorization") + "'."); pushHandler.ping("loginSucceeded"); while (!pushHandler.isClosed()) { try { Thread.sleep(10000L); } catch (InterruptedException i) { log.severe("Error in Thread handling, don't know what to do: "+i.toString()); pushHandler.cleanup(); break; } } pushHandler = null; log.info("Persistent HTTP connection lost, leaving doGet() ...."); } /** * GET request from the browser, usually to do an initial login. * <p /> * Used for login and for keeping a permanent http connection. * <br /> * The sessionId from the login is delivered back to the browser, * and will be used for all following calls to this and other servlets. * <br /> * It is important that this login servlet generates the sessionId * and no other servlet generates one - so call other servlets *after* * successful login. * <p /> */ public void doGetFake(String ME, HttpServletRequest req, HttpServletResponse res, String actionType, MsgHolder msgHolder) throws ServletException, IOException { res.setContentType("text/plain"); if (log.isLoggable(Level.FINER)) log.finer("Entering doGet() ... " + Global.getMemoryStatistic()); if (actionType.equalsIgnoreCase("NONE")) { String str = "Please call servlet with some ActionType"; log.severe(str); XmlBlasterException x = new XmlBlasterException(this.initialGlobal, ErrorCode.USER_CONFIGURATION, ME, str); writeResponse(res, I_XmlBlasterAccessRaw.EXCEPTION_NAME, x.getMessage()); return; } // for logging only: HttpSession oldSession = req.getSession(false); String oldSessionId = (oldSession == null) ? "no-session-id" : oldSession.getId(); HttpSession session = req.getSession(true); if (actionType.equals(I_XmlBlasterAccessRaw.CREATE_SESSIONID_NAME) || // Initial dummy request to create a http-sessionId and bounce it back to the applet/browser actionType.equals(I_XmlBlasterAccessRaw.CONNECT_NAME)) { // "connect" TODO: !!! Reconnect to old session boolean invalidate = getParameter(req, "xmlBlaster/invalidate", false); if (invalidate == true) { log.info("Entering servlet doGet("+I_XmlBlasterAccessRaw.CONNECT_NAME+"), forcing a new sessionId"); session.invalidate(); // force a new sessionId } session = req.getSession(true); } String sessionId = session.getId(); ME += "-" + sessionId; if (log.isLoggable(Level.FINE)) log.fine("Entering servlet doGet(oldSessionId="+oldSessionId+") ..."); if (false) { // HttpServletResponse.addCookie(javax.servlet.http.Cookie) javax.servlet.http.Cookie[] cookies = req.getCookies(); if (cookies != null) { for (int i=0; i<cookies.length; i++) { log.info("Receiving cookie name=" + cookies[i].getName() + ", domain=" + cookies[i].getDomain() + ", path=" + cookies[i].getPath()); } } } if (sessionId == null) { String str = "Sorry, your sessionId is invalid"; //XmlBlasterException x = new XmlBlasterException(this.initialGlobal, ErrorCode.USER_CONFIGURATION, ME, str); writeResponse(res, I_XmlBlasterAccessRaw.EXCEPTION_NAME, str); return; } try { if (actionType.equals(I_XmlBlasterAccessRaw.CONNECT_NAME)) { // Here we NEVER return to hold the persistent http connection for callbacks to the applet String qos = getParameter(req, "xmlBlaster.connectQos", (String)null); // if the binary protocol is used ... if (msgHolder != null) qos = msgHolder.getQos(); connect(ME, log, session, qos, req, res); } else if (actionType.equals(I_XmlBlasterAccessRaw.CREATE_SESSIONID_NAME)) { //------------------ first request from applet -------------------------- if (log.isLoggable(Level.FINE)) log.fine("doGet: dummyToCreateASessionId"); writeResponse(res, I_XmlBlasterAccessRaw.CREATE_SESSIONID_NAME, "OK-"+System.currentTimeMillis()); return; } else if (actionType.equals(I_XmlBlasterAccessRaw.PONG_NAME)){ //------------------ answer of a ping ----------------------------------------------- // The PushHandler adds 'ping' which // pings the applet to hold the http connection.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -