Servlets & JSP Series 8 - Script-free pages

Servlets & JSP Series 8 - Script-free pages

  • Standard action is related to JavaBean; Standard actions contains- 1.jsp:useBean; 2.jsp:getProperty; 3.jsp:setProperty; 4.jsp:include; 5.jsp:forward.
  • Declare and initialize a bean attribute with <jsp:useBean>; Get a bean attribute’s property value with <jsp:getProperty>.
  • <jsp:useBean> can also create a bean: if the <jsp:useBean> cannot find an attribute object, it can make one.
  • With a <jsp:useBean> body, you can have code that runs conditionally, only if the bean attrivute cannot be found and a new bean is created, the Property values will be set only if a new bean is created, if an existing bean with that scope and id are found, the body of the tag will never run, so the property will not be reset from your JSP code, any code inside the body of <jsp:useBean> is conditional, it runs only if the bean is not found and a new one is created.
  • When you write a <jsp:useBean>, the class attribute determines the class of the new object, it also determines the type of the reference variable used in the generated servlet, but if you want the reference type to be different from the actual object, you can change the Person class to make it abstract, and make a concrete subclass Employee, and in JSP, we you need to make the reference variable type Person, and the object an instance of class Employee.
  • If type is used without class, the beam must already exists in “page” scope; If class is used (with or without type) the class must not be abstract, and must have a public no-arg constructor.
  • The scope attribute defaults to “page”, if you do not specify a scope in either the <jsp:useBean> or <jsp:getProperty> tags, the Container uses the default of “page”.
  • Type == reference type; class== object type; type is what you declare (can be abstract); class is what you instantiate (must be concrete); type x = new class().
  • If going straight from the request to the JSP without going through a servlet, the param attribute lets you set the value of a bean property to the value of a request parameter, just by naming the request parameter.
  • If the request parameter name matched the bean property name, you do not need to specify a value in the <jsp:setProperty> tag for that property.
  • The <jsp:setProperty> action takes the String request parameter, converts it to an int and passes that int to the bean’s setter method for that property.
  • Automatic String-to-primitive conversion does not work if you use scripting, it fails even if an expression is inside the <jsp:setProperty> tag, if you use scripting, the automatic conversion does not work.
  • The bean standard action tags are more natural to a non-programmer.
  • EL make it easy to print nested properties, in other words, properties of properties.
  • EL expression are always within curly braces, and prefixed with the dollar sign ${firstThing.secondThing}, the first named variable in the expression is either an implicit object or an attribute.
  • The first variable is either an implicit object or an attribute, and the thing to the right of the dot is either a map key (if the first variable is a map) or a bean property if the first variable is an attribute that’s a JavaBean.
  • Example: ${person.name} – 1.if the expression has a variable followed by a dot, the left-hand variable must be a map or a bean; 2. The thing to the right of the dot must be a map key or a bean property; 3.and the thing on the right must follow normal Java naming rules for identifiers. When the variable is on the left side of the dot, it’s either a map or a bean, this is true regardless of whether the variable is an implicit object or an attribute, the pageContext implicit object is a bean-it has getter methods, all other implicit objects are maps, if the object is a bean but the named property does not exist, then an exception is thrown.
  • The [] operator is like the dot only way better, the dot operator works only when the thing on the right is a bean property or map key for the thing on the left, that’s it, but the [] operator is a lot more powerful and flexible - ${person[“name”]} is the same as ${person.name}.
  • If the expression has a variable followed by a bracket [], the left-hand variable can be a Map, a bean, a List, or an array; if the thing inside the brackets is a String literal, it can be a Map key or a bean property, or an index into a List or array.
  •   If the thing to the left of the bracket is an array or a List, and the index is a String literal, the index is coerced to an int, this would not work: ${favoriteFood[:one:]}, because “one” cannot be turned into an int, you will get an error if the index canot be coerced.
  • For JavaBeans and Maps, we can use either the [] operator or the convenient dot operator, just think if map keys the same way you think of property names in a bean, we ask for the key or property name, and we get back the value of the key or property.
  • The EL implicit objects: pageScope; requestScope; sessionScope; applicationScope; param; paramValues; header; headerValues; cookie; initParam; pageContext.
  • The header implicit object keeps a Map of all the headers, use either access operator to pass in the header name and the value of that header will print, note: there is also a headerValues implicit object for headers with multiple values, it works just like paramValues.
  • Scope maps are not the real object, the requestScope is not the request object, the implicit requestScope is just a Map of the request scope attributes, not eh request object itself.
  • Use requestScope to get request attributes, not request properties, for request properties, you need to go through pageContext. Pagecontext has a request property request has a method property.
  • Functions in EL: 1.Write a Java class with a public static method; 2.Write a Tag Library Descriptor (TLD) file; 3. Put a taglib derective in your JSP; 4.Use EL to invoke the function.
  • The class with the function (the public static method) must be available to the web appjust like servlet, bean, and listener classes, that means somewhere in WEB-INF/classes. Put the TLD file somewhere under WEB-INF, and make sure the taglib directive in the JSP includes a uri attribute that matches the <uri> element in the TLD.
  • EL is null-friendly, it handles unknown or null values so that the page still displays, even if it cannot find an attribute/property/key with the name in the expression, in arithmetic, EL treats the null value as “zero”, in logical expressions, EL treats the null value as “false”.
  • EL expressions are always within cruly braces, and prefixed with a dollar($) sign ${expression}.
  • The first named variable in the expression is either an implicit object or an attribute in one of the four scopes (page, request, session, or application).
  • The dot operator lets you access values by using a Map key or a bean property name, for example ${foo.bar} gives you the value of bar, where bar is the name of Map key into the Map foo, or bar is the property of bean foo, whatever comes to the right of the dot operator must follow normal Java naming rules for identifiers (in other words, must start with a letter, underscore, or dollar sign, can include numbers after the first character, but nothing else, etc).
  • We can never put anything to the right of the dot that would not be legal as a Java identifier, for example, we cannot say ${foo.1}.
  • The [] operator is more powerful than the dot, because it lets you access arrays and Lists, and we can put other expressions including named variables within the brackets, and we can nest them to any level we can stand.
  • For example, if musicList is an ArrayList, we can access the first value in the list by saying ${musicList[0]} or ${music[“0”]}, EL does not care if we put quotes around the list index.
  • If what is inside the brackets is not in quotes, the Container evaluates it, if it is in quotes, and it’s not an index into an array or List, the Container sees it and the literal name of a property or key.
  • All but one of the EL implicit objects are Maps, from the Map implicit objects we can get attributes from any of the four scopes, request, parameter values, header values, cookie values, and context init parameters, the no-map implicit object is pageContext, which is a reference to the pageContext object.
  • Do not confuse the implicit EL scope objects (Maps of the attributes) with the objects to which the attribute are bound, in other words, don’t confuse the requestScope implicit object with the actual JSP implicit request object, the only way to access the request object is by going through the pageContext implicit object(Although some of what you might want from the rquest is already available through other EL implicit objects, including param/paramValues, header/headerValues, and cookie).
  • EL functions allow you to call a public static method in a plain old Java class, the function name does not have to match the actual method name, for example, &{foo:rolllt()} does not mean that there must be a method named rolllt() in a class that has a function.
  • The function name is mapped to a real static method using TLD(Tag Library Descriptor) file, declare a function using the <function> element, including the <name> of the function, the full-qualified<function-class>, and the <function-signature> which include the return type as well as the method name and argument list.
  • To use a function in a JSP, you must declare the namespace using a taglib directive, put a prefix attribute in the taglib directive to tell the Container the TLD in which the function you are calling can be found, example:<% taglib prefix-“mine” uri=”/WEB-INF/foo.tld”>.
  • The include directive tells the Container one thing: copy everything in the included file and paste it into this file.
  • The <jsp:include> standard action appears to do the same thing as the include directive; the include directive just takes the contents of the first JSP file and places it into the new JSP page before it does the translation.
  • The include directive happens at translation time <jsp:include> happens at runtime; the include directive inserts the source of the JSP file, at translation time, but the <jsp:include/> standard action inserts the response of the JSP file, at runtime.
  • There’s an extra performance hit with every <jsp:invlude>, with the directive, on the other hand, the hit happens only once-when the including page is translated, so if you are pretty sure that once you go to production the included file will not change, the directive might be the way to go, of course there is still the tradeoff that the generated servlet class is a little larger when you use the directive.
  • With the include directive, the Container has a lot of work to do, but only on the first request, from the second request on, there is no extra runtime overhead.
  • The whole process of the include directive: 1.The client makes a request for Contact.jsp, which has not been translated, the Container read the Contact.jsp to start the translation process; 2.The container sees the include directive, and combines the source code of Header.jsp and Contact.jsp, and create/translate that into a Java source file for the generated servlet; 3.The Container compiles the translated source file into a servlet class, it’s just like any other servlet at this point, and the previous step never has to happen again, unless Contact.jsp changes(or, if your Container is smart and can tell that the included Header.jsp has changed); 4.To complete the request, the Container loads the newly-compiled class, initializes a servlet(instantiates the servlet then calls init() on the new object), allocates a thread for the request, and calls the _jspService() method, from the second request on, the Container does only step: allocates a thread and calls the _jspService() method.
  • With the include standard action, there is less work at translation time, and more work with each request, especially if the included file is a JSP.
  • The whole process of the <jsp:include> standard action: 1.The client makes a request for Contact.jsp, which has not been translated, the Container reads the Contact.jsp page to start the translation process; 2.The container sees the include standard action, and uses that to insert a method call in the generated servlet code that- at runtime-will dynamically combine the response from Header.jsp into the response from Contact.jsp, the Container generates servlet for both JSP files(This is not dictated by the spec, so we are showing only an example of how it could work); 3.The container compiles the translated source file into a servlet class, it’s just like any other servlet at this point, the generated servlet class file is loaded into the Container’s JVM and it initialized, next, the Container allocates a thread for the request and calls the JSP’s _jspService() method; 4.The Contact servlet hits the method that does the dynamic include, and something vendor-specific happens, all we care about is that the response generated by the Head servlet is combined with the response from the Contact servlet(at the appropriate place)(Not shown: at some point the Header.jsp is translated and compiled, then the generated servlet class is loaded and initialized).
  • The attribute names are different for the include directive and <jsp:include/>: The directive attribute is file but the standard action attribute is page, to help us remember, the include directive <%@ include file=”foo.jsp”%> is used only at translation time, and when translating, the Container cares only about files=.jsp to .java, and .java to .class; but the <jsp:include page=”foo.jsp”> standard action, as with all standard actions, is executed at request time, when the Container cares about pages to be executed.
  • The include directive is position-sensitive: it’s the only directive whose position is the JSP actually matters, with a page directive, for example, you can put it anywhere in the page, although by convention most people put page directives at the top; but the include directive tells the Container exactly where to insert the source from the included file.
  • Do not put opening and closing HTML and Body tags within your reusable pieces, design and write your layout template chunks(like headers, nav bars, etc.) assuming they will be included in some other page.
  • The usage of the <jsp:forward> standard action: you  can forward from on JSP to another, or from one JSP to a servlet, or from one JSP to any other resource in your web app.
  • With <jsp:forward>, the buffer is cleared before the forward, when a forward happens, the resource to which the request is forward starts with a clear response buffer, in other words, anything written to the response before the forward happens is thrown out. Nothing you write before the forward will appear if the forward happens.
  • The <jsp:useBean> standard action defines a variable that hoads a reference to either an existing bean attribute or, if the bean does not already exist, a new bean.
  • The <jsp:useBean> must have an “id” attribute which declares the variable name that will be used in this JSP to refer to the bean.
  • If you do not include a “scope” attribute with <jsp:useBean>, the scope defaults to page scope.
  • The “class” attribute is optional, and it declares the class type that will be used if a new bean is created, the type must be public, non-abstract, and have a public no-arg constructor.
  • If you put a “type” attribute in <jsp:useBean>, it must be a type to which the bean can be cast.
  • If you have a “type” attribute but do not have a “class” attribute, the bean must already exist, since you have not specified the class type that should be instantiated for the new bean.
  • The <jsp:useBean> tag can have a body, and anything in the body runs only if a new bean is created as a result of <jsp:useBean>(which means that no bean with that “id” was found in the specified(or default) scope).
  • The main purpose of the body of <jsp:useBean> is to set the new bean’s properties, using <jsp:setProperty>.
  • <jsp:setProperty> must have a name attribute (which will match the “id” from <jsp:useBean>), and a “property” attribute, the “property” attribute must be either an actual property name or the wildcard “*”.
  • If you do not include  a ”value” attribute, the Container will set the property value only if there is a request parameter with a name that matched the property name, if you use the wildcard (*) for the “property” attribute, the Container will set the value of all properties that have a matching request parameter name.
  • If the request parameter name is different from the property name but you want to set the value of the property equal to the request parameter value, you can use the “param” attribute in the <jsp:setProperty> tag.
  • The <jsp:setProperty> action uses introspect to match the “property” to a JavaBean setter method, if the property is “*”, then the JSP will iterate over all request parameters to set the JavaBean properties.
  • Property values can be String or primitives, and the <jsp:setProperty> standard action will do the conversions automatically.
  • You can build a page with reusable components using one of two include mechanisms – the include directive or the <jsp:include> standard action.
  • The include directive does the include at translation time, only once, so the include directive is considered the appropriate mechanism for including content that is not likely t change after deployment.
  •   The include directive essentially copies everything from within the included file and pastes it into the page with the include, the Container combines all the included files and compliles just one file for the generated servlet, at runtime, the page with the include runs exactly as though you had typed all the source into one file yourself.
  • The <jsp:include> standard action includes the response of the included page into the original page at runtime, so the include standard action is considered appropriate for including content that may be updated after deployment, while the include directive is not.
  • Either mechanism can include dynamic elements (JSP code with EL expressions, for example) as well as static HTML pages.
  • The include directive is the only position-sensitive directive, the included content is inserted into the page at the exact location of the directive.
  • The attribute for the include directive and the include standard action are inconsistently named – directive uses “file” as the attribute while the standard action uses a “page attribute”.
  • In your reusable components, be sure to strip out the opening and closing tags, otherwise, the generated output will have nested opening and closing tags, which not all browsers can handle, design and construct you reusable pieces knowing that they will be included/inserted into something else.
  • You can customize an included file by setting a request parameter using the <jsp:param> standard action inside the body of a <jsp:include>.
  • We did not show it in this chapter, but the <jsp:param> can be used inside the body of a <jsp:forward> tag as well.
  •   The only places where a <jsp:param> makes sense are within a <jsp:include> or a <jsp:forward> standard action.
  • If the param name used in <jsp:param> already has a value as a request parameter, the new value will overwrite the previous one, otherwise, a new request parameter is added to the request.
  • The include resource has some limitations: it cannot change the response status code or set headers.
  • The <jsp:forward> standard action forwards the request to another resource from the same web app.
  • When a forward happens, the response buffer is cleared first, the resource to which the request was forwarded gets to start with a clean output, so anything written to the response before the forward will be thrown away.
  • If you commit the response before the forward, the client will be set whatever was flushed, but that’s it, the forward won’t happen, and the rest of the original page won’t be processed.

猜你喜欢

转载自kayonlife.iteye.com/blog/1985654
今日推荐