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

📄 basetunnelservlet.java

📁 大量java源程序
💻 JAVA
字号:
/*
 * @(#)BaseTunnelServlet
 *
 * Copyright (c) 1998 Karl Moss. All Rights Reserved.
 *
 * You may study, use, modify, and distribute this software for any
 * purpose provided that this copyright notice appears in all copies.
 *
 * This software is provided WITHOUT WARRANTY either expressed or
 * implied.
 *
 * @author  Karl Moss
 * @version 1.0
 * @date    17Apr98
 *
 */

package javaservlets.tunnel.server;

import javax.servlet.*;
import javax.servlet.http.*;
import java.io.*;

/**
 * <p>This is the base server object used for HTTP tunneling.
 */

public abstract class BaseTunnelServlet extends HttpServlet
{
  // Constant key value for getting/setting the server object
  // table into the session object
  static final String OBJECT_TABLE = "ObjectTable";

  /**
    * <p>Services the HTTP request
    *
    * @param req The request from the client
    * @param resp The response from the servlet
    */

  public void service(HttpServletRequest req,
                      HttpServletResponse resp)
    throws ServletException, java.io.IOException
    {
      // Get the input stream for reading data from the client
      DataInput in = _getInputStream(req.getInputStream());

      // Get the session object or create one if it does not
      // exist. A session will persist as long as the client
      // browser maintains a connection to the server.
      HttpSession session = req.getSession(true);

      // Get the server object table bound to the session. This may
      // be null if this is the first request. If so create a
      // new object table for the session
      java.util.Hashtable objectTable =
        (java.util.Hashtable) session.getAttribute(OBJECT_TABLE);

//      java.util.Hashtable objectTable =
//        (java.util.Hashtable) session.getValue(OBJECT_TABLE);

      if (objectTable == null) {
        objectTable = new java.util.Hashtable();

        // Add the server object to the HTTP session
   session.setAttribute(OBJECT_TABLE, objectTable);
//        session.putValue(OBJECT_TABLE, objectTable);
      }

      // We'll be sending binary data back to the client so
      // set the content type appropriately
      resp.setContentType("application/octet-stream");

      // Data will always be written to a byte array buffer so
      // that we can tell the client the length of the data
      ByteArrayOutputStream byteOut = new ByteArrayOutputStream();

      // Create the output stream to be used to write the
      // data to our buffer
      DataOutput out = _getOutputStream(byteOut);

      // Read the method ordinal from the input stream. All
      // request headers contain a method ordinal
      int ordinal = in.readInt();

      // The server object
      Object serverObject;

      // The object handle
      int objectHandle;

      // Evaluate the ordinal. -1 is reserved for initializing
      // the server
      switch (ordinal) {
      case -1:

        // Create a new instance of the server object
        serverObject = _getNewInstance();

        // Send the response back to the client indicating
        // that the server object is ready for method
        // calls.
        out.writeInt(ordinal);

        // Get the object handle
        objectHandle = serverObject.hashCode();

        // Put the object in the object table for the session
        objectTable.put(new Integer(objectHandle), serverObject);

        // Part of the initial object response is the object
        // handle
        out.writeInt(objectHandle);
        break;

      default:

        // Read the object handle from the request header
        objectHandle = in.readInt();

        // Attempt to find the object in the object table for
        // the session
        serverObject = objectTable.get(new Integer(objectHandle));

        // We have to have a server object in order to invoke
        if (serverObject == null) {
          throwException(out, "Invalid server object");
        }
        else {

          try {

            // The response needs to always include the ordinal
            // that was invoked.
            out.writeInt(ordinal);
            _flush(out);

            // Invoke the method for the given ordinal
            _invokeMethod(serverObject, ordinal, in, out);
          }
          catch (Exception ex) {

            // Any exceptions thrown by invoking the server
            // method should be sent back to the client. Make
            // sure we are working with a 'pure' output stream
            // that does not contain any other data
            byteOut = new ByteArrayOutputStream();
            out = _getOutputStream(byteOut);
            throwException(out, ex.getMessage());
          }

        }
      }

      // Flush the contents of the output stream to the
      // byte array
      _flush(out);

      // Get the buffer that is holding our response
      byte[] buf = byteOut.toByteArray();

      // Notify the client how much data is being sent
      resp.setContentLength(buf.length);

      // Send the buffer to the client
      ServletOutputStream servletOut = resp.getOutputStream();

      // Wrap up
      servletOut.write(buf);
      servletOut.close();
    }

  /**
    * <p>Initialize the servlet. This is called once when the
    * servlet is loaded. It is guaranteed to complete before any
    * requests are made to the servlet
    *
    * @param cfg Servlet configuration information
    */

  public void init(ServletConfig cfg)
    throws ServletException
    {
      super.init(cfg);
    }

  /**
    * <p>Destroy the servlet. This is called once when the servlet
    * is unloaded.
    */

  public void destroy()
    {
      super.destroy();
    }

  /**
    * <p>Sends a packet to the client that will cause
    * an exception to be thrown
    *
    * @param out Output stream
    * @param message Exception message
    */
  public void throwException(DataOutput out, String message)
    throws IOException
    {
      // -2 is reserved for exceptions
      out.writeInt(-2);
      out.writeUTF(message);
    }

  /**
    * <p>Creates a new instance of the server object. This
    * method must be implemented by the server.
    *
    * @return Instance of the server object
    */
  public abstract Object _getNewInstance()
    throws ServletException;

  /**
    * <p>Invokes the method for the ordinal given. If the method
    * throws an exception it will be sent to the client. This
    * method must be implemented by the server.
    *
    * @param Object Server object
    * @param ordinal Method ordinal
    * @param in Input stream to read additional parameters
    * @param out Output stream to write return values
    */
  public abstract void _invokeMethod(Object serverObject, int ordinal,
                                     DataInput in, DataOutput out)
    throws Exception;

  /**
    * <p>Creates an input stream to be used to read data
    * sent from the client. This method must be implemented
    * by the server
    *
    * @param servletInput Servlet input stream from the servlet
    * request header
    * @return Input stream to read data from the client
    */
  public abstract DataInput _getInputStream(
        ServletInputStream servletInput)
    throws IOException;

  /**
    * <p>Closes the input stream. The default implementation does
    * nothing.
    *
    * @param in Input stream to close
    */
  public void _close(DataInput in) throws IOException
    {
    }

  /**
    * <p>Gets an output stream to be used for writing data to
    * an internal buffer. The buffer will be written to the
    * client. This method must be implemented by the server.
    *
    * @param buffer Buffer to hold the output data
    * @return Output stream to write data to the buffer
    */
  public abstract DataOutput _getOutputStream(
        ByteArrayOutputStream buffer)
    throws IOException;

  /**
    * <p>Flushes the any buffered data to the output stream. The
    * default implementation does nothing.
    *
    * @param out Output stream to flush
    */
  public void _flush(DataOutput out) throws IOException
    {
    }

}

⌨️ 快捷键说明

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