⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 clusterablesync4jservlet.java

📁 实现了SyncML无线同步协议
💻 JAVA
字号:
/** * Copyright (C) 2003-2004 Funambol * *  This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA  */package sync4j.transport.http.server;import java.io.*;import java.net.InetAddress;import java.net.UnknownHostException;import java.util.logging.Logger;import java.util.logging.Level;import javax.servlet.*;import javax.servlet.http.*;import sync4j.framework.core.*;import sync4j.framework.tools.Base64;import sync4j.framework.server.*;import sync4j.framework.tools.WBXMLTools;import sync4j.framework.transport.http.SyncHolder;import sync4j.framework.protocol.ProtocolException;import org.apache.commons.lang.StringUtils;import sync4j.transport.http.server.Constants;import org.jibx.runtime.*;import org.jibx.runtime.impl.*;/** *  Receives the HTTP request and does session management. * *  <b>Session Management</b> *  <p> *  If the url contains a parameter {PARAM_SESSION_ID}={SESSION_ID}, the session *  id is used to lookup in the <i>handlerCache</i> if there is already a *  <i>SyncHolder</i> associated with it; the found handler is then used to process *  the incoming request. Otherwise, (either if the session parameter is not *  specified or no cached handler is found), a new session id is created and a *  new <i>SyncHolder</i> object is instantiated and stored in the cache.<br> *  The session id is created as followed: *  <p> *  <ol> *    <li> the first four bytes contains the IP address of the remote client *    <li> a dash ('-') is appended *    <li> the creation timestamp is appended *    <li> the resulting string is encoded base 64 *  </ol> *  Note that no session expiration is handled by this class. That is delegated *  to the <i>SyncHandler</i> object. * *  @author Stefano Fornari * *  @version $Id: ClusterableSync4jServlet.java,v 1.6 2004/05/20 16:21:06 luigiafassina Exp $ * */public final class ClusterableSync4jServletextends HttpServletimplements Constants {    // ------------------------------------------------------------ Private data    public static final String PARAM_SERVER_URI = "server-uri";    private static String serverUri = null;        private String jndiAddress = DEFAULT_JNDI_ADDRESS;    private RemoteHolderCache holderCache = null;    private Logger log = Logger.getLogger(LOG_NAME);    // ---------------------------------------------------------- Public methods    public void init() throws ServletException {        String value;        ServletConfig config = getServletConfig();        value = config.getInitParameter(PARAM_CHANNEL_PROPERTIES);        if (StringUtils.isEmpty(value)) {            String msg = "The servlet configuration parameter "                       + PARAM_CHANNEL_PROPERTIES                       + " cannot be empty ("                       + value                       + ")"                       ;            log.severe(msg);            throw new ServletException(msg);        }        value = config.getInitParameter(PARAM_SESSION_TTL);        if (!StringUtils.isEmpty(value)) {            try {                Long.parseLong(value);            } catch (NumberFormatException e) {                String msg = "The servlet configuration parameter "                           + PARAM_SESSION_TTL                           + " is not an integer number ("                           + value                           + ")"                           ;                log.severe(msg);                throw new ServletException(msg);            }        }        value = config.getInitParameter(PARAM_JNDI_ADDRESS);        if (StringUtils.isEmpty(value)) {            String msg = "Missing optional parameter "                       + PARAM_JNDI_ADDRESS                       + ", default value ("                       + jndiAddress                       + ") used."                       ;            log.warning(msg);        } else {            jndiAddress = value;        }        holderCache = new RemoteHolderCache(config);                value = config.getInitParameter(PARAM_SERVER_URI);        if (StringUtils.isEmpty(value)) {            String msg = "The servlet configuration parameter "                       + PARAM_SERVER_URI                       + " cannot be empty ("                       + value                       + ")"                       ;            log(msg);            throw new ServletException(msg);        }        serverUri = value;    }    public void doPost(            final HttpServletRequest request,            final HttpServletResponse response)            throws ServletException, IOException {        final String contentType = request.getContentType().split(";")[0];        final int contentLength  = request.getContentLength();        if (log.isLoggable(Level.FINE)) {            log.fine("contentType: " + contentType);            log.fine("contentLength: " + contentLength);        }        if (contentLength < 1) {            throw new Error("Content length < 1 (" + contentLength + ")");        }        byte[] requestData = new byte[contentLength];        InputStream in = request.getInputStream();        int n = 0;        int bytesRead = 0;        try {            do {                n = in.read(requestData,                            bytesRead,                            requestData.length - bytesRead);                if (n > 0) {                    bytesRead += n;                }            } while (n != -1);        } catch (IOException ex) {            handleError(request, response, "Error reading the request", ex);            return;        } finally {            try {                if (in != null) {                    in.close();                }            } catch (Exception ex) {                handleError(request, response, ex.getClass().getName(), ex);                return;            }            in = null;        }        if (bytesRead != contentLength) {            handleError(request, response, "bytesRead != contentLength", null);            return;        }        //        // If the session id is not specified in the URL, a new remote object        // will be created. Otherwise the session id specifies which remote        // object shall handles the request.        //        RemoteEJBSyncHolder holder = null;        try {            holder = createHolder(request);        } catch (Exception e) {            handleError(request, response, "Error creating SyncBean", e);            return;        }        SyncResponse resp = null;        try {            resp = holder.processMessage(requestData, contentType);        } catch (Exception e) {            Throwable cause = e.getCause();            if (  (cause != null)               && (  (cause instanceof ProtocolException)                  || (cause instanceof Sync4jException  )                  )               ) {                handleError(request, response, "Protocol error", cause);                return;            } else {                throw new ServletException(e);            }        } finally {            //            // Now we can store the handler into the distributed cache. Note            // that when the holder is put in the cache a serialized copy is            // actually stored, not the simple local reference.            //            if (holder.isNew()) {                holderCache.put(holder);            }        }        //        // Set the <RespURI> tag to the server uri plus the session id parameter        //        SyncML responseMessage = resp.getMessage();        responseMessage.getSyncHdr().setRespURI(            serverUri                +            request.getContextPath() +            request.getServletPath() +            '?'                      +            PARAM_SESSION_ID         +            '='                      +            holder.getSessionId()        );        OutputStream out = null;        try {            out = response.getOutputStream();            response.setContentType(resp.getMimeType());            byte[] buf = null;            if (sync4j.framework.core.Constants.MIMETYPE_SYNCML_XML.equals(resp.getMimeType()))            {                if (log.isLoggable(Level.FINE)) {                    log.fine("Sending back XML");                }                                try {                    ByteArrayOutputStream bout = new ByteArrayOutputStream();                    IBindingFactory f = BindingDirectory.getFactory(SyncML.class);                    IMarshallingContext c = f.createMarshallingContext();                    c.setIndent(0);                    c.marshalDocument(responseMessage, "UTF-8", null, bout);                    buf = bout.toByteArray();                } catch(Exception e) {                    e.printStackTrace();                }                                                response.setContentLength(buf.length);                out.write(buf);            } else if (sync4j.framework.core.Constants.MIMETYPE_SYNCML_WBXML.equals(resp.getMimeType())){                if (log.isLoggable(Level.FINE)) {                    log.fine("Sending back WBXML");                }                try {                    buf = WBXMLTools.toWBXML(responseMessage);                } catch (Sync4jException e) {                    handleError(request, response, "Encoding error", e);                }                response.setContentLength(buf.length);                out.write(buf);            }            out.flush();        } finally {            if (log.isLoggable(Level.FINE)) {                log.fine("Finally");            }            if (out != null) out.close();        }        //        // If the message completed the SyncML communication, the holder        // must be closed and discarded.        //        if (resp.isCompleted()) {            releaseHolder(holder);        }    }    public void doGet(            final HttpServletRequest request,            final HttpServletResponse response)            throws ServletException, IOException {        log.info("holderCache: " + holderCache);        super.doGet(request, response);    }    // --------------------------------------------------------- Private methods    /**     * Factory method for <i>SyncHolder</i> objects. If the session id is     * passed as a CGI parameter, it is transformed in a EJB handle. If the     * handle is not valid, it is considered expired. If the session id is not     * specified, a new EJB is created     *     * @param request the associated HTTP request object     *     * @return a new <i>SyncHolder</i>     *     */    private RemoteEJBSyncHolder createHolder(HttpServletRequest request)    throws Exception {        String sessionId = request.getParameter(PARAM_SESSION_ID);        RemoteEJBSyncHolder holder = null;        if (log.isLoggable(Level.FINE)) {            log.fine("holderCache: " + holderCache);        }        if (!StringUtils.isEmpty(sessionId)) {            holder = (RemoteEJBSyncHolder)holderCache.get(sessionId);        }        if (holder == null) {            holder = new RemoteEJBSyncHolder(true);            holder.setSessionId(createSessionId(request));            holder.setJndiAddress(jndiAddress);        }        return holder;    }    /**     * Closes the given <i>SyncHolder</i> and removes it from the cache.     *     * @param holder the holder to releases     */    private void releaseHolder(SyncHolder holder) {        try {            holder.close();        } catch (Exception e) {            log.severe(e.getMessage());            log.throwing(getClass().getName(), "releaseHolder", e.getCause());        }        holderCache.remove(holder.getSessionId());    }    /**     * Handles errors conditions returning an appropriate content to the client.     *     * @param request the request object     * @param response the response object     * @msg   a desctiptive message     * @t     a throwable object     *     */    private void handleError(final HttpServletRequest   request,                             final HttpServletResponse response,                                   String                   msg,                             final Throwable                  t) {        if (msg == null) {            msg = "";        }        if (t == null) {           log.severe(msg);        } else {            log.severe(msg);            log.throwing(getClass().getName(), "handleError", t);        }        try {            response.sendError(response.SC_BAD_REQUEST, msg);        } catch (IOException e) {            log.severe(e.getMessage());            log.throwing(getClass().getName(), "handleError", e);        }    }    /**     * Creates the session id (see the class description for details).     *     * @param request the HTTP request object     *     * @return a newly created session id     */    private String createSessionId(HttpServletRequest request) {        String clientIP  = request.getRemoteAddr()   ;        long   timestamp = System.currentTimeMillis();        StringBuffer sb = new StringBuffer();        byte[] ip = null;        try {            ip = InetAddress.getByName(clientIP).getAddress();        } catch (UnknownHostException e) {            ip = new byte[] {0, 0, 0, 0};        }        sb.append(ip).append('-').append(timestamp);        String stringSessionId = new String(Base64.encode(sb.toString().getBytes()));        //        // strips out tailing '='        //        int i = stringSessionId.lastIndexOf('=');        return ((i>0) ? stringSessionId.substring(0, i-1) : stringSessionId);    }    /**     * The same as <i>handleError(reqest, response, msg, t, null)</i>.     *     * @param request the request object     * @param response the response object     * @msg   a desctiptive message     * @t     a throwable object     *     */    private void handleError(final HttpServletRequest   request,                             final HttpServletResponse response,                             final String                   msg) {        this.handleError(request, response, msg, null);    }}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -