5.5Differentiating Among Different Browser Types
Use User-Agent only when necessary
Check for null
To differentiate between Netscape and Internet Explorer, check for “MSIE,” not “Mozilla.”
Note that the header can be faked.
package coreservlets; import java.io.*; import javax.servlet.*; import javax.servlet.http.*; /** Servlet that gives browser-specific insult. * Illustrates how to use the User-Agent * header to tell browsers apart. */ public class BrowserInsult extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html"); PrintWriter out = response.getWriter(); String title, message; // Assume for simplicity that Netscape and IE are // the only two browsers. String userAgent = request.getHeader("User-Agent"); if ((userAgent != null) && (userAgent.indexOf("MSIE") != -1)) { title = "Microsoft Minion"; message = "Welcome, O spineless slave to the " + "mighty empire."; } else { title = "Hopeless Netscape Rebel"; message = "Enjoy it while you can. " + "You <I>will</I> be assimilated!"; } String docType = "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 " + "Transitional//EN\">\n"; out.println(docType + "<HTML>\n" + "<HEAD><TITLE>" + title + "</TITLE></HEAD>\n" + "<BODY BGCOLOR=\"#FDF5E6\">\n" + "<H1 ALIGN=CENTER>" + title + "</H1>\n" + message + "\n" + "</BODY></HTML>"); } }
5.6Changing the Page According to How the User Got There
package coreservlets; import java.io.*; import javax.servlet.*; import javax.servlet.http.*; /** Servlet that displays referer-specific image. */ public class CustomizeImage extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html"); PrintWriter out = response.getWriter(); String referer = request.getHeader("Referer"); if (referer == null) { referer = "<I>none</I>"; } String title = "Referring page: " + referer; String imageName; if (contains(referer, "JRun")) { imageName = "jrun-powered.gif"; } else if (contains(referer, "Resin")) { imageName = "resin-powered.gif"; } else { imageName = "tomcat-powered.gif"; } String imagePath = "../request-headers/images/" + imageName; String docType = "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 " + "Transitional//EN\">\n"; out.println(docType + "<HTML>\n" + "<HEAD><TITLE>" + title + "</TITLE></HEAD>\n" + "<BODY BGCOLOR=\"#FDF5E6\">\n" + "<CENTER><H2>" + title + "</H2>\n" + "<IMG SRC=\"" + imagePath + "\">\n" + "</CENTER></BODY></HTML>"); } private boolean contains(String mainString, String subString) { return(mainString.indexOf(subString) != -1); } }
5.7 Accessing the Standard CGI Variables
A Servlet That Shows the CGI Variables
package coreservlets; import java.io.*; import javax.servlet.*; import javax.servlet.http.*; import java.util.*; /** Creates a table showing the current value of each * of the standard CGI variables. */ public class ShowCGIVariables extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html"); PrintWriter out = response.getWriter(); String[][] variables = { { "AUTH_TYPE", request.getAuthType() }, { "CONTENT_LENGTH", String.valueOf(request.getContentLength()) }, { "CONTENT_TYPE", request.getContentType() }, { "DOCUMENT_ROOT", getServletContext().getRealPath("/") }, { "PATH_INFO", request.getPathInfo() }, { "PATH_TRANSLATED", request.getPathTranslated() }, { "QUERY_STRING", request.getQueryString() }, { "REMOTE_ADDR", request.getRemoteAddr() }, { "REMOTE_HOST", request.getRemoteHost() }, { "REMOTE_USER", request.getRemoteUser() }, { "REQUEST_METHOD", request.getMethod() }, { "SCRIPT_NAME", request.getServletPath() }, { "SERVER_NAME", request.getServerName() }, { "SERVER_PORT", String.valueOf(request.getServerPort()) }, { "SERVER_PROTOCOL", request.getProtocol() }, { "SERVER_SOFTWARE", getServletContext().getServerInfo() } }; String title = "Servlet Example: Showing CGI Variables"; String docType = "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 " + "Transitional//EN\">\n"; out.println(docType + "<HTML>\n" + "<HEAD><TITLE>" + title + "</TITLE></HEAD>\n" + "<BODY BGCOLOR=\"#FDF5E6\">\n" + "<CENTER>\n" + "<H1>" + title + "</H1>\n" + "<TABLE BORDER=1>\n" + " <TR BGCOLOR=\"#FFAD00\">\n" + " <TH>CGI Variable Name<TH>Value"); for(int i=0; i<variables.length; i++) { String varName = variables[i][0]; String varValue = variables[i][1]; if (varValue == null) varValue = "<I>Not specified</I>"; out.println(" <TR><TD>" + varName + "<TD>" + varValue); } out.println("</TABLE></CENTER></BODY></HTML>"); } /** POST and GET requests handled identically. */ public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } }
6.2 HTTP 1.1 Status Codes
100–199
Codes in the 100s are informational, indicating that the client should
respond with some other action.
• 200–299
Values in the 200s signify that the request was successful.
• 300–399
Values in the 300s are used for files that have moved and usually
include a Location header indicating the new address.
• 400–499
Values in the 400s indicate an error by the client.
• 500–599
Codes in the 500s signify an error by the server.
6.4A Front End to Various Search Engines
package coreservlets; import java.io.*; import javax.servlet.*; import javax.servlet.http.*; import java.net.*; /** Servlet that takes a search string and a search * engine name, sending the query to * that search engine. Illustrates manipulating * the response status code. It sends a 302 response * (via sendRedirect) if it gets a known search engine, * and sends a 404 response (via sendError) otherwise. */ public class SearchEngines extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String searchString = request.getParameter("searchString"); if ((searchString == null) || (searchString.length() == 0)) { reportProblem(response, "Missing search string"); return; } // The URLEncoder changes spaces to "+" signs and other // non-alphanumeric characters to "%XY", where XY is the // hex value of the ASCII (or ISO Latin-1) character. // Browsers always URL-encode form values, and the // getParameter method decodes automatically. But since // we're just passing this on to another server, we need to // re-encode it to avoid characters that are illegal in // URLs. Also note that JDK 1.4 introduced a two-argument // version of URLEncoder.encode and deprecated the one-arg // version. However, since version 2.3 of the servlet spec // mandates only the Java 2 Platform (JDK 1.2 or later), // we stick with the one-arg version for portability. searchString = URLEncoder.encode(searchString); String searchEngineName = request.getParameter("searchEngine"); if ((searchEngineName == null) || (searchEngineName.length() == 0)) { reportProblem(response, "Missing search engine name"); return; } String searchURL = SearchUtilities.makeURL(searchEngineName, searchString); if (searchURL != null) { response.sendRedirect(searchURL); } else { reportProblem(response, "Unrecognized search engine"); } } private void reportProblem(HttpServletResponse response, String message) throws IOException { response.sendError(response.SC_NOT_FOUND, message); } }
package coreservlets; /** Small class that encapsulates how to construct a * search string for a particular search engine. */ public class SearchSpec { private String name, baseURL; public SearchSpec(String name, String baseURL) { this.name = name; this.baseURL = baseURL; } /** Builds a URL for the results page by simply concatenating * the base URL (http://...?someVar=") with the URL-encoded * search string (jsp+training). */ public String makeURL(String searchString) { return(baseURL + searchString); } public String getName() { return(name); } }
package coreservlets; /** Utility with static method to build a URL for any * of the most popular search engines. */ public class SearchUtilities { private static SearchSpec[] commonSpecs = { new SearchSpec("Google", "http://www.google.com/search?q="), new SearchSpec("AllTheWeb", "http://www.alltheweb.com/search?q="),new SearchSpec("Yahoo", "http://search.yahoo.com/bin/search?p="), new SearchSpec("AltaVista", "http://www.altavista.com/web/results?q="), new SearchSpec("Lycos", "search.lycos.com/default.asp?query="), new SearchSpec("HotBot", "http://hotbot.com/default.asp?query="), new SearchSpec("MSN", "http://search.msn.com/results.asp?q="), }; public static SearchSpec[] getCommonSpecs() { return(commonSpecs); } /** Given a search engine name and a search string, builds * a URL for the results page of that search engine * for that query. Returns null if the search engine name * is not one of the ones it knows about. */ public static String makeURL(String searchEngineName, String searchString) { SearchSpec[] searchSpecs = getCommonSpecs(); String searchURL = null; for(int i=0; i<searchSpecs.length; i++) { SearchSpec spec = searchSpecs[i]; if (spec.getName().equalsIgnoreCase(searchEngineName)) { searchURL = spec.makeURL(searchString); break; } } return(searchURL); } }