Web programmers face many difficult decisions, not the least of which is how to deal with the fairly horrible state of modern browsers. A popular Web site is likely to receive requests from versions of Internet Explorer 3 through 6, Mozilla, Netscape 4.7, Opera, various AOL browsers, and numerous custom browsers now available in consumer devices, such as phones and PDAs (personal digital assistants). Each of these is likely to render HTML slightly differently, support different media types, and handle JavaScript differently, if at all.
One way of dealing with this variability is to use the “lowest common denominator,” that is, only those features that are supported and work the same in every browser. This makes things easier for the Web developer but means that the user will be getting a site that looks like something from the early 1990s, which may disappoint many users. Alternatively, Web developers may design a site for one browser—perhaps Mozilla 1.0—and put up a note encouraging other users to switch to this browser. This is likely to infuriate many users who either don’t want to or can’t change browsers simply to get to one site.
Finally, developers can create parallel versions of all the browser-specific HTML and JavaScript and so on and send out the appropriate version, based on which browser is being used. The browser makes this possible by identifying itself with every request, and JSPs make this possible through the conditional tags. A skeleton of code that accomplishes this is shown in Listing 4.11.
Listing 4.11 Browser detection
<%@ taglib prefix="c" uri="http://java.sun.com/jstl/core" %> <jsp:useBean id="browser" class="com.awl.jspbook.ch04.BrowserBean"/> <c:set target="${browser}" property="request" value="${pageContext.request}"/> You are using a browser that identifies itself as <c:out value="${browser.fullName}"/><p> <c:if test="${browser.type == 'Gecko'}"> ... include Mozilla code here ... </c:if> <c:if test="${browser.type == 'MSIE'}"> ... include IE code here ... </c:if>
This example uses BrowserBean, a utility bean that extracts browser information from the request. In order to obtain this information, BrowserBean must have access to the request object. This object is obtained from the pageContext, as was done in Listing 4.7, and passed with a c:set tag to the bean.
A bean such as BrowserBean is needed for two reasons: first, because the browser name is not available as a simple property, such as the ones shown in Listing 4.7; second, because the full name of the browser is likely to be something unwieldy, such as Mozilla/5.0 (X11; U; FreeBSD i386; en-US; rv:1.0rc3) Gecko/20020607, which contains information about the specific revision and operating system on which the browser is running. This is generally more information than needed to select the appropriate browser-specific code for a page. This second problem is solved by having the bean recognize major browser types, and it is this type that is used by the c:if tags.