《Java Servlet Programming》读书笔记_2010.06.10

来源:互联网 发布:淘宝打不开手机相册了 编辑:程序博客网 时间:2024/06/07 10:10

Locking a Servlet to a Server (Example)

package cn.com.per.retrievinginfo;

 

import java.io.IOException;

import java.io.PrintWriter;

import java.net.InetAddress;

import java.net.UnknownHostException;

 

import javax.servlet.GenericServlet;

import javax.servlet.ServletException;

import javax.servlet.ServletRequest;

import javax.servlet.ServletResponse;

 

@SuppressWarnings("serial")

public class KeyedServerLock extends GenericServlet {

    //This servlet has no class or instance variables

    //associated with the locking, so as to simplify

    //synchronization issues.

    @Override

    public void service(ServletRequest req, ServletResponse res)

           throws ServletException, IOException {

       res.setContentType("text/plain");

       PrintWriter out = res.getWriter();

       //The piracy check shouldn't be done in init

       //because name/port are part of request

       String key = getInitParameter("key");

       String host = req.getServerName();

       int port = req.getServerPort();

      

       //Check if the init parameter "key" unlocks this server

       if(!keyFitsServer(key, host, port)) {

           //Explain, condemn, threaten, etc.

           out.println("Pirated!");

       }

       else {

           //Give 'em the goods

           out.println("Valid");

           //etc...

       }

    }

   

    //This method contains the algorithm used to match a key with

    //a server host and port. This example implementation is extremely

    //weak and should not be used by commercial sites.

    private boolean keyFitsServer(String key, String host, int port) {

       if(key == null) return false;

      

       long numericKey = 0;

       try {

           numericKey = Long.parseLong(key);

       } catch (NumberFormatException e) {

           return false;

       }

      

       //The key must be a 64-bit number equal to the logical not(~)

       //of the 32-bit IP address concatenated with the 32-bit port number

       byte hostIP[];

       try {

           hostIP = InetAddress.getByName(host).getAddress();

       } catch(UnknownHostException e) {

           return false;

       }

      

       //Get the 32-bit IP address

       long servercode = 0;

       for(int i = 0; i < 4; i++) {

           servercode <<= 8;

           servercode |= hostIP[i];

       }

      

       //Concatenate the 32-bit port number

       servercode <<= 32;

       servercode |= port;

      

       //logical not

       Long accesscode = ~numericKey;

      

       //The moment of truth:Does the key match?

       return (servercode == accesscode);

    }

}

 

Getting a Context Init Parameter

l  public String ServletContext.getInitParameter(String name)

return the string value of the specified parameter

l  public Enumeration ServletContext.getInitParameterNames()

return an Enumeration containing the names of all the init parameters to the web application

The init parameters for acontext are specified in the web.xml deployment descriptor for the context using the <context-param> tags. Like:
<web-app><context-param>
     <param-name>rmihost</param-name>
     <param-value>localhost</param-value>
</context-param></web-app>
Any servlet within this web application can read the context init parameters
There’s no standard mechanism to create global init parameters visible across all contexts.

2010-06-10

Determining the Servlet Version

l  A servlet can also ask the server what Servlet API version the server supports.Besides being useful for debugging, a servlet can use this information to decide whether to use a new approach to solve a task or an older, perhaps less efficient, approach.

l  Servlet API 2.1 introduced two methods to return the version information.
public int ServletContext.getMajorVersion()  //for servlet API 2.1, it returns 2
public int ServletContext.getMinorVersion()  //for servlet API 2.1, it returns 1

 

4.3 The Client

Getting Information About the Client Machine

l  public String ServletRequest.getRemoteAddr()  //return the IP address of the client machine

l  public String ServletRequest.getRemoteHost()  //return the hostname of the client machine

l  The information comes from the socket that connects the server to the client, so the remote address and hostname may be that of a proxy server.

l  The IP address or remote hostname can be converted to a java.net.InetAddress object using InetAddress.getByName() :
InetAddress remoteInetAddress = InetAddress.getByName(req.getRemoteAddr());

 

Restricting Access

Example:

package cn.com.per.servlet.retrievinginfo;

 

import java.io.IOException;

import java.io.PrintWriter;

 

import javax.servlet.ServletException;

import javax.servlet.http.HttpServlet;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

 

/**

 * @author Alex

 *

 * Can they be trusted?

 */

@SuppressWarnings("serial")

public class ExportRestriction extends HttpServlet {

 

    public void doGet(HttpServletRequest request, HttpServletResponse response)

           throws ServletException, IOException {

 

       response.setContentType("text/html");

       PrintWriter out = response.getWriter();

 

       // ...Some introductory HTML...

      

       //Get the client's hostname

       String remoteHost = request.getRemoteHost();

      

       //See if the client is allowed

       if(!isHostAllowed(remoteHost)) {

           out.println("Access <BLINK>denied</BLINK>");

       }

       else {

           out.println("Access granted");

           //Display download links, etc...

       }

    }

   

    //Disallow hosts ending with .cu, .ir, .iq

    private boolean isHostAllowed(String host) {

       return (!host.endsWith(".cu") && !host.endsWith(".ir") && !host.endsWith(".iq"));

    }

}

 

Getting Information About the User

l  public String HttpServletRequest.getRemoteUser()
//return the name of the user making the request as a String
//  or null if access to the servlet was not restricted.

l  public String HttpServletRequest.getAuthType()
//return the type of authentication used or null if access to the servlet was not restricted.
The types may be BASIC, DIGEST, FORM, or CLIENT-CERT.

l  With the remote user’name, a servlet can save information about each client.

n  Over the long term, it can remember each individual’s preferences.

n  For the short term, it can remember the series of pages viewed by the client and use them to add a sense of state to a stateless HTTP protocol.

 

Request Parameters

l  An HTTP servlet gets its request parameters as part of its query string(for GET requests) or as encoded POST data (for POST requests), or sometimes both.

l  public String ServletRequest.getParameter(String name)
return the value of the named parameter as a String or null if the parameter was not specified

l  public String[] ServletRequest.getParameterValues(String name)
return the values of the named parameter as an array of String objects or null

l  A single value is returned in an array of length 1. If you call getParameter() on a parameter with multiple values, the value is the same as the first value returned by getParameterValues()

l  One word of warning: if the parameter information came in as encoded POST data, it vill not be available if the POST data has already been read manually using the getReader() or getInputStream() method of ServletRequest(because POST data can be read only once).

l  Inaddtion to getting parameter values, a servlet can access parameter names using getParameterNames(): public Enumeration ServletRequest.getParameterNames()
This method returns all the parameter names as an Enumeration of String object or an empty enu.
The method is most often used for debugging.

l  A servlet can retrieve the raw query string of the request with getQueryString():
public String ServletRequest.getQueryString()
return the raw query string of the request or null if there was no query string.

l  For example, if a request has a query string of a=hokey an POST data of a=pokey,
the reqest.getParameterValues(“a”) method would return the array {“hokey”, “pokey”}

 

Path Information

l  In addition to parameters, an HTTP request can include something called extra path information or a virtual path. This path information is encoded in the URL of an HTTP request.

 

Getting Path Information

l  public String HttpServletRequest.getPathInfo()
return the extra path information associated with the request(URL decoded if necessary) or null

l  public String HttpServletRequest.getPathTranslated()
return the extra path information translated to a real filesystem path or null

 

Ad hoc Path Information

l  public String ServletContext.getRealPath(String path)
return the real path of any given virtual path or null if the translation cannot be performed.
If the given path is /, the method returns the document root for the server.
If the given path is getPathInfo(), the method returns the same real path as would be returned by getPathTranslated().

l  This method can be used by generic servlets as well as HTTP servlets.

 

Getting the context path

l  Web applications are mapped to URI prefixes on the server.

l  public String HttpServletRequest.getContextPath()
return a String representing the URI prefix of the context handling the request.
The value starts with /, has no ending /, and, for the default context, is empty.

 

Getting MIME types

l  public String ServletContext.getMimeType(String file)
return the MIME type of the given file, based on its extension, or null if it isn’t know.
Common MIME types are text/html, text/plain, image/gif, and image/jpeg.

l  Example: String type = getServletContext().getMimeType(req.getPathTranslated())
the code fragment finds the MIME type of the extra path information.

 

Reading from an Abstact Resource

l  public URL ServletContext.getResource(String uripath)
return a URL that used to investigate the specified resource and read its content
A servlet gains access to an abstract resource using this method.

l  The getResource() method is intended to support only reading of static content(no dynamic content an no writing of content).