Survey
* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project
* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project
10 fake-points (which aren’t worth anything) to whoever: 1) spots the quote in this slide and names its source 2) Figures out why the container we use is named Apache Tomcat JSP – Java Server Pages: The Gory Details 1 Using External Parameters 2 JSP Initial Parameters • Like Servlets, initialization parameters can be passed to JSP files using the <servlet> element of the application configuration file web.xml • Use the sub-element <jsp-file> instead of the subelement <servlet-class> • Since a <servlet> element is being used, a <servletmapping> element is also needed - Use the real JSP URL as the <jsp-file> - Remember that just like in servlets mapping, you have the flexibility of being able to map several URLs to the same jsp or servlet, each with different init parameters. 3 An Example Application scoped initialization parameters (we haven’t discussed these, but by now you can guess what they do and web.xml what they’re good for…) <web-app> <context-param> <param-name>dbLogin</param-name> <param-value>snoopy</param-value> </context-param> <context-param> <param-name>dbPassword</param-name> <param-value>snoopass</param-value> </context-param> 4 web.xml <servlet> <servlet-name>ParamPage</servlet-name> In the case of JSP, <jsp-file>/paramPage.jsp</jsp-file> the relative location of the JSP <init-param> (relative to the JSP <param-name>tableName</param-name> application’s root scoped directory) should initialization <param-value>users</param-value> be given instead of parameters the Servlet </init-param> classname since </servlet> the Servlet is created from it by <servlet-mapping> the container. <servlet-name>ParamPage</servlet-name> <url-pattern>/paramPage.jsp</url-pattern> </servlet-mapping> You can also map a different URL to this JSP (highly useful if you need the URL to </web-app> end with an extension other than .jsp) 5 paramPage.jsp <html> <head><title>JSP initial parameters</title></head> You can omit the config and call getInitParameter() <body> directly, since the generated servlet extends HttpJspBase which extends HttpServlet which <h1>Hello</h1> implements the ServletConfig interface <h2>I should use the table <i><%= config.getInitParameter("tableName") %></i> JSP scoped initialization parameters </h2> <h2>To access the Database, I should use the login <i><%= application.getInitParameter("dbLogin") %></i> and the password Application scoped initialization parameters <i><%= application.getInitParameter("dbPassword") %></i>. </h2> Reminder: within a JSP this is Equivalent to </body> getServletContext().getInitParameter() within a Servlet </html> 6 Interacting with other Resources 7 JSP Cooperation • We will consider several ways in which JSP and other resources cooperate - Forwarding the request handling to other resources - Including the content of other sources - Including the code of other JSP files - Forwarding exception handling to other JSPs 8 Actions • JSP actions use constructs in XML syntax to control the behavior of the Servlet engine • Using actions, you can - forward the request to another resource in the application - dynamically include a resource content in the response A Quick Reference to JSP Elements 9 The forward Action • jsp:forward - Forwards the requester to a new resource <jsp:forward page="{relativeURL|<%= expression %>}"> <jsp:param name="parameterName" value="{parameterValue | <%= expression %>}" /> * </jsp:forward> You can use %=, % instead of <%=, %> so that the code would be a legal XML 0 or more parameters (not attributes!) added to the original request parameters • Can you write down the code this translates to? - Hint: Recall RequestDispatcher from last week The forward action 10 Forward Action Example <%! int even = 0; %> <% even = (1 - even); %> <% if (even == 0) { %> <jsp:forward page="/requestParams.jsp" > <jsp:param name="sessionID" value="<%= session.getId() %>" /> <jsp:param name="even" value="true" /> </jsp:forward> <% } else { %> <jsp:forward page="/requestParams.jsp" > <jsp:param name="sessionID" value="<%= session.getId() %>" /> <jsp:param name="even" value="false" /> </jsp:forward> <% } %> forward.jsp 11 <html> <head><title>Print Request Params</title></head> <body> <%@ page import="java.util.*" %> <% Enumeration parameterNames = request.getParameterNames(); %> <% while (parameterNames.hasMoreElements()) { %> <% String name = (String)parameterNames.nextElement(); %> <h2><%= name %> : <%= request.getParameter(name) %> </h2> <% } %> </body> requestParams.jsp </html> Open /forward.jsp?year=2006 12 The include Action • jsp:include - Include a resource content at run time <jsp:include page="{relativeURL|<%= expression %>}"> <jsp:param name="parameterName" value="{parameterValue | <%= expression %>}" />* </jsp:include> 0 or more parameters added to the original request parameters • This action is also translated to an invocation of the RequestDispatcher The include action 13 Include Action Example <html> <head> <title>Include (action) Example</title> </head> <body> <h2>Included part begins:<h2><hr/> <jsp:include page="/requestParams2.jsp" > <jsp:param name="sessionID" value="<%= session.getId() %>" /> </jsp:include> <hr/><h2>Included part ends<h2> </body> include.jsp </html> 14 <%@ page import="java.util.*" %> <% Enumeration parameterNames = request.getParameterNames(); %> <% while (parameterNames.hasMoreElements()) { %> <% String name = (String)parameterNames.nextElement(); %> <h2><%= name %> : <%= request.getParameter(name) %> </h2> <% } %> requestParams2.jsp The html tags were removed. Otherwise the main JSP output HTML code would have 2 html elements for example… Open /include.jsp?year=2006 15 The include Directive • This directive lets you include files at the time the JSP page is translated into a Servlet • The directive looks like this: <%@ include file="url" %> • Included JSP content can affect main JSP page - e.g. included page directive can affect the result ContentType • As of Tomcat 5.x, generated Servlets are updated when included files change (unlike older versions...) The include directive 16 Main JSP Include - Action Using RequestDispatcher File1.jsp HTML content Servlet1 HTML content File2.jsp Servlet2 HTML content 17 Include Directive File1.jsp File2.jsp Servlet HTML content 18 include Action vs. Directive • When a resource is included using the include action, the generated Servlet uses the dispatcher to include its content at runtime (so the resource needs not be a JSP or even a Servlet) • When a file is included using the include directive, the file itself is included verbatim into the JSP code, prior to the Servlet generation (so the included resource must have JSP syntax) • In which of the above cases can the included resouce change the HTTP headers or status? Compare the results of includeaction.jsp, includedirective.jsp 19 BlaBla.jsp <html> <head><title>Including JSP</title></head><body> <h2>Here is an interesting page.</h2> <p>Bla, Bla, Bla, Bla.</p> <%@ include file="/AccessCount.jsp" %> <jsp:include page="/dbimail.jsp"/> </body></html> AccessCount.jsp <%! private int accessCount = 0; %> <hr><p>Accesses to page since Servlet init: <%= ++accessCount %></p> dbimail.jsp <hr><p> Page Created for Dbi Course at <%= new java.util.Date() %>. Email us <a href="mailto:[email protected]">here</a>. </p> 20 BlaBla_jsp.java out.write("<html>\r\n"); out.write(" <head><title>Including JSP</title></head>\r\n"); out.write(" <body>\r\n"); out.write(" <h2>Here is an interesting page.</h2>\r\n"); out.write(" <p>Bla, Bla, Bla, Bla.</p>\r\n"); Original JSP out.write("<hr>\r\n"); out.write("<p> \r\n"); out.write(" Accesses to page since Servlet init: \r\n"); out.print( ++accessCount ); Included JSP out.write("</p>\r\n"); org.apache.jasper.runtime.JspRuntimeLibrary. include(request, response, "/dbimail.jsp", out, false); out.write(" </body>\r\n"); Similar to out.write("</html>\r\n"); RequestDispatcher().include() Original JSP 21 Directive Included Counter • Suppose that the file BlaBla2.jsp is similar the BlaBla.jsp • How will the counter of BlaBla2.jsp act? Why? - Will it be identical to the 1st counter or not? • What if we used a JSP action instead of a JSP directive for the counter? - Will it be identical to the 1st counter or not? Why? 22 Error Pages • We can set one JSP page to be the handler of uncaught exceptions of another JSP page, using JSP directives - The default behaviour is displaying a 500 Internal Server Error with a partial stack trace with other exception info to the client (ugly and a security risk). - You can log the entire stack trace along with other data for easier debugging • <%@ page errorPage="url " %> Runtime exceptions or other exceptions which are declared as thrown by methods your JSP code use. Other exceptions cannot be thrown or else your generated servlet code wouldn’t compile - Defines a JSP page that handles uncaught exceptions - The page in url should have true in the page-directive: • <%@ page isErrorPage="true|false" %> - The variable exception holds the exception thrown by the calling JSP Creating an error page without isErrorPage=true, is legal but the exception object is not created in the generated Servlet. 23 If you refer to exception in such a JSP, you’ll have a compilation error… connect.jsp <html> <head><title>Reading From Database </title></head> Reminder: <body> • The driver is loaded <%@ page import="java.sql.*" %> dynamically an instance <%@ page errorPage="errorPage.jsp" %> •ofCreates itself • Register this <% instance with the Class.forName("org.postgresql.Driver"); DriverManager Connection con = DriverManager.getConnection ("jdbc:postgresql://dbserver/public?user=" + "snoopy"); %> <h2>Can Connect!!</h2> </body> </html> 24 errorPage.jsp <html> <head><title>Connection Error</title></head> <body> <%@ page import="java.io.*" %> <%@ page isErrorPage="true" %> <h1>Oops. There was an error when you accessed the database.</h1> <h2>Here is the stack trace:</h2> <pre style="color:red"> <% exception.printStackTrace(new PrintWriter(out)); %> </pre> A method of any exception object (and not a JSP special method) that prints the stack trace into a given PrintWriter. </body> In our case, the PrintWriter is the out implicit object. </html> If you want to sleep better at night, flush the PrintWriter before continuing (why, if we aren’t using out anymore?) 25 This is the result you’ll see if the server can find the driver package, and connect to the database using the driver created with user=snoopy 26 This is the result you’ll see if the server can find the driver package, but fails to connect to the database using the driver created with user=snoopy Check the result of calling connect2.jsp which raises an exception after trying to load a non-existing class This time the error page is errorPage2.jsp in which isErrorPage=true is missing… 27 Custom JSP Tags 28 Custom JSP Tags • JSP code may use custom tags – tags that are defined and implemented by the programmer • The programmer defines how each of the custom tags is translated into Java code • There are two methods to define custom tags: - Tag libraries - used in old versions of JSP - Tag files - much simpler, introduced in JSP 2.0 29 Tag Libraries • A tag library consists of: - Tag handlers - Java classes that define how each of the new tags is translated into Java code - A TLD (Tag Library Descriptor) file, which is an XML file that defines the structure and the implementing class of each tag Tag Libraries tutorial The taglib directive 30 A Simple TagLib Example • Goal: <dbitag:date/> The java file is placed in webapps/dbi/WEB-INF/src/dbi/ We must use a package (not necessarily named like your application) since this is a helper class which is imported form the JSP’s generated Servlet that is placed within a named package The class file is placed in webapps/dbi/WEB-INF/classes/dbi/ DateTag.java package dbi; Base class of import javax.servlet.jsp.JspException; tags which import javax.servlet.jsp.tagext.SimpleTagSupport; don’t handle the body or the import java.io.IOException; attributes public class DateTag extends SimpleTagSupport { public void doTag() throws JspException, IOException { getJspContext().getOut().print(new java.util.Date()); Using the JSP-context, You can } also acquire other implicit objects by calling getSession(), Read more about } SimpleTagSupport Class 31 getRequest() etc… Set this value that indicates your tag library version <taglib> <tlib-version>1.0</tlib-version><jsp-version>2.0</jsp-version> <tag> <name>date</name> Name of the tag Tag’s class file in /dbi/WEB-INF/classes/dbi/ <tagclass>dbi.DateTag</tagclass> This defined tag contains <body-content>empty</body-content> no body The prefix for this tag must appear </tag> You can add before the tag itself (looks like a here more namespace). </taglib> dbi-taglib.tld tags… The Prefix can’t be empty <%@ taglib prefix="dbitag" uri="/WEB-INF/tags/dbi-taglib.tld" %> <html><body> <h1>Hello. The time is: <dbitag:date/></h1> </body></html> The path could be a URL. If you choose to use a local path, it must begin with /WEB-INF/tags/ As you can see from the path, the taglib is taglibuse.jsp specifically defined to the current application context. 32 Taglib with Attributes package dbi; import javax.servlet.jsp.JspException; import javax.servlet.jsp.tagext.TagSupport; import java.io.IOException; public class DateTag2 extends TagSupport { private boolean isLongFormat = false; The setter/getter methods should be named after the attribute (i.e. “get” + capital (<attribute>)) This member’s name should be identical to the attribute’s. public void setIsLongFormat(boolean b) { isLongFormat = b; } public boolean getIsLongFormat() { return isLongFormat; { Base class of tags which do handle attributes In our example the attribute is defined as not required so it must have a default value Attribute’s setter method Attribute’s getter method DateTag2.java 33 public int doStartTag() throws JspException { Invoked when the generated Servlet starts processing the “start tag” try { if (isLongFormat) { pageContext.getOut().print(new java.util.Date().getTime()); } else { pageContext.getOut().print(new java.util.Date()); } } Prints the date according to the isLongFormat attribute catch (Exception e) { throw new JspException("DateTag: " + e.getMessage()); } return SKIP_BODY; } Signals the generated Servlet public int doEndTag() { return EVAL_PAGE; } the generated Servlet to } Signals continue executing the generated Servlet code there’s no body within the tag to process Invoked when the generated Servlet starts processing the “end tag” Read more about TagSupport Class 34 <tag> <name>date2</name> <tagclass>dbi.DateTag2</tagclass> <body-content>empty</body-content> Same as before, only with different names for the tag,class You can put several blocks one after another <attribute> <name>isLongFormat</name> <required>false</required> </attribute> </tag> The attribute is “not required” so you have to define a default value in DateTag2.java dbi-taglib2.tld <%@ taglib prefix="dbitag" uri="/WEB-INF/tags/dbi-taglib2.tld" %> <html><body> Uses default attribute value <h1>Hello.</h1> <h2>The time is: <dbitag:date2/></h2> <h2>Milliseconds since the epoch : <dbitag:date2 isLongFormat="true" /></h2> </body></html> Uses a given attribute value taglibuse2.jsp 35 How does it work? taglibuse2_jsp.java Create the JspContext taglibuse2.jsp JSP to Java Servlet translation The attribute value is set using the setter method. The translator actually translated the attribute string value as it appears in the JSP source, to a boolean value as the Java tag class expects it… When the translation engine first encounters <dbitag:date2> it creates a new instance of DateTag2 (so we needn’t worry about concurrency issues) and passes it the JspContext reference “Start tag” is reached JspContext DateTag2 setIsLongFormat() doStartTag() doEndTag() “End tag” is reached 36 Tag Files • JSP 2.0 provides an extremely simplified way of defining tags • The movitation: JSP programmers don’t like writing cumbersome code or class files. • The idea: for each custom tag, write a tag file tagName.tag that implements the tag translation using JSP code • This way, the programmer can avoid creating tag handlers and TLD files 37 The Simplified Example <%= new java.util.Date() %> date.tag <%@ taglib prefix="dbitag" tagdir="/WEB-INF/tags/" %> <html> <body> In this new mechanism we use tagdir instead of uri we used in the old taglib implementation <h1>Hello. The time is: <dbitag:date/></h1> </body> </html> taguse.jsp 38 The Attributes Example A new directive <%@ attribute name="isLongFormat" required="false" %> date3.tag <%!private String createDate(String isLong) { Default and Private method isLongFormat=“false” declaration case if ((isLong == null) || (isLong.equals("false"))) { return new java.util.Date().toString();} else { return new Long(new java.util.Date().getTime()).toString();} } %> <%=createDate(isLongFormat)%> Calls the private method isLongFormat=“true” case The isLongFormat parameter is identified as the isLongFormat attribute because we used the attribute directive <%@ taglib prefix="dbitag" tagdir="/WEB-INF/tags/" %> <html><body> Default case <h1>Hello.</h1> <h2>The time is: <dbitag:date3/></h2> <h2>Milliseconds since the epoch : <dbitag:date3 isLongFormat="true" /></h2> </body></html> isLongFormat=“true” taguse3.jsp 39 Other Capabilities of Custom Tags • Attributes - You can add validation mechanism for the attributes values • Tag Body - Tag translation may choose to ignore, include or change the tag body 40 Java Beans in JSP Read more about JavaBeans The useBean action The setProperty action The getProperty action 41 Motivation • Software components (e.g. objects, data structures, primitives) are extensively used in Web applications • For example: - Service local variables - Attributes forwarded in requests - Session attributes, like users information - Application attributes, like access counters 42 Motivation • Standard actions are used to manipulate components: declaration, reading from the suitable context, setting of new values (according to input parameters), storing inside the suitable context, etc. • Java Beans provide a specification for automatic handling and manipulation of software components in JSP (and other technologies...) 43 Java Beans: The Idea • Java Beans are simply objects of classes that follow some (natural) coding convention: - An empty constructor - A readable property has a matching getter - A writable property has a matching setter • Use JSP actions to access and manipulate the bean, and special action attributes to specify the properties of the bean, like its scope • JSP programmers don’t like writing cumbersome code or class files. 44 Example 1: Access Counter In the following example, we use a Bean to maintain an access counter for requests to the pages 45 Bean must reside in a package Counter Bean package dbi; public class CounterBean { A Bean is a concept and therefore there’s no need to extend any class or implement any interface! (though it would’ve been very Java-ish to create an empty interface “Bean”) A Bean is created by an empty constructor private int counter; public CounterBean() { counter = 0; } public int getCounter() { return counter; } public void setCounter(int i) { counter = i; } Counter setter and getter public void increment() { ++counter; } } Other methods can be implemented as well CounterBean.java 46 <html> <head><title>Bean Example</title></head><body> <jsp:useBean id="accessCounter" class="dbi.CounterBean" scope="application"/> You could also use the type attribute in order to instantiate a data type which is either superclass of class or an interface that class implements <% accessCounter.increment(); %> <h1> Welcome to Page A</h1> <h2>Accesses to this application: The default scope is page An instance named according to the given id is either found in the right scope or created. Any tags inside <jsp:useBean> will be executed on instantiation only (but not if the instance is already an attribute of the right scope) <jsp:getProperty name="accessCounter" property="counter"/> </h2> <a href="pageB.jsp">Page B</a></body> </html> Invokes getCounter() pageA.jsp 47 <html> <head><title>Bean Example</title></head><body> <jsp:useBean id="accessCounter" class="dbi.CounterBean" scope="application"/> <% accessCounter.increment(); %> Since an instance named according to the given id can be found in the application scope, no instantiation takes place <h1> Welcome to Page B</h1> <h2>Accesses to this application: <jsp:getProperty name="accessCounter" property="counter"/> </h2> pageB.jsp <a href="pageA.jsp">Page A</a></body> </html> A very similar JSP 48 From the Generated Servlet dbi.CounterBean accessCounter = null; synchronized (application) { The instance is created and kept in the application’s scope as required. Note however that accessing this instance is out of the synchronized scope accessCounter = (dbi.CounterBean) _jspx_page_context.getAttribute("accessCounter", PageContext.APPLICATION_SCOPE); Similar effect to if (accessCounter == null) { getServletContext().getAttribute() accessCounter = new dbi.CounterBean(); _jspx_page_context.setAttribute("accessCounter", accessCounter, PageContext.APPLICATION_SCOPE); } } Similar effect to getServletContext().setAttribute() 49 Example 2: Session Data In the following example, we use a Bean in order to keep a user's details throughout the session 50 package dbi; public class UserInfoBean { private String firstName; private String lastName; public UserInfoBean() { firstName = lastName = null;} public String getFirstName() {return firstName;} public String getLastName() { return lastName;} public void setFirstName(String string) {firstName = string;} public void setLastName(String string) {lastName = string;} } UserInfoBean.java 51 <html> <head><title>Information Form</title></head> <body> <h1>Fill in your details:</h1> <form action="infoA.jsp" method="get"><p> Your First Name: <input type="text" name="firstName" /> <br/> Your Last Name: <input type="text" name="lastName" /><br/> <input type="submit" /></p> </form> </body></html> infoForm.html 52 <jsp:useBean id="userInfo" class="dbi.UserInfoBean" scope="session"/> <jsp:setProperty name="userInfo" property="*"/> <html> The String values are converted to the right bean’s property types.. Match all the request parameters to corresponding properties. You could match parameters to properties explicitly using property=… param=… <head><title>Page A</title></head><body> <h1>Hello You can also set properties with explicit values using property=… value=… <jsp:getProperty name="userInfo" property="firstName"/> <jsp:getProperty name="userInfo" property="lastName"/>, </h1> <h1>Have a nice session!</h1> <h2> <a href="infoB.jsp">User Info B</a></h2> </body></html> infoA.jsp 53 <jsp:useBean id="userInfo" class="dbi.UserInfoBean" scope="session"/> <jsp:setProperty name="userInfo" property="*"/> <html> This time the request has no parameters so no bean properties are set <head><title>Page B</title></head><body> <h1>Hello <jsp:getProperty name="userInfo" property="firstName"/> <jsp:getProperty name="userInfo" property="lastName"/>, </h1> A very similar JSP <h1>Have a nice session!</h1> <h2> <a href="infoA.jsp">User Info A</a></h2> </body></html> infoB.jsp 54 Advantages of Java Beans • Easy and standard management of data - Automatic management of bean sharing and lots more • Good programming style - Allow standard but not direct access to members - You can add code to the setters and getters (e.g. constraint checks) without changing the client code - You can change the internal representation of the data without changing the client code • Increase of separation between business logic (written by programmers) and HTML (written by GUI artists) 55 JSP Expression Language Read more about JSP EL 56 JSP Expression Language • JSP expression language is a comfortable tool to access useful objects in JSP • This language provides shortcuts in a somewhat JavaScript-like syntax • An expression in EL is written as ${expr} • For example: Hi, ${user}. <em style="${style}">Welcome</em> Note that the EL expression does not violate the XML syntax as opposed to <%= expression %> 57 EL Variables • JSP EL does not recognize JSP's implicit objects, but rather has its own set • Each of these objects maps names to values Maps a cooki e name to a single value Map a parameter name to a single value or to multiple values param, paramValues, header ,headerValues, Map a header name to a single value or to multiple values cookie, Maps a context initialization initParam, parameter name to a single value pageScope, requestScope, sessionScope, applicationScope Variables belonging to the different scopes. Now is a good time to make sure you remember they exist and what they mean… • For example, use the param[“x”] or param.x to get the value of the parameter x 58 EL Variables (cont) • A variable that is not an EL implicit object is looked up at the page, request, session (if valid) and application scopes • That is, x is evaluated as the first non null element obtained by executing pageContext.getAttribute("x"), request.getAttribute("x"), etc. • Might be confusing. Make sure you know what you’re accessing! 59 Object Properties • In JSP EL, Property prop of Object o is referred to as o[prop] • Property prop of Object o is evaluated as follows: - If o is a Map object, then o.get(prop) is returned - If o is a List or an array, then prop is converted into an integer and o.get(prop) or o[prop] is returned - Otherwise, treat o “as a bean”, that is: convert p to a string, and return the corresponding getter of o, that is o.getProp() • The term o.p is equivalent to o["p"] 60 An Example <% response.addCookie(new Cookie("course","dbi")); session.setAttribute("dbiurl",new java.net.URL("http://www.cs.huji.ac.il/~dbi/index.html")); String[] strs = {"str1","str2"}; session.setAttribute("arr", strs); %> <html><head><title>JSP Expressions</title></head><body> <form method="get" action="el.jsp"> <h2>Write the parameter x: <input name="x" type="text" /> <input type="submit" value="send" /></h2> </form> </body></html> elcall.jsp 61 <%@ page isELIgnored="false" %> The default value is TRUE <html> <head><title>EL Examples</title></head> <h1>Expression-Language Examples</h1> ${…} means evaluate the expression inside the {} <h2>Parameter <code>x</code>: ${param["x"]} </h2> <h2>Cookie <code>course</code>: ${cookie.course.value}</h2> cookie[“course”].getValue() <h2>Header <code>Connection</code>: header [“Connection”] ${header.Connection} </h2> sessionScope[“dbiurl”]. <h2>Path of session attr. <code>dbiurl</code>: getPath(). You can omit the sessionScope ${sessionScope.dbiurl.path}</h2> <h2>Element <code>arr[${param.x}]</code>: ${arr[param.x]} </h2> </body></html> Only the ${param.x} is evaluated sessionScope[“arr”][param[“x”] el.jsp62 JSP and XML 63 Simple XML Production Ordinary XML declarations Link with XSL stylesheet <?xml version="1.0"?> <!DOCTYPE colors SYSTEM "colors.dtd"> <?xml-stylesheet type="text/xsl" href="colors.xsl"?> <%! static String[] colors = {"red","blue","green"}; %> <%@ page contentType="text/xml" %> JSP directive which <colors> sets the MIME-type of the result… <% for(int i=0; i<3; ++i) { %> <color id="<%=i%>"><%= colors[i] %></color> <% } %> Open colors.jsp Check the result of the same JSP without the page </colors> contentType directive 64 Generated XML <?xml version="1.0"?> <!DOCTYPE colors SYSTEM "colors.dtd"> <?xml-stylesheet type="text/xsl" href="colors.xsl"?> <colors> <color id="0">red</color> <color id="1">blue</color> <color id="2">green</color> </colors> 65 JSPX Files (JSP Documents) • JSPX files are JSP files that have the extension jspx and have XML syntax • JSPX files are also referred to as JSP documents • Special JSP tags are used to replace non-XML JSP symbols (<%, <%@, etc.) (Tags and EL can help too!) • The default content type of JSPX is text/xml (and not text/html) • You can also keep the .jsp suffix and tell the container that a JSP file acts as a JSPX file (and therefore its output is of XML type etc.) Sun JSP Documents Tutorial 66 Advantages/Disadvantages of JSPX • Since JSPX documents conform to a legal XML structure you can: - Check if the document is well formed XML - Validate the document against a DTD - Nest and scope namespaces within the document - Use all kinds of XML tools (e.g. editors) • The main disadvantage is JSPX documents they can grow very long and very (very) cumbersome (as will soon become apparent). • Much ado about nothing? sometimes the above “advantages” simple aren’t needed or are of little help. 67 <%= Expression %> <jsp:expression> Expression </jsp:expression> <% Code %> <jsp:scriptlet> Code </jsp:scriptlet> <%! Declaration %> <jsp:declaration> Declaration </jsp:declaration> An empty element <%@ Directive %> <jsp:directive.type Attribute="value"/> 68 Problems on the way to a legal XML • The XML declaration (<?xml version="1.0"?>) and the DOCTYPE definition are now those of the JSPX file. - How do we include the declaration+dtd of the original XML document in the result XML? - Solution: use the <jsp:output> tag to explicitly require DOCTYPE and XML declarations (next slide…) • How do we generate dynamic attribute values and still keep the document well formed? The following line is an illegal XML opening tag: <color id=“<jsp:expression>i</jsp:expression>“> - Solution 1: use <jsp:element> for explicit element construction - Solution 2: use an EL expression 69 Namespace of basic JSP elements and Tag libraries.. <?xml version=“1.0” ?> <colors xmlns:jsp="http://java.sun.com/JSP/Page"> <jsp:output doctype-root-element="colors" Root element + DTD of the resulting XML doctype-system="colors.dtd" /> <jsp:output omit-xml-declaration="false"/> <jsp:declaration> Do not omit the XML declaration of the result static String[] colors = {"red","blue","green"};</jsp:declaration> <jsp:scriptlet><![CDATA[ for(int i=0; i<3; ++i) { ]]></jsp:scriptlet> CDATA is <jsp:element name="color"> used because <jsp:attribute name="id"> of <. <jsp:expression>i</jsp:expression> Altenatively: </jsp:attribute> use < <jsp:expression>colors[i]</jsp:expression> </jsp:element> The result is equivalent to the original line: <jsp:scriptlet>} <color id="<%=i%>"><%= colors[i] %></color> </jsp:scriptlet> Open colors.jspx, result of the same JSP with 70 omit-xml-declaration=true (omittruecolors.jspx) </colors> A few more problems on the way… • Where can we add an XSL declaration? it should both be: - outside the root element (colors) - after jsp:output which must be defined after jsp namespace declaration within the colors element… • When using the include directive, the JSP might become illegal XML with more than a single root. • A solution: Use the <jsp:root> element as the document root • Does this solve all the problems which might arise when using the include directive? 71 <?xml version=“1.0” ?> <jsp:root version="2.0" xmlns:jsp="http://java.sun.com/JSP/Page"> <jsp:output doctype-root-element="colors" doctype-system="colors.dtd" /> Now we can add the XSL <jsp:output omit-xml-declaration="false"/> <![CDATA[<?xml-stylesheet type="text/xsl" href="colors.xsl"?>]]> <colors > We use CDATA because of the <?, ?> etc <jsp:declaration>static String[] colors = {"red","blue","green"}; </jsp:declaration> <jsp:scriptlet><![CDATA[ for(int i=0; i<3; ++i) { ]]></jsp:scriptlet> <jsp:element name="color"> <jsp:attribute name="id"> <jsp:expression>i</jsp:expression></jsp:attribute> <jsp:expression>colors[i]</jsp:expression> </jsp:element> Still problematic: Which DTD should we use? <jsp:scriptlet>}</jsp:scriptlet> the DTD should enable every JSP element within every other element… </colors> </jsp:root> Open colors1.2.jsp 72