home *** CD-ROM | disk | FTP | other *** search
/ Total Network Tools 2002 / NextStepPublishing-TotalNetworkTools2002-Win95.iso / Archive / Web Server / Sambar Server.exe / _SETUP.1 / javaeng.jar / javax / servlet / http / HttpServlet.java < prev    next >
Encoding:
Java Source  |  2000-04-03  |  17.0 KB  |  538 lines

  1. /*
  2.  * HttpServlet.java -- Abstract base class for all http servlets
  3.  *
  4.  * Copyright (c) 1998, 1999 by Free Software Foundation, Inc.
  5.  * Written by Paul Siegmann (pauls@euronet.nl)
  6.  *
  7.  * This program is free software; you can redistribute it and/or modify
  8.  * it under the terms of the GNU Library General Public License as published
  9.  * by the Free Software Foundation, version 2. (see COPYING.LIB)
  10.  *
  11.  * This program is distributed in the hope that it will be useful, but
  12.  * WITHOUT ANY WARRANTY; without even the implied warranty of
  13.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14.  * GNU General Public License for more details.
  15.  *
  16.  * You should have received a copy of the GNU General Public License
  17.  * along with this program; if not, write to the Free Software Foundation
  18.  * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307 USA
  19.  */
  20. package javax.servlet.http;
  21.  
  22. import java.io.IOException;
  23. import java.io.PrintWriter;
  24. import java.io.Serializable;
  25. import java.lang.reflect.Method;
  26. import java.util.Enumeration;
  27.  
  28. import javax.servlet.GenericServlet;
  29. import javax.servlet.ServletException;
  30. import javax.servlet.ServletOutputStream;
  31. import javax.servlet.ServletRequest;
  32. import javax.servlet.ServletResponse;
  33.  
  34. /**
  35.  * The mother-of-all-HttpServlets.
  36.  * Every normal http servlet extends this class and overrides either the doGet
  37.  * or doPost methods (or both).
  38.  * The server calls service. Service in its turn calls doGet, doPost, whatever,
  39.  * depending on the client's request.
  40.  *
  41. #ifdef SERVLET_2_0
  42.  * @version Servlet API 2.0 
  43. #endif
  44. #ifdef SERVLET_2_1
  45.  * @version Servlet API 2.1
  46. #endif
  47. #ifdef SERVLET_2_2
  48.  * @version Servlet API 2.2
  49. #endif
  50.  * @since Servlet API 1.0
  51.  * @author Paul Siegmann (pauls@euronet.nl)
  52.  */
  53. public abstract class HttpServlet
  54.     extends GenericServlet
  55.     implements Serializable 
  56. {
  57.     private String optionString = null;
  58.  
  59.     /**
  60.      * Does nothing
  61.      *
  62.      * @since Servlet API 1.0
  63.      */
  64.     public HttpServlet() {
  65.     }
  66.  
  67.  
  68.     /**
  69.      * This method is called on a "DELETE" request.
  70.      * The default implementation is that 
  71.      * HttpServletResponse.SC_BAD_REQUEST (error nr: 400)
  72.      * and the message "Method \"DELETE\" is not supported by this servlet"
  73.      * is returned to the client.
  74.      *
  75.      * @since Servlet API 2.0
  76.      *
  77.      * @exception ServletException if an Servlet Exception occurs
  78.      * @exception IOException if an IOException occurs
  79.      */
  80.     protected void doDelete(HttpServletRequest request,
  81.                 HttpServletResponse response) throws ServletException, IOException {
  82.         response.sendError(HttpServletResponse.SC_BAD_REQUEST,"Method \"DELETE\" is not supported by this servlet");
  83.     }
  84.  
  85.  
  86.     /**
  87.      * This method is called on a "GET" request.
  88.      * The default implementation is that 
  89.      * HttpServletResponse.SC_BAD_REQUEST (error nr: 400)
  90.      * and the message "Method \"GET\" is not supported by this servlet"
  91.      * is returned to the client.
  92.      *
  93.      * @since Servlet API 1.0
  94.      *
  95.      * @exception ServletException if an Servlet Exception occurs
  96.      * @exception IOException if an IOException occurs
  97.      */
  98.     protected void doGet(HttpServletRequest request,
  99.                 HttpServletResponse response) throws ServletException, IOException {
  100.         response.sendError(HttpServletResponse.SC_BAD_REQUEST,"Method \"GET\" is not supported by this servlet");
  101.     }
  102.  
  103.  
  104.     /**
  105.      * This method is called on a "HEAD" request.
  106.      * This method calls the doGet method with the request parameter,
  107.      * but the response object is replaced by a HttpServletResponse that
  108.      * is identical to the reponse, but it has a "dummy" OutputStream.<BR>
  109.      * The doGet method should perform a check like the following:<BR>
  110.      * <CODE>if(request.getMethod().equals("HEAD")) { ... }</CODE><BR>
  111.      * if it wants to know whether it was called from doHead.
  112.      *
  113.      * @since Servlet API 2.0
  114.      *
  115.      * @exception ServletException if an Servlet Exception occurs
  116.      * @exception IOException if an IOException occurs
  117.      */
  118.     private void doHead(HttpServletRequest request,
  119.                 HttpServletResponse response) throws ServletException, IOException {
  120.         doGet(request, new DoHeadHttpServletResponse(response));
  121.     }
  122.  
  123.  
  124.     /**
  125.      * This method is called on a "OPTIONS" request.
  126.      * It tells the client which methods are supported by the servlet.<BR>
  127.      * This comes down to an implementation where HEAD, TRACE and OPTIONS
  128.      * are supported by default because this class contains default
  129.      * implementations of them. GET, POST, DELETE and PUT are added
  130.      * to this list if the subclass has its own implementation of
  131.      * the doGet, doPost, doDelete or doPut method respectively.
  132.      * Note:<BR>
  133.      * This implementation is probably not the most efficient one,
  134.      * but the whole OPTIONS thing is intended for debugging
  135.      * purposes, and this implementation does the job.
  136.      *
  137.      * @since Servlet API 2.0
  138.      *
  139.      * @exception ServletException if an Servlet Exception occurs
  140.      * @exception IOException if an IOException occurs
  141.      */
  142.     protected void doOptions(HttpServletRequest request,
  143.                     HttpServletResponse response) throws ServletException, IOException {
  144.         if(optionString == null) {
  145.             try {
  146.                 Method[] methodList = this.getClass().getMethods();
  147.                 String basisClassName = "javax.servlet.http.HttpServlet";
  148.                 StringBuffer result = new StringBuffer("");
  149.                 for(int i = 0; i < methodList.length; i++) {
  150.                     if("doGet".equals(methodList[i].getName())
  151.                      &&(! basisClassName.equals(methodList[i].getDeclaringClass().getName()))) {
  152.                             result.append("GET, ");
  153.                     } else if("doDelete".equals(methodList[i].getName())
  154.                         &&(! basisClassName.equals(methodList[i].getDeclaringClass().getName()))) {
  155.                             result.append("DELETE, ");
  156.                     } else if("doPut".equals(methodList[i].getName())
  157.                         &&(! basisClassName.equals(methodList[i].getDeclaringClass().getName()))) {
  158.                             result.append("PUT, ");
  159.                     } else if("doPost".equals(methodList[i].getName())
  160.                         &&(! basisClassName.equals(methodList[i].getDeclaringClass().getName()))) {
  161.                             result.append("POST, ");
  162.                     }
  163.                 }
  164.                 result.append("HEAD, TRACE, OPTIONS");
  165.                 optionString = result.toString();
  166.             } catch (SecurityException e) {
  167.                  response.sendError(HttpServletResponse.SC_BAD_REQUEST,"Method \"OPTIONS\" is not supported by this servlet");
  168.             }
  169.         }
  170.         response.setHeader("Allow",optionString);
  171.     }
  172.  
  173.  
  174.     /**
  175.      * This method is called on a "POST" request.
  176.      * The default implementation is that 
  177.      * HttpServletResponse.SC_BAD_REQUEST (error nr: 400)
  178.      * and the message "Method \"POST\" is not supported by this servlet"
  179.      * is returned to the client.
  180.      *
  181.      * @since Servlet API 1.0
  182.      *
  183.      * @exception ServletException if an Servlet Exception occurs
  184.      * @exception IOException if an IOException occurs
  185.      */
  186.     protected void doPost(HttpServletRequest request,
  187.                 HttpServletResponse response) throws ServletException, IOException {
  188.         response.sendError(HttpServletResponse.SC_BAD_REQUEST,"Method \"POST\" is not supported by this servlet");
  189.     }
  190.  
  191.  
  192.     /**
  193.      * This method is called on a "PUT" request.
  194.      * The default implementation is that 
  195.      * HttpServletResponse.SC_BAD_REQUEST (error nr: 400)
  196.      * and the message "Method \"PUT\" is not supported by this servlet"
  197.      * is returned to the client.
  198.      *
  199.      * @since Servlet API 2.0
  200.      *
  201.      * @exception ServletException if an Servlet Exception occurs
  202.      * @exception IOException if an IOException occurs
  203.      */
  204.     protected void doPut(HttpServletRequest request,
  205.                 HttpServletResponse response) throws ServletException, IOException {
  206.         response.sendError(HttpServletResponse.SC_BAD_REQUEST,"Method \"PUT\" is not supported by this servlet");
  207.     }
  208.  
  209.  
  210.     /**
  211.      * This method is called on a "TRACE" request.
  212.      * This method is for debugging purposes.<BR>
  213.      * When a client makes a TRACE request the following is returned:<BR>
  214.      * content type = "message/http"<BR>
  215.      * message size: <size of the complete message><BR>
  216.      * first line of the message : TRACE <requested uri>
  217.      * <protocol><BR>
  218.      * on the following lines all the request header names and values
  219.      *
  220.      * @since Servlet API 2.0
  221.      *
  222.      * @exception ServletException if an Servlet Exception occurs
  223.      * @exception IOException if an IOException occurs
  224.      */
  225.     protected void doTrace(HttpServletRequest request,
  226.                 HttpServletResponse response) throws ServletException, IOException {
  227.         StringBuffer result = new StringBuffer("\r\n");
  228.  
  229.         result.append("TRACE " + request.getRequestURI() + " " + request.getProtocol() + "\r\n");
  230.         String headerName;
  231.           for(Enumeration e = request.getHeaderNames(); e.hasMoreElements();) {
  232.             headerName = (String)e.nextElement();
  233.             result.append(headerName + ": " + request.getHeader(headerName) + "\r\n");
  234.         }
  235.  
  236.         response.setContentType("message/http");
  237.         response.setContentLength(result.length());
  238.         PrintWriter out = response.getWriter();
  239.         out.print(result.toString());
  240.         out.close();
  241.     }
  242.  
  243.  
  244.     /**
  245.      * Returns the time the requested uri was last modified in seconds since
  246.      * 1 january 1970. Default implementation returns -1.
  247.      *
  248.      * @since Servlet API 1.0
  249.      */
  250.     protected long getLastModified(HttpServletRequest request) {
  251.         return -1;
  252.     }
  253.  
  254.  
  255.     /**
  256.      * This method looks whether the request is a POST, GET, etc method,
  257.      * and then calls the appropriate doPost, doGet, whatever method.<BR>
  258.      * If the request method is something it can't handle it sends
  259.      * a HttpServletResponse.SC_BAD_REQUEST error through the response.
  260.      *
  261.      * @since Servlet API 1.0
  262.      *
  263.      * @exception ServletException an error has occured
  264.      * @exception IOException an error has occured
  265.      */
  266.     protected void service(HttpServletRequest request,
  267.                 HttpServletResponse response) throws ServletException, IOException {
  268.         if(request.getMethod().equals("GET") ) {
  269.             if(testConditional(request,response)) {
  270.                 doGet(request,response);
  271.             }
  272.         } else if (request.getMethod().equals("HEAD") ) {
  273.             if(testConditional(request,response)) {
  274.                 doHead(request,response);
  275.             }
  276.         } else if (request.getMethod().equals("POST") ) {
  277.             doPost(request,response);
  278.         } else if (request.getMethod().equals("DELETE") ) {
  279.             doDelete(request,response);
  280.         } else if (request.getMethod().equals("OPTIONS") ) {
  281.             doOptions(request,response);
  282.         } else if (request.getMethod().equals("PUT") ) {
  283.             doPut(request,response);
  284.         } else if (request.getMethod().equals("TRACE") ) {
  285.             doTrace(request,response);
  286.         } else {
  287.             response.sendError(HttpServletResponse.SC_BAD_REQUEST, "Method \"" + request.getMethod() + "\" is not supported by this servlet");
  288.         }
  289.     }
  290.  
  291.  
  292.     /**
  293.      * Frontend for calling service(HttpServletRequest,HttpServletResponse).
  294.      * <P>
  295.      * This method tries to typecast the ServletRequest and the
  296.      * ServletResponse to HttpServletRequest and HttpServletResponse
  297.      * and then call service(HttpServletRequest,HttpServletResponse).<BR>
  298.      *
  299.      * @since Servlet API 1.0
  300.      *
  301.      * @param request The client's request
  302.      * @param response The class to write the response date to.
  303.      * @exception ServletException an error has occured
  304.      * @exception IOException an error has occured
  305.      */
  306.     public void service(ServletRequest request,
  307.                 ServletResponse response) throws ServletException, IOException {
  308.         try {
  309.              service((HttpServletRequest)request,(HttpServletResponse)response);
  310.         } catch (ClassCastException e) {
  311.             throw new ServletException("This servlet only excepts http requests");
  312.         }
  313.     }
  314.  
  315.  
  316.     /**
  317.      * Check for possible "If-Modified-Since" header parameters.
  318.      * Sets the "Last-Modified" header field if != -1.<BR>
  319.      * Sets the "Date" header to the current date/time<BR>
  320.      * Sets the "Server" header to getServerInfo<BR>
  321.      * throws an IllegalArgumentException on a malformed date header.<BR>
  322.      * just like sun's implemenation. :-( <BR>
  323.      *
  324.      * @return true: get the requested resource
  325.      *        false: don't get it.
  326.      */
  327.     private boolean testConditional(
  328.                 HttpServletRequest request,
  329.                 HttpServletResponse response) throws IOException {
  330.  
  331.         response.setDateHeader("Date",System.currentTimeMillis());
  332.         response.setHeader("Server",getServletConfig().getServletContext().getServerInfo());
  333.         long lastModifiedTime = getLastModified(request);
  334.         if(lastModifiedTime >= 0) {
  335.             response.setDateHeader("Last-Modified",lastModifiedTime);
  336.             long requestModifiedTime = request.getDateHeader("If-Modified-Since");
  337.             if((requestModifiedTime >= 0)
  338.              &&(requestModifiedTime <= lastModifiedTime )) {
  339.                 response.sendError(HttpServletResponse.SC_NOT_MODIFIED);
  340.                 return false;
  341.             }
  342.             /*
  343.             long requestUnModifiedTime = request.getDateHeader("If-Unmodified-Since");
  344.             if((requestUnModifiedTime != -1)
  345.              &&(requestUnModifiedTime > lastModifiedTime )) {
  346.                 response.setStatus(HttpServletResponse.SC_NOT_MODIFIED);
  347.                 return false;
  348.             }
  349.             */
  350.         }
  351.         return true;
  352.     }
  353.  
  354.  
  355.     /**
  356.      * This class is built for use in the doHead method of HttpServlet.<BR>
  357.      * The only reason it even has a name is that it needs a constructor.<BR>
  358.      * It enables the doHead method to have the doGet method do the work of
  359.      * a HEAD method without him noticing it.<BR>
  360.      * The only important method in this class is the getOutputStream
  361.      * method.
  362.      * This method returns a ServletOutputStream that has an empty
  363.      * write(int) and an empty write(byte[],int,int) implementation.
  364.      * <P>
  365.      * The real response is passed to this class in the constructor.
  366.      * All other methods call this response to do the work.
  367.      * This means that all those methods have an implementation of this
  368.      * form:
  369.      * <PRE>
  370.      *    void foo () {
  371.      *        realResponse.foo();
  372.      *    }
  373.      * </PRE>
  374.      */
  375.      private class DoHeadHttpServletResponse
  376.          implements HttpServletResponse {
  377.  
  378.         HttpServletResponse        myResponse;
  379.  
  380.  
  381.         DoHeadHttpServletResponse(HttpServletResponse response) {
  382.             myResponse = response;
  383.         }
  384.  
  385.  
  386.         public void addCookie(Cookie aCookie) {
  387.             myResponse.addCookie(aCookie);
  388.         }
  389.  
  390.  
  391.         public boolean containsHeader(String name) {
  392.             return myResponse.containsHeader(name);
  393.         }
  394.  
  395.  
  396.     #ifdef SERVLET_2_0
  397.     #else
  398.  
  399.         public String encodeRedirectURL(String url) {
  400.             return myResponse.encodeRedirectURL(url);
  401.         }
  402.  
  403.  
  404.         public String encodeURL(String url) {
  405.             return myResponse.encodeURL(url);
  406.         }
  407.  
  408.     #endif
  409.  
  410.         public void sendError(int errorCode, String errorMessage) throws IOException {
  411.             myResponse.sendError(errorCode,errorMessage);
  412.         }
  413.  
  414.  
  415.         public void sendError(int errorCode) throws IOException {
  416.             myResponse.sendError(errorCode);
  417.         }
  418.  
  419.  
  420.         public void sendRedirect(String location) throws IOException {
  421.             myResponse.sendRedirect(location);
  422.         }
  423.  
  424.  
  425.         public void setDateHeader(String name, long value) {
  426.             myResponse.setDateHeader(name,value);
  427.         }
  428.  
  429.  
  430.         public void setHeader(String name, String value) {
  431.             myResponse.setHeader(name,value);
  432.         }
  433.  
  434. #ifdef SERVLET_2_2
  435.         
  436.         public void addHeader(String name, String value) {
  437.             myResponse.addHeader(name,value);
  438.         }
  439.  
  440.         
  441.         public void addDateHeader(String name, long value) {
  442.             myResponse.addDateHeader(name,value);
  443.         }
  444.  
  445.         
  446.         public void addIntHeader(String name, int value) {
  447.             myResponse.addIntHeader(name,value);
  448.         }
  449.  
  450. #endif
  451.  
  452.         public void setIntHeader(String name, int value) {
  453.             myResponse.setIntHeader(name,value);
  454.         }
  455.  
  456.  
  457.         public void setStatus(int sc) {
  458.             myResponse.setStatus(sc);
  459.         }
  460.  
  461.  
  462.         public void setStatus(int sc, String sm) {
  463. #ifdef SERVLET_2_0
  464.             myResponse.setStatus(sc,sm);
  465. #else
  466.             // We could also call sendError(sc,sm),
  467.             // but that could throw an IOException.
  468.             myResponse.setStatus(sc);
  469. #endif
  470.         }
  471.  
  472.  
  473.         public String encodeUrl(String url) {
  474. #ifdef SERVLET_2_0
  475.             return myResponse.encodeUrl(url);    
  476. #else
  477.             return myResponse.encodeURL(url);
  478. #endif
  479.         }
  480.  
  481.  
  482.         public String encodeRedirectUrl(String url) {
  483. #ifdef SERVLET_2_0
  484.             return myResponse.encodeRedirectUrl(url);    
  485. #else
  486.             return myResponse.encodeRedirectURL(url);
  487. #endif
  488.         }
  489.  
  490.  
  491.     /* ********************************************************************
  492.      *                                                                    *
  493.      *                  ServletResponse Methods                           *
  494.      *                                                                    *
  495.      **********************************************************************/
  496.  
  497.         public void setContentLength(int length) {
  498.             myResponse.setContentLength(length);
  499.         }
  500.         
  501.         public void setContentType(String type) {
  502.             myResponse.setContentType(type);
  503.         }
  504.  
  505.  
  506.         /**
  507.          * Returns a dummy ServletOutputStream.
  508.          * This method is the only one whose implementation differs from that
  509.          * of an ordinary HttpServletResponse.
  510.          * The ServletOutputStream it returns has an empty write(int)
  511.          * and an empty write(byte[],int,int) implementation.
  512.          */
  513.         public ServletOutputStream getOutputStream() throws IOException {
  514.             return new ServletOutputStream() {
  515.                 public void write(int aByte)
  516.                             throws IOException {
  517.                 }
  518.  
  519.                 public void write(byte[] buffer,
  520.                             int offset,
  521.                             int length)
  522.                             throws IOException {
  523.                 }
  524.             };
  525.         }
  526.  
  527.  
  528.         public PrintWriter getWriter() throws IOException {
  529.             return myResponse.getWriter();
  530.         }
  531.  
  532.  
  533.         public String getCharacterEncoding() {
  534.             return myResponse.getCharacterEncoding();
  535.         }
  536.     }
  537. }
  538.