| Servlet-JSP Notes |
|
| Written by Sudhanshu Prakash | |
| Monday, 14 July 2008 07:43 | |
|
To be a servlet, a class should extend HttpServlet and override doGet or doPost, depending on whether the data is being sent by GET or by POST. If you want the same servlet to handle both GET and POST and to take the same ction for each, you can simply have doGet call doPost, or vice versa.
public void init() throws ServletException { // Initialization code... } public void init(ServletConfig config) throws ServletException { super.init(config); } public void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // Servlet Code } This is not a good idea. Instead, just have doPost call doGet (or viceversa), as below. public void doGet(HttpServletRequest request, HttpServletResponse response) } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } Although this approach takes a couple of extra lines of code, it has five advantages over directly overriding service: 4. You get automatic support for OPTIONS requests. If a doGet method exists, the standard service method answers OPTIONS requests by returning an Allow header indicating that GET, HEAD, OPTIONS, and TRACE are supported. 5. You get automatic support for TRACE requests. TRACE is a request method used for client debugging: it just returns the HTTP request headers back to the client. public class YourServlet extends HttpServletimplements SingleThreadModel {
The Role of Form Data: If you've ever used a search engine, visited an on-line bookstore, tracked stocks on the Web, or asked a Web-based site for quotes on plane tickets, you've probably seen funny-looking URLs like The http://host/path?user=Marty+Hall&origin=bwi&dest=lax. part after the question mark (i.e., user=Marty+Hall&origin= bwi&dest=lax) is known as form data (or query data) and is the most com- mon way to get information from a Web page to a server-side program. Form data can be attached to the end of the URL after a question mark (as above), for GET requests, or sent to the server on a separate line, for POST requests. If you're not familiar with HTML forms, Chapter 16 (Using HTML Forms) gives details on how to build forms that collect and transmit data of this sort. Reading Form Data from Servlets: You simply call the getParameter method of the Http-ServletRequest, supplying the case-sensitive parameter name as an argu- ment. You use getParameter exactly the same way when the data is sent by GET as you do when it is sent by POST. The servlet knows which request method was used and automatically does the right thing behind the scenes. The return value is a String corresponding to the URL-decoded value of the first occurrence of that parameter name. An empty String is returned if the parameter exists but has no value, and null is returned if there was no such parameter. If the parameter could potentially have more than one value, you should call getParameterValues (which returns an array of strings) instead of getParameter (which returns a single string). The return value of getParameterValues is null for nonexistent parameter names and is a one-element array when the parameter has only a single value. Parameter names are case sensitive so, for example, request.get- Parameter("Param1") and request.getParameter("param1") are not interchangeable. getParameter: To read single value from HttpServletRequest. parameter names are case sensitive. getParameterValues: To read multiple values (if same param name appear more than once in GET/POST data) getParameter will return single string corresponding to the first value. getparameterValues will return array of strings. getParameterNames and getParameterMap: To get full list of parameter names. There is not gurantee that any particular underlying datastructure will be used. And, Since some common data structures (hash tables, in particular) scramble the order of elements, you should not count on getparameterNames returning the parameters in the order in which they appear in HTML FORM. "Don't count on getParameterNames returning the names in any particular order." Reading Raw form data and parsing uploaded Files: getReader and getInputStream If you read data in this manner, it is not guranteed to be available with getParameter. The first case in which you might read and parse the data yourself is when the data comes from a custom client rather than by an HTML form. The most common custom client is an APPLET. APPLET-servlet cmmunication of this nature is discussed later. Eample of Reading All Parameters: Enumerations paramNames = request.getParameterNames(); while( paramNames.hasMoreElements() ) { String paramName = (String) paramNames.nextElement(); String[] paramValues = paramName.getParameterValues(paramName); } Points to Ponder: When examining request parameters, you need to check for three conditions: 1. The value is null 2. The value is an empty string. 3. The value is non-empty string of wrong format. Filtering Strings for HTML-Specific Characters: The first case where manual conversion is difficult occurs when the string is derived from a program excerpt or another source where it is already in some standard format. Going through manually and changing all the special characters can be tedious in such a case, but forgetting to convert even one special character can result in your Web page having missing or improperly formatted sections (see Figure 39 later in this section). The second case where manual conversion fails is when the string is derived from HTML form data. Here, the conversion absolutely must be performed at runtime, since of course the query data is not known at compile time. Failing to do this for an internal Web page can also result in missing or improperly formatted sections of the servlet's output if the user ever sends these special characters. Failing to do this filtering for externally-accessible Web pages also lets your page become a vehicle for the cross-site scripting attack. Here, a malicious programmer embeds GET parameters in a URL that refers to one of your servlets. These GET parameters expand to HTML <SCRIPT> elements that exploit known browser bugs. However, by embed- ding the code in a URL that refers to your site and only distributing the URL, not the malicious Web page itself, the attacker can remain undiscovered more easily and can also exploit trusted relationships to make users think the scripts are coming from a trusted source (your servlet). For more details on this issue, see http://www.cert.org/advisories/ CA-2000-02.html and http://www.microsoft.com/technet/security/crssite.asp. HTTP Headers Note that HTTP request headers are distinct from the form data dis- cussed in the previous chapter. Form data results directly from user input and is sent as part of the URL for GET requests and on a separate line for POST requests. Request headers, on the other hand, are indirectly set by the browser and are sent immediately following the initial GET or POST request line. For instance, the following example shows an HTTP request that might result from submitting a book-search request to a servlet at http://www.somebookstore.com/search. The request includes the head- ers Accept, Accept-Encoding, Connection, Cookie, Host, Referer, and User-Agent, all of which might be important to the operation of the serv- let, but none of which can be derived from the form data or deduced auto- Reading Request Header: Reading headers is straightforward; just call the getHeader method of HttpServletRequest, which returns a String if the specified header was supplied on this request, null otherwise. Header names are not case sensi- tive. So, for example, request.getHeader("Connection") and request.getHeader("connection") are interchangeable. Always check that request.getHeader is non-null before using it. getCookies getCookies returns the contents of the Cookie header, parsed and stored in an array of Cookie objects. getAuthType and getRemoteUser getAuthType and getRemoteUser break the Authorization header into its component pieces. getContentLength The getContentLength method returns the value of the Content-Length header (as an int). getContentType The getContentType method returns the value of the Content-Type header (as a String). getDateHeader and getIntHeader The getDateHeader and getIntHeader methods read the specified header and then convert them to Date and int values, respectively. getHeaderNames Rather than looking up one particular header, you can use the getHeaderNames method to get an Enumeration of all header names received on this particular request. getHeaders If a header appears (it can) multiple times, with each occurrence listing a separate value. If a header name is repeated in the request, version 2.1 servlets cannot access the later values without reading the raw input stream, since getHeader returns the value of the first occurrence of the header only. In version 2.2, however, getHeaders returns an Enumeration of the values of all occurrences of the header. Finally, in addition to looking up the request headers, you can get informa- tion on the main request line itself, also by means of methods in Http- ServletRequest. getMethod The getMethod method returns the main request method (normally GET or POST, but things like HEAD, PUT, and DELETE are possible). getRequestURI The getRequestURI method returns the part of the URL that comes after the host and port but before the form data. For example, for a URL of http://randomhost.com/servlet/search.BookSearch, getRequestURI would return /servlet/search.BookSearch. getProtocol Lastly, the getProtocol method returns the third part of the request line, which is generally HTTP/1.0 or HTTP/1.1. Servlets TODO: Different HTTP 1.1 Header Names and their meaning. Sending Compressed web pages. Generating the Server Response: HTTP Status Codes Genrating the Server Response: HTTP Response Headers: setContentType This method sets the Content-Type header and is used by the majority of servlets. setContentLength This method sets the Content-Length header, which is useful if the browser supports persistent (keep-alive) HTTP connections. See Section 7.4 for an example. addCookie This method inserts a cookie into the Set-Cookie header. There is no corresponding setCookie method, since it is normal to have multiple Set-Cookie lines. See Chapter 8 for a discussion of cookies. sendRedirect As discussed in the previous chapter, the sendRedirect method sets the Location header as well as setting the status code to 302. Handling Cookies Cookies are never interpreted or executed in any way and thus cannot be used to insert viruses. Furthermore, since browsers generally only accept 20 cookies per site, and since browsers can limit each cookies to 4 kilobytes, cookies cannot be used to fill up someone's disk or launch other denial-of-service attack. Advantages of cookies:
To send cookies to the client, a servlet should create one or more cookies with designated names and values with new Cookie(name, value), set any optional attributes with cookie.setXxx (readable later by cookie.getXxx), and insert the cookies into the response headers with response.addCookie(cookie). To read incoming cookies, a servlet should call request.getCookies, which returns an array of Cookie objects corre- sponding to the cookies the browser has associated with your site (this is null if there are no cookies in the request). In most cases, the servlet loops down this array until it finds the one whose name (getName) matches the name it had in mind, then calls getValue on that Cookie to see the value associated with that name. Each of these topics is discussed in more detail in the following sections. Sending Cookie to the client:
C.setMaxAge( 60 * 60 * 24 * 7 ); // One Week By creating a Cookie object and calling setMaxAge, all you have done is manipulate a data structure in the server's memory. You haven't actually sent anything to the client/ browser. If you don't send the cookie to the client, it has no effect. response.addCookie(C); Reading Cookies from the client:
Before adding the cookie to the outgoing headers, you can set various charac- teristics of the cookie by using one of the following setXxx methods, where Xxx is the name of the attribute you want to specify. Each setXxx method has a corresponding getXxx method to retrieve the attribute value. Except for name and value, the cookie attributes apply only to outgoing cookies from the server to the client; they aren't set on cookies that come from the browser to the server. See Appendix A (Servlet and JSP Quick Reference) for a sum- marized version of this information. public String getComment() public void setComment(String comment) These methods look up or specify a comment associated with the cookie. With version 0 cookies (see the upcoming subsection on getVersion and setVersion), the comment is used purely for informational purposes on the server; it is not sent to the client. public String getDomain() public void setDomain(String domainPattern) These methods get or set the domain to which the cookie applies. Normally, the browser only returns cookies to the exact same host- name that sent them. You can use setDomain method to instruct the browser to return them to other hosts within the same domain. To prevent servers setting cookies that apply to hosts outside their domain, the domain specified is required to start with a dot (e.g., .prenhall.com), and must contain two dots for noncountry domains like .com, .edu and .gov; and three dots for country domains like .co.uk and .edu.es. For instance, cookies sent from a servlet at bali.vacations.com would not normally get sent by the browser to pages at mexico.vacations.com. If the site wanted this to happen, the servlets could specify cookie.setDomain(".vacations.com"). public int getMaxAge() public void setMaxAge(int lifetime) These methods tell how much time (in seconds) should elapse before the cookie expires. A negative value, which is the default, indicates that the cookie will last only for the current session (i.e., until the user quits the browser) and will not be stored on disk. See the LongLivedCookie class (Listing 8.4), which defines a subclass of Cookie with a maximum age automatically set one year in the future. Specifying a value of 0 instructs the browser to delete the cookie. public String getName() public void setName(String cookieName) This pair of methods gets or sets the name of the cookie. The name and the value are the two pieces you virtually always care about. However, since the name is supplied to the Cookie constructor, you rarely need to call setName. On the other hand, getName is used on almost every cookie received on the server. Since the getCookies method of Http- ServletRequest returns an array of Cookie objects, it is common to loop down this array, calling getName until you have a particular name, then check the value with getValue. For an encapsulation of this pro- cess, see the getCookieValue method shown in Listing 8.3. public String getPath() public void setPath(String path) These methods get or set the path to which the cookie applies. If you don't specify a path, the browser returns the cookie only to URLs in or below the directory containing the page that sent the cookie. For example, if the server sent the cookie from http://ecommerce.site.com/toys/ specials.html, the browser would send the cookie back when connect- ing to http://ecommerce.site.com/toys/bikes/beginners.html, but not to http://ecommerce.site.com/cds/classical.html. The setPath method can be used to specify something more general. For example, someCookie.setPath("/") specifies that all pages on the server should receive the cookie. The path specified must include the current page; that is, you may specify a more general path than the default, but not a more specific one. So, for example, a servlet at http://host/store/cust-service/request could specify a path of /store/ (since /store/ includes /store/cust-service/) but not a path of /store/cust-service/returns/ (since this directory does not include /store/cust-service/). public boolean getSecure() public void setSecure(boolean secureFlag) This pair of methods gets or sets the boolean value indicating whether the cookie should only be sent over encrypted (i.e., SSL) connections. The default is false; the cookie should apply to all connections. public String getValue() public void setValue(String cookieValue) The getValue method looks up the value associated with the cookie; the setValue method specifies it. Again, the name and the value are the two parts of a cookie that you almost always care about, although in a few cases, a name is used as a boolean flag and its value is ignored (i.e., the existence of a cookie with the designated name is all that matters). public int getVersion() public void setVersion(int version) These methods get/set the cookie protocol version the cookie complies with. Version 0, the default, follows the original Netscape specification (http://www.netscape.com/newsref/std/cookie_spec.html). Reading Cookies from the Client To send cookies to the client, you create a Cookie, then use addCookie to send a Set-Cookie HTTP response header. To read the cookies that come back from the client, you call getCookies on the HttpServletRequest. This call returns an array of Cookie objects corresponding to the values that came in on the Cookie HTTP request header. If there are no cookies in the request, getCookies returns null. Once you have this array, you typically loop down it, calling getName on each Cookie until you find one matching the name you have in mind. You then call getValue on the matching Cookie and finish with some processing specific to the resultant value. This is such a common process that Section 8.5 presents two utilities that simplify retrieving a cookie or cookie value that matches a designated cookie name. Current browsing sesssion means -- until the user restarts the browser. Modifying Cookie values: To replace a previous cookie value, send the same cookie name with a different cookie value. If you actually use the incoming Cookie objects, don't forget to do response.addCookie; merely calling setValue is not sufficient. You also need to reapply any relevant cookie attributes by calling setMaxAge, setPath etc. -- cookie attributes are not specified for incoming cookies. Reapplying these attributes means that refusing the incoming Cookie objects saves you little, so many developers don't bother. To instruct the browser to delete a cookie, use setMaxAge to assign a max age of 0. Session Tracking There are three typical ways of session tracking: Cookies URL Rewriting With this approach, the client appends some extra data on the end of each URL that identifies the session, and the server associates that identifier with data it has stored about that session. For example, with http://host/path/file.html;jsessionid=1234, the session information is attached as jsessionid=1234. This is also an excellent solution, and even has the advantage that it works when browsers don't support cookies or when Hidden Form Fields HTML forms can have an entry that looks like the following: <INPUT TYPE="HIDDEN" NAME="session" VALUE="..."> This entry means that, when the form is submitted, the specified name and value are included in the GET or POST data. For details, see Section 16.9 (Hidden Fields). This hidden field can be used to store information about the session but it has the major disadvantage that it only works if every page is dynamically generated. The Session Tracking API Using sessions in servlets is straightforward and involves looking up the ses- sion object associated with the current request, creating a new session object when necessary, looking up information associated with a session, storing information in a session, and discarding completed or abandoned sessions. Finally, if you return any URLs to the clients that reference your site and URL-rewriting is being used, you need to attach the session information to the URLs. Looking Up the HttpSession Object Associated with the Current Request You look up the HttpSession object by calling the getSession method of HttpServletRequest. Behind the scenes, the system extracts a user ID from a cookie or attached URL data, then uses that as a key into a table of previously created HttpSession objects. But this is all done transparently to the programmer: you just call getSession. If getSession returns null, this means that the user is not already participating in a session, so you can create a new session. Creating a new session in this case is so commonly done that there is an option to automatically create a new session if one doesn't already exist. Just pass true to getSession. Thus, your first step usually looks like this: HttpSession session = request.getSession(true); If you care whether the session existed previously or is newly created, you can use isNew to check. TODO Calling getSession(false) ..... Looking up information associated with a Session TODO TODO. (getValue or getAttributue ?) HttpSession objects live on the server; they're just automatically associated with the client by a behind-the-scenes mechanism like cookies or URL-rewriting. These session objects have a built-in data structure that lets you store any number of keys and associated values. In version 2.1 and earlier of the servlet API, you use session.getValue("attribute") to look up a previously stored value. The return type is Object, so you have to do a type- cast to whatever more specific type of data was associated with that attribute name in the session. The return value is null if there is no such attribute, so you need to check for null before calling methods on objects associated with sessions. Methods in HttpSession Class: public Object getValue(String name) public Object getAttribute(String name) These methods extract a previously stored value from a session object. They return null if there is no value associated with the given name. Use getValue in version 2.1 of the servlet API. Version 2.2 supports both methods, but getAttribute is preferred and getValue is deprecated. public void putValue(String name, Object value) public void setAttribute(String name, Object value) These methods associate a value with a name. Use putValue with version 2.1 servlets and either setAttribute (preferred) or putValue (deprecated) with version 2.2 servlets. If the object supplied to putValue or setAttribute implements the HttpSessionBinding- Listener interface, the object's valueBound method is called after it is stored in the session. Similarly, if the previous value implements HttpSessionBindingListener, its valueUnbound method is called. public void removeValue(String name) public void removeAttribute(String name) These methods remove any values associated with the designated name. If the value being removed implements HttpSessionBindingListener, its valueUnbound method is called. With version 2.1 servlets,use removeValue. In version 2.2, removeAttribute is preferred, but removeValue is still supported (albeit deprecated) for backward compatibility. public String[] getValueNames() public Enumeration getAttributeNames() These methods return the names of all attributes in the session. Use getValueNames in version 2.1 of the servlet specification. In version 2.2, getValueNames is supported but deprecated; use getAttribute- Names instead. public String getId() This method returns the unique identifier generated for each session. It is sometimes used as the key name when only a single value is associated with a session, or when information about sessions is being logged. public boolean isNew() This method returns true if the client (browser) has never seen the ses- sion, usually because it was just created rather than being referenced by an incoming client request. It returns false for preexisting sessions. public long getCreationTime() This method returns the time in milliseconds since midnight, January 1, 1970 (GMT) at which the session was first built. To get a value useful for printing out, pass the value to the Date constructor or the setTimeIn- Millis method of GregorianCalendar. public long getLastAccessedTime() This method returns the time in milliseconds since midnight, January 1, 1970 (GMT) at which the session was last sent from the client. public int getMaxInactiveInterval() public void setMaxInactiveInterval(int seconds) These methods get or set the amount of time, in seconds, that a session should go without access before being automatically invalidated. A neg- ative value indicates that the session should never time out. Note that the time out is maintained on the server and is not the same as the cookie expiration date, which is sent to the client. public void invalidate() This method invalidates the session and unbinds all objects associated with it. Terminating Sessions Sessions will automatically become inactive when the amount of time between client accesses exceeds the interval specified by getMax- InactiveInterval. When this happens, any objects bound to the Http- Session object automatically get unbound. When this happens, your attached objects will automatically be notified if they implement the HttpSessionBindingListener interface. Rather than waiting for sessions to time out, you can explicitly deactivate a session through the use of the session's invalidate method. Encoding URLs Sent to the Client If you are using URL-rewriting for session tracking and you send a URL that references your site to the client, you need to explicitly add on the session data. Since the servlet will automatically switch to URL-rewriting when cook- ies aren't supported by the client, you should routinely encode all URLs that reference your site. There are two possible places you might use URLs that refer to your own site. The first is when the URLs are embedded in the Web page that the servlet generates. These URLs should be passed through the encodeURL method of HttpServletResponse. The method will determine if URL-rewriting is currently in use and append the session information only if necessary. The URL is returned unchanged otherwise. Here's an example: String originalURL = someRelativeOrAbsoluteURL; String encodedURL = response.encodeURL(originalURL); out.println("<A href=\"" + encodedURL + "\">...</A>"); The second place you might use a URL that refers to your own site is in a sendRedirect call (i.e., placed into the Location response header). In this second situation, there are different rules for determining if session informa- tion needs to be attached, so you cannot use encodeURL. Fortunately, Http- ServletResponse supplies an encodeRedirectURL method to handle that case. Here's an example: String originalURL = someURL; // Relative URL OK in version 2.2 String encodedURL = response.encodeRedirectURL(originalURL); response.sendRedirect(encodedURL); Java Servlet Pages Template Text In many cases, a large percentage of your JSP page just consists of static HTML, known as template text. In almost all respects, this HTML looks just like normal HTML, follows all the same syntax rules, and is simply "passed through" to the client by the servlet created to handle the page. Not only does the HTML look normal, it can be created by whatever tools you already are using for building Web pages. For example, I used Allaire's HomeSite for most of the JSP pages in this book. There are two minor exceptions to the "template text is passed straight through" rule. First, if you want to have <% in the output, you need to put <\% in the template text. Second, if you want a comment to appear in the JSP page but not in the resultant document, use <%-- JSP Comment --%> HTML comments of the form <!-- HTML Comment --> are passed through to the resultant HTML normally. JSP Expression A JSP expression is used to insert values directly into the output. It has the following form: <%= Java Expression %> The expression is evaluated, converted to a string, and inserted in the page. This evaluation is performed at run time (when the page is requested) and thus has full access to information about the request. For example, the following shows the date/time that the page was requested: Current time: <%= new java.util.Date() %> JSP expression can be used to assign attribute values .... <jsp:setProperty name="author" property="firstName" value="Marty" /> Attributes that permit JSP Expression jsp:setProperty name/value jsp:include page atr jsp:formard page attr jsp:param page attr Predefined Variables Thee predefined variables are implicit objects and these names can be used directly in jspExpression or scriptlet but not in jsp declaration, because JSP declarations result in code that appears outside of the _jspService method. request, the HttpServletRequest response, the HttpServletResponse session, the HttpSession associated with the request (unlessdisabled with session attribute of page directive ) out, the PrintWriter (a buffered version called JspWriter) used to send output to the client application: ServletContext as obtain vi ServletConfig.getContext(). It has getAttribute and setAttribute to associate data with specified keys config: ServletConfig pageContext: single point of access to many of the page attributes and provide convenient place to store shared data. It stores the value of pageContext object associated with the current page. page: this is simply synonym for this and not much useful for java. XML Syntax for expression: <jsp:expression> Java Expression </jsp:expression> JSP Scriptlet If you want to do something more complex than insert a simple expression, JSP scriptlets let you insert arbitrary code into the servlet's _jspService method (which is called by service). Scriptlets have the following form: <% Java Code %> Scriptlets have access to the same automatically defined variables as expressions (request, response, session, out, etc.; see Section 10.5). So, for example, if you want output to appear in the resultant page, you would use the out variable, as in the following example. <% String queryData = request.getQueryString(); out.println("Attached GET data: " + queryData); %> In general, however, scriptlets can perform a number of tasks that cannot be accomplished with expressions alone. These tasks include setting response headers and status codes, invoking side effects such as writing to the server log or updating a database, or executing code that contains loops, condition- als, or other complex constructs. For instance, the following snippet specifies that the current page is sent to the client as plain text, not as HTML (which is the default). <% response.setContentType("text/plain"); %> It is important to note that you can set response headers or status codes at various places within a JSP page, even though this capability appears to violate the rule that this type of response data needs to be specified before any document content is sent to the client. Setting headers and status codes is permitted because servlets that result from JSP pages use a special type of PrintWriter (of the more specific class JspWriter) that buffers the document before sending it. This buffering behavior can be changed, how- ever; see Section 11.6 for a discussion of the autoflush attribute of the page directive. Special Scriptlet Syntax There are two special constructs you should take note of. First, if you want to use the characters %> inside a scriptlet, enter %\> instead. Second, the XML equivalent of <% Code %> is <jsp:scriptlet> Code </jsp:scriptlet> The two forms are treated identically by JSP engines. JSP Declarations A JSP declaration lets you define methods or fields that get inserted into the main body of the servlet class (outside of the _jspService method that is called by service to process the request). A declaration has the following form: <%! Java Code %> Since declarations do not generate any output, they are normally used in conjunction with JSP expressions or scriptlets. For example, here is a JSP fragment that prints the number of times the current page has been requested since the server was booted (or the servlet class was changed and reloaded). Recall that multiple client requests to the same servlet result only in multiple threads calling the service method of a single servlet instance. They do not result in the creation of multiple servlet instances except possibly when the servlet implements SingleThreadModel. For a discussion of Sin- gleThreadModel, see Section 2.6 (The Servlet Life Cycle) and Section 11.3 (The isThreadSafe Attribute). Thus, instance variables (fields) of a servlet are shared by multiple requests and accessCount does not have to be declared static below. <%! private int accessCount = 0; %> Accesses to page since server reboot: <%= ++accessCount %> JSP Page Directive: Structuring Generated XML JSP directive effects overall structure of the servlet that results from the JSP page. In JSP, there are three types of directives: page, include, and taglib. The page directive lets you control the structure of the servlet by importing classes, customizing the servlet superclass, setting the content type, and the like. A page directive can be placed anywhere within the document; its use is the topic of this chapter. The second directive, include, lets you insert a file into the servlet class at the time the JSP file is translated into a servlet. An include directive should be placed in the document at the point at which you want the file to be inserted; it is discussed in Chapter 12 (Including Files and Applets in JSP Documents) for inserting files into JSP pages. JSP 1.1 introduces a third directive, taglib, which can be used to define custom markup tags; it is discussed in Chapter 14 (Creating Custom JSP Tag Librar- ies). The page directive lets you define one or more of the following case-sen- sitive attributes: import, contentType, isThreadSafe, session, buffer, autoflush, extends, info, errorPage, isErrorPage, and language. These attributes are explained in the following sections. The import Attribute of page directive: lets you specify the packages that should be imported by the servlet into which the JSP page gets translated. If you don't explicitly specify any classes to import, the servlet imports java.lang.*, javax.servlet.*, javax.servlet.jsp.*, javax.servlet.http.*, and possibly some number of server-specific entries. <%@ page import="package.class" %> <%@ page import="package.class1,...,package.classN" %> The import attribute is the only page attribute that is allowed to appear multiple times within the same document. The contentType attribute The contentType attribute sets the Content-Type response header, indicat- ing the MIME type of the document being sent to the client. Unfortunately, this approach brings to light a small deficiency in the page directive: attribute values cannot be computed at run time, nor can page directives be conditionally inserted as can template text. So, the following attempt results in Excel content regardless of the result of the checkUser- Request method. <% boolean usingExcel = checkUserRequest(request); %> <% if (usingExcel) { %> <%@ page contentType="application/vnd.ms-excel" %> <% } %> Fortunately, there is a simple solution to the problem of conditionally set- ting the content type: just use scriptlets and the normal servlet approach of response.setContentType, as in the following snippet: <% String format = request.getParameter("format"); if ((format != null) && (format.equals("excel"))) { response.setContentType("application/vnd.ms-excel"); } %> The isThreadSafe Attribute The isThreadSafe attribute controls whether or not the servlet that results from the JSP page will implement the SingleThreadModel interface. Use of the isThreadSafe attribute takes one of the following two forms: <%@ page isThreadSafe="true" %> <%!-- Default --%> <%@ page isThreadSafe="false" %> With normal servlets, simultaneous user requests result in multiple threads concurrently accessing the service method of the same servlet instance. This behavior assumes that the servlet is thread safe; that is, that the servlet synchronizes access to data in its fields so that inconsistent values will not result from an unexpected ordering of thread execution. In some cases (such as page access counts), you may not care if two visitors occasionally get the same value, but in other cases (such as user IDs), identical values can spell disaster. For example, the following snippet is not thread safe since a thread could be preempted after reading idNum but before updating it, yield- ing two users with the same user ID. <%! private int idNum = 0; %> <% String userID = "userID" + idNum; out.println("Your ID is " + userID + "."); idNum = idNum + 1; %> The code should have used a synchronized block. This construct is written synchronized(someObject) { ... } and means that once a thread enters the block of code, no other thread can enter the same block (or any other block marked with the same object refer- ence) until the first thread exits. So, the previous snippet should have been written in the following manner. <%! private int idNum = 0; %> <% synchronized(this) { String userID = "userID" + idNum; out.println("Your ID is " + userID + "."); idNum = idNum + 1; } %> That's the normal servlet behavior: multiple simultaneous requests are dis- patched to multiple threads concurrently accessing the same servlet instance. However, if a servlet implements the SingleThreadModel interface, the sys- tem guarantees that there will not be simultaneous access to the same servlet instance. The system can satisfy this guarantee either by queuing up all requests and passing them to the same servlet instance or by creating a pool of instances, each of which handles a single request at a time. The Session Attribute The session attribute controls whether or not the page participates in HTTP sessions. Use of this attribute takes one of the following two forms: <%@ page session="true" %> <%-- Default --%> <%@ page session="false" %> A value of true (the default) indicates that the predefined variable ses- sion (of type HttpSession) should be bound to the existing session if one exists; otherwise, a new session should be created and bound to session. A value of false means that no sessions will be used automatically and attempts to access the variable session will result in errors at the time the JSP page is translated into a servlet. The buffer attribute The buffer attribute specifies the size of the buffer used by the out variable, which is of type JspWriter (a subclass of PrintWriter). Use of this attribute takes one of two forms: <%@ page buffer="sizekb" %> <%@ page buffer="none" %> Servers can use a larger buffer than you specify, but not a smaller one. For example, <%@ page buffer="32kb" %> means the document content should be buffered and not sent to the client until at least 32 kilobytes have been accumulated or the page is completed. The default buffer size is server specific, but must be at least 8 kilobytes. Be cautious about turning off buff- ering; doing so requires JSP entries that set headers or status codes to appear at the top of the file, before any HTML content. the autoFluch attribute The autoflush attribute controls whether the output buffer should be auto- matically flushed when it is full or whether an exception should be raised when the buffer overflows. Use of this attribute takes one of the following two forms: <%@ page autoflush="true" %> <%-- Default --%> <%@ page autoflush="false" %> A value of false is illegal when also using buffer="none". The extends Attribute The extends attribute indicates the superclass of the servlet that will be gen- erated for the JSP page and takes the following form: <%@ page extends="package.class" %> Use this attribute with extreme caution since the server may be using a custom superclass already. The errorPage Attribute The errorPage attribute specifies a JSP page that should process any excep- tions (i.e., something of type Throwable) thrown but not caught in the cur- rent page. It is used as follows: <%@ page errorPage="Relative URL" %> The exception thrown will be automatically available to the designated error page by means of the exception variable. See Listings 11.5 and 11.6 for examples. The isErrorPage Attribute The isErrorPage attribute indicates whether or not the current page can act as the error page for another JSP page. Use of isErrorPage takes one of the following two forms: <%@ page isErrorPage="true" %> <%@ page isErrorPage="false" %> <%!-- Default --%> The language Attribute At some point, the language attribute is intended to specify the underlying programming language being used, as below. <%@ page language="cobol" %> For now, don't bother with this attribute since java is both the default and the only legal choice. XML Syntax for Directives JSP permits you to use an alternative XML-compatible syntax for directives. These constructs take the following form: <jsp:directive.directiveType attribute="value" /> For example, the XML equivalent of <%@ page import="java.util.*" %> is <jsp:directive.page import="java.util.*" /> INCLUDING FILES AND APPLETS IN JSP DOCUMENTS TODO TODO TODO Including files at page translation time: You use the include directive to include a file in the main JSP document at the time the document is translated into a servlet (which is typically the first time it is accessed). The syntax is as follows: <%@ include file="Relative URL" %> There are two ramifications of the fact that the included file is inserted at page translation time, not at request time as with jsp:include (Section 12.2). Including Files at Request Time The include directive (Section 12.1) lets you include documents that con- tain JSP code into multiple different pages. Including JSP content is a useful capability, but the include directive requires you to update the modification date of the page whenever the included file changes, which is a significant inconvenience. The jsp:include action includes files at the time of the cli- ent request and thus does not require you to update the main file when an included file changes. On the other hand, the page has already been trans- lated into a servlet by request time, so the included files cannot contain JSP. Including Applets for the plug-in The jsp:plugin Element The simplest way to use jsp:plugin is to supply four attributes: type, code, width, and height. You supply a value of applet for the type attribute and use the other three attributes in exactly the same way as with the APPLET ele- ment, with two exceptions: the attribute names are case sensitive, and single or double quotes are always required around the attribute values. So, for example, you could replace <APPLET CODE="MyApplet.class" WIDTH=475 HEIGHT=350> </APPLET> with <jsp:plugin type="applet" code="MyApplet.class" width="475" height="350"> </jsp:plugin> The jsp:plugin element has a number of other optional attributes. Most, but not all, parallel attributes of the APPLET element. Here is a full list. The jsp:param and jsp:params Elements The jsp:param element is used with jsp:plugin in a manner similar to the way that PARAM is used with APPLET, specifying a name and value that are accessed from within the applet by getParameter. There are two main dif- ferences, however. First, since jsp:param follows XML syntax, attribute names must be lower case, attribute values must be enclosed in single or dou- ble quotes, and the element must end with />, not just >. Second, all jsp:param entries must be enclosed within a jsp:params element. So, for example, you would replace <APPLET CODE="MyApplet.class" WIDTH=475 HEIGHT=350> <PARAM NAME="PARAM1" VALUE="VALUE1"> <PARAM NAME="PARAM2" VALUE="VALUE2"> </APPLET> with <jsp:plugin type="applet" code="MyApplet.class" width="475" height="350"> <jsp:params> <jsp:param name="PARAM1" value="VALUE1" /> <jsp:param name="PARAM2" value="VALUE2" /> </jsp:params> </jsp:plugin> USING JAVABEANS WITH JSP Requirement for creating a JavaBean
The jsp:useBean action lets you load a bean to be used in the JSP page. Beans provide a very useful capability because they let you exploit the reus- ability of Java classes without sacrificing the convenience that JSP adds over servlets alone. The simplest syntax for specifying that a bean should be used is: <jsp:useBean id="name" class="package.Class" /> This usually means "instantiate an object of the class specified by Class, and bind it to a variable with the name specified by id." So, for example, the JSP action <jsp:useBean id="book1" class="coreservlets.Book" /> can normally be thought of as equivalent to the scriptlet <% coreservlets.Book book1 = new coreservlets.Book(); %> Rather than using the class attribute, you are permitted to use beanName instead. The difference is that beanName can refer either to a class or to a file containing a serialized bean object. The value of the beanName attribute is passed to the instantiate method of java.beans.Bean. In most cases, you want the local variable to have the same type as the object being created. In a few cases, however, you might want the variable to be declared to have a type that is a superclass of the actual bean type or is an interface that the bean implements. Use the type attribute to control this, as in the following example: <jsp:useBean id="thread1" class="MyClass" type="Runnable" /> This use results in code similar to the following being inserted into the _jspService method: Runnable thread1 = new MyClass(); Note that since jsp:useBean uses XML syntax, the format differs in three ways from HTML syntax: the attribute names are case sensitive, either single or double quotes can be used (but one or the other must be used), and the end of the tag is marked with />, not just >. The first two syntactic differ- ences apply to all JSP elements that look like jsp:xxx. The third difference applies unless the element is a container with a separate start and end tag. Accessing Bean Properties Once you have a bean, you can access its properties with jsp:getProperty, which takes a name attribute that should match the id given in jsp:useBean and a property attribute that names the property of interest. Alternatively, you could use a JSP expression and explicitly call a method on the object that has the variable name specified with the id attribute. For example, assuming that the Book class has a String property called title and that you've cre- ated an instance called book1 by using the jsp:useBean example just given, you could insert the value of the title property into the JSP page in either of the following two ways: <jsp:getProperty name="book1" property="title" /> <%= book1.getTitle() %> setting Bean Properties You normally use jsp:setProperty to set bean properties. The simplest form of this action takes three attributes: name (which should match the id given by jsp:useBean), property (the name of the property to change), and value (the new value). For example, the SaleEntry class shown in Listing 13.3 has an itemID property (a String), a numItems property (an int), a discountCode prop- erty (a double), and two read-only properties itemCost and totalCost (each of type double). Listing 13.4 shows a JSP file that builds an instance of the SaleEntry class by means of: <jsp:useBean id="entry" class="coreservlets.SaleEntry" /> The results are shown in Figure 132. Once the bean is instantiated, using an input parameter to set the itemID is straightforward, as shown below: <jsp:setProperty name="entry" property="itemID" value='<%= request.getParameter("itemID") %>' /> Notice that I used a JSP expression for the value parameter. Most JSP attribute values have to be fixed strings, but the value and name attributes of jsp:setProperty are permitted to be request-time expressions. If the expression uses double quotes internally, recall that single quotes can be used instead of double quotes around attribute values and that \' and \" can be used to represent single or double quotes within an attribute value. Setting the itemID property was easy since its value is a String. Setting the numItems and discountCode properties is a bit more problematic since their values must be numbers and getParameter returns a String. Here is the somewhat cumbersome code required to set numItems: <% int numItemsOrdered = 1; try { numItemsOrdered = Integer.parseInt(request.getParameter("numItems")); } catch(NumberFormatException nfe) {} %> <jsp:setProperty name="entry" property="numItems" value="<%= numItemsOrdered %>" /> Fortunately, JSP has a nice solution to this problem that lets you associate a property with a request parameter and that automatically performs type conversion from strings to numbers, characters, and boolean values. Instead of using the value attribute, you use param to name an input parameter. The value of this parameter is automatically used as the value of the property, and simple type conversions are performed automatically. If the specified input parameter is missing from the request, no action is taken (the system does not pass null to the associated property). So, for example, setting the numItems property can be simplified to: <jsp:setProperty name="entry" property="numItems" param="numItems" /> instead of value use param and provide the inpur parameter name as an argument. It does automatic type conversion. Associating All Properties with Input Parameters Associating a property with an input parameter saves you the bother of per- forming conversions for many of the simple built-in types. JSP lets you take the process one step further by associating all properties with identically named input parameters. All you have to do is to supply "*" for the prop- erty parameter. So, for example, all three of the jsp:setProperty state- ments of Listing 13.5 can be replaced by the following simple line. Listing 13.6 shows the complete page. <jsp:setProperty name="entry" property="*" /> Although this approach is simple, four small warnings are in order. First, as with individually associated properties, no action is taken when an input parameter is missing. In particular, the system does not supply null as the property value. Second, the JSWDK and the Java Web Server both fail for conversions to properties that expect double values. Third, automatic type conversion does not guard against illegal values as effectively as does manual type conversion. So you might consider error pages (see Sections 11.9 and 11.10) when using automatic type conversion. Fourth, since both property names and input parameters are case sensitive, the property name and input parameter must match exactly. Sharing Beans Up to this point, I have treated the objects that were created with jsp:use- Bean as though they were simply bound to local variables in the _jspService method (which is called by the service method of the servlet that is generated from the page). Although the beans are indeed bound to local variables, that is not the only behavior. They are also stored in one of four different locations, depending on the value of the optional scope attribute of jsp:useBean. The scope attribute has the following possible val- ues: page This is the default value. It indicates that, in addition to being bound to a local variable, the bean object should be placed in the PageContext object for the duration of the current request. In principle, storing the object there means that servlet code can access it by calling getAttribute on the predefined pageContext variable. In practice, beans created with page scope are almost always accessed by jsp:getProperty, jsp:setProperty, scriptlets, or expressions later in the same page. application This very useful value means that, in addition to being bound to a local variable, the bean will be stored in the shared ServletContext available through the predefined application variable or by a call to getServletContext(). The ServletContext is shared by all servlets in the same Web application (or all servlets in the same server or servlet engine if no explicit Web applications are defined). Values in the ServletContext can be retrieved by the getAttribute method. This sharing has a couple of ramifications. First, it provides a simple mechanism for multiple servlets and JSP pages to access the same object. See the following subsection (Conditional Bean Creation) for details and an example. Second, it lets a servlet create a bean that will be used in JSP pages, not just access one that was previously created. This approach lets a servlet handle complex user requests by setting up beans, storing them in the ServletContext, then forwarding the request to one of several possible JSP pages to present results appropriate to the request data. For details on this approach, see Chapter 15 (Integrating Servlets and JSP). session This value means that, in addition to being bound to a local variable, the bean will be stored in the HttpSession object associated with the current request, where it can be retrieved with getValue. Attempting to use scope="session" causes an error at page translation time when the page directive stipulates that the current page is not participating in sessions. (See Section 11.4, "The session Attribute.") request This value signifies that, in addition to being bound to a local variable, the bean object should be placed in the ServletRequest object for the duration of the current request, where it is available by means of the getAttribute method. This value is only a slight variation of the per-request scope provided by scope="page" (or by default when no scope is specified). Conditional Bean Creation: To make bean sharing more convenient, there are two situations where bean-related elements are evaluated conditionally. First, a jsp:useBean element results in a new bean being instantiated only if no bean with the same id and scope can be found. If a bean with the same id and scope is found, the preexisting bean is simply bound to the vari- able referenced by id. A typecast is performed if the preexisting bean is of a more specific type than the bean being declared, and a ClassCastExcep- tion results if this typecast is illegal. Second, instead of <jsp:useBean ... /> you can use <jsp:useBean ...> statements </jsp:useBean> The point of using the second form is that the statements between the jsp:useBean start and end tags are executed only if a new bean is created, not if an existing bean is used. This conditional execution is convenient for setting initial bean properties for beans that are shared by multiple pages. Since you don't know which page will be accessed first, you don't know which page should contain the initialization code. No problem: they can all contain the code, but only the page first accessed actually executes it. For example, Listing 13.7 shows a simple bean that can be used to record cumulative access counts to any of a set of related pages. It also stores the name of the first page that was accessed. Since there is no way to predict which page in a set will be accessed first, each page that uses the shared counter has state- ments like the following: <jsp:useBean id="counter" class="coreservlets.AccessCountBean" scope="application"> <jsp:setProperty name="counter" property="firstPage" value="Current Page Name" /> </jsp:useBean> Collectively, the pages using the counter have been accessed <jsp:getProperty name="counter" property="accessCount" /> times. Questions Q. What is the difference between the getRequestDispatcher(String path) method of javax.servlet.ServletRequest interface and javax.servlet.ServletContext interface? A: The getRequestDispatcher(String path) method of javax.servlet.ServletRequest interface accepts parameter the path to the resource to be included or forwarded to, which can be relative to the request of the calling servlet. If the path begins with a "/" it is interpreted as relative to the current context root.The getRequestDispatcher(String path) method of javax.servlet.ServletContext interface cannot accepts relative paths. All path must sart with a "/" and are interpreted as relative to curent context root. Q:Explain the directory structure of a web application. A: The directory structure of a web application consists of two parts. A private directory called WEB-INF A public resource directory which contains public resource folder. WEB-INF folder consists of 1. web.xml 2. classes directory 3. lib directory (what for ?) What is preinitialization of a servlet? A container doesnot initialize the servlets ass soon as it starts up, it initializes a servlet when it receives a request for that servlet first time. This is called lazy loading. The servlet specification defines the <load-on-startup> element, which can be specified in the deployment descriptor to make the servlet container load and initialize the servlet as soon as it starts up. The process of loading a servlet before any request comes in is called preloading or preinitializing a servlet What is the difference between Difference between doGet() and doPost()? A doGet() method is limited with 2k of data to be sent, and doPost() method doesn't have this limitation. A request string for doGet() looks like the following: http://www.allapplabs.com/svt1?p1=v1&p2=v2&...&pN=vN doPost() method call doesn't need a long text tail after a servlet name in a request. All parameters are stored in a request itself, not in a request string, and it's impossible to guess the data transmitted to a servlet only looking at a request string. What is the difference between ServletContext and ServletConfig? ServletContext: Defines a set of methods that a servlet uses to communicate with its servlet container, for example, to get the MIME type of a file, dispatch requests, or write to a log file.The ServletContext object is contained within the ServletConfig object, which the Web server provides the servlet when the servlet is initialized ServletConfig: The object created after a servlet is instantiated and its default constructor is read. It is created to pass initialization information to the servlet. What is a Expression? An expression tag contains a scripting language expression that is evaluated, converted to a String, and inserted where the expression appears in the JSP file. Because the value of an expression is converted to a String, you can use an expression within text in a JSP file. Like <%= someexpression %> <%= (new java.util.Date()).toLocaleString() %> You cannot use a semicolon to end an expression What is a Declaration? A declaration declares one or more variables or methods for use later in the JSP source file. A declaration must contain at least one complete declarative statement. You can declare any number of variables or methods within one declaration tag, as long as they are separated by semicolons. The declaration must be valid in the scripting language used in the JSP file. What is a Scriptlet? A scriptlet can contain any number of language statements, variable or method declarations, or expressions that are valid in the page scripting language.Within scriptlet tags, you can 1.Declare variables or methods to use later in the file (see also Declaration). Scriptlets are executed at request time, when the JSP engine processes the client request. If the scriptlet produces output, the output is stored in the out object, from which you can display it. What are implicit objects? List them? Certain objects that are available for the use in JSP documents without being declared first. These objects are parsed by the JSP engine and inserted into the generated servlet. The implicit objects re listed below
When you invoke a forward request, the request is sent to another resource on the server, without the client being informed that a different resource is going to process the request. This process occurs completly with in the web container. When a sendRedirtect method is invoked, it causes the web container to return to the browser indicating that a new URL should be requested. Because the browser issues a completly new request any object that are stored as request attributes before the redirect occurs will be lost. This extra round trip a redirect is slower than forward. What are the different scope valiues for the <jsp:useBean>? The different scope values for <jsp:useBean> are 1. page2. request 3.session 4.application Explain the life-cycle mehtods in JSP? THe generated servlet class for a JSP page implements the HttpJspPage interface of the javax.servlet.jsp package. Hte HttpJspPage interface extends the JspPage interface which inturn extends the Servlet interface of the javax.servlet package. the generated servlet class thus implements all the methods of the these three interfaces. The JspPage interface declares only two mehtods - jspInit() and jspDestroy() that must be implemented by all JSP pages regardless of the client-server protocol. However the JSP specification has provided the HttpJspPage interfaec specifically for the JSp pages serving HTTP requests. This interface declares one method _jspService(). The jspInit()- The container calls the jspInit() to initialize te servlet instance.It is called before any other method, and is called only once for a servlet instance. The _jspservice()- The container calls the _jspservice() for each request, passing it the request and the response objects. The jspDestroy()- The container calls this when it decides take the instance out of service. It is the last method called n the servlet instance. Can we call destroy() method on servlets from service method? How we can check in particular page the session will be alive or not? What is the importance of deployment descriptor in servlet? When we increase the buffer size in our project using page directive attribute ‘buffer’ what changes we observe? When a servlet accepts a call from a client, it receives two objects. What are they? What are the differences between GET and POST service methods? In which conditions we have to use the ServletContext? What methods will be called in which order?((i.e)service(),doget(),dopost()) Servlet is Java class. Then why there is no constructor in Servlet? Can we write the constructor in Servlet What information that the ServletRequest interface allows the servlet access to? When do you have action=get? Can a init(ServletConfig config) method be overrided in servlets? How many ServletConfig and servlet context objects are present in one application? How to communicate between two servlets? What is the difference between servlets and applets? What method used to add a jsp to the servlet? How will u pass the argument from one servlet to another servlet? How to get one Servlet’s Context Information in another Servlet? What is the super class of All servlets? Difference between single thread and multi thread model servlet? Types of Servlets? What is servlet context and what it takes actually as parameters? Why is that we deploy servlets in a webserver.What exactly is a webserver? Which code line must be set before any of the lines that use the PrintWriter? http://www.javaprepare.com/scwd/quests/servlet.html
In GET your entire form submission can be encapsulated in one URL, like a hyperlink. query length is limited to 260 characters, not secure, faster, quick and easy. In POST Your name/value pairs inside the body of the HTTP request, which makes for a cleaner URL and imposes no size limitations on the form's output. It is used to send a chunk of data to the server to be processed, more versatile, most secure.
The servlet mapping defines an association between a URL pattern and a servlet. The mapping is used to map requests to servlets.
Servlets are to servers; applets are to browsers. Unlike applets, however, servlets have no graphical user interface. |
|
| Last Updated ( Thursday, 31 July 2008 07:41 ) |