Parameter XML RepresentationIn the previous examples, you saw how to reference parameters from your XSQL page.. With only one line of code, you’ll have every parameter: The result
Trang 1Parameter XML Representation
In the previous examples, you saw how to reference parameters from your XSQL page But what if you want the parameters to be part of the result? This is the job of two actions:
<xsql:include-request-param>and <xsql:include-request-params> This action outputs all of the parameters to the XML Here is an example of <xsql:include -request-param>:
<?xml version=”1.0”?>
<page xmlns:xsql=”urn:oracle-xsql”>
<xsql:include-param name=”conn” />
<xsql:include-param name=”fields” />
<xsql:include-param name=”tables” />
</page>
Now save this as include-param.xsql You can either pass the parameters in on the URL as before or change the action of your very-unsecure.html form to include-params.xsql In either case, this page should produce the result shown in Figure 6.2
Figure 6.2 XML representation of parameters.
Trang 2In this case, you have to specify the parameters one at a time If you know that you want all of the parameters—or, if you want so many parameters that it’s easier to just grab all of them—then you can use the <xsql:include-request params> action You can create the following XSQL page as include-request-params.xsql With only one line of code, you’ll have every parameter:
<?xml version=”1.0”?>
<page xmlns:xsql=”urn:oracle-xsql”>
<xsql:include-request-params />
</page>
The result for this, when you use the same parameters as before, is shown in Figure 6.3
The XML schema is very simple Even if there are no parameters at all, you’ll always have the following skeleton:
<request>
<parameters>
</parameters>
<session>
</session>
<cookies>
</cookies>
</request>
Figure 6.3 Result of <xsql:include-request-params>.
Trang 3The parameters are children of the respective elements As you can see in the previous example, parameters received from forms are children of the <parameters> element For each parameter, a child element with the same name as the parameter encloses the parameter’s value This works the same for session parameters and cook-ies Here is an example where two of each are set:
<request>
<parameters>
<param1>param-value1</param1>
<param2>param-value2</param2>
</parameters>
<session>
<session1>session-value1</session1>
<session2>session-value2</session2>
</session>
<cookies>
<cookies1>cookies-value1</cookies1>
<cookies2>cookies-value2</cookies2>
</cookies>
</request>
Parameter Types
There are several different types of parameters in XSQL So far, you’ve been dealing with request parameters This section covers the other types of parameters A quick definition of request parameters is given first Next, page-private parameters are cov-ered These are parameters that are defined inside of a page Last, session and cookie parameters are covered These can only be used in conjunction with the XSQL servlet
Request Parameters
In the previous examples, you used request parameters Request parameters come in
as part of the request When you are using XSQL in conjunction with the XSQL servlet, they are passed as either an HTTP GET or POST request If you are using XSQL from the command line or it is embedded in your code, you can also pass in request parameters Exactly how you do this is a bit beyond the scope of this chapter, but you’ll learn how
to do this in Chapters 15 and 17, respectively
For now, you should focus on how request parameters are used with HTTP You did this in the earlier example when you accessed the URL http://localhost /xsql/ref-params.xsql?conn=demo&fields=ename&tables=emp&
In this case you are using an HTTP GET method to query your data The GET method
is the most common HTTP method—it is what you use most any time that you click on
a link The second most common method is POST—this is what your HTML forms usu-ally use You can reference parameters in XSQL with both GET and POST For this example, let’s say that you want to create a simple form for processing queries Here is the HTML for the form
Trang 4<body>
<h1>Sample Form </h1>
<form action=”ref-params.xsql” method=”post”>
<table border=”0”>
<tr>
<td>Connection:</td>
<td><input type=”text” name=”conn” /></td>
</tr>
<tr>
<td>Fields:</td>
<td><input type=”text” name=”fields” /></td>
</tr>
<tr>
<td>Tables:</td>
<td><input type=”text” name=”tables” /></td>
</tr>
<tr>
<td colspan=”2” align=”center”>
<input name=”submitButton” type=”submit” value=”Select” />
</td>
</tr>
</table>
</form>
</body>
</html>
You can now do essentially any Select statement with this form Figure 6.4 shows how to fill out the form so you can query on just the employee names from the emp table
Figure 6.4 Using parameters with an HTML form.
Trang 5When you click Select, you should get the results shown in Figure 6.4 You would get the exact same results with the URI specified earlier and shown in Figure 6.1
Page-Private Parameters
You can think of page-private parameters as being local to the page, whereas session parameters and cookie parameters can span multiple page calls Page-private parame-ters aren’t limited solely to HTTP transactions The XSQL command line and XSQL request object can also provide page-private parameters The important characteristic
of page-private parameters is that they are gone after the result is returned Subsequent transactions won’t know about the parameters unless they are explicitly passed Sometimes, you may wish to set page-private parameters explicitly in your XSQL page You do this with the <xsql:set-page-param> action It allows you two ways
to set parameters The first way equates a parameter with a string value, whereas the second way allows you to set a parameter based on a SQL query Examples of both ways to set parameters follow:
<?xml version=”1.0”?>
<page xmlns:xsql=”urn:oracle-xsql” connection=”demo”>
<xsql:set-page-param name=”ename” value=”ADAMS” />
<xsql:set-page-param name=”deptno”>
select deptno from emp where ename=’{@ename}’
</xsql:set-page-param>
<xsql:include-param name=”ename” />
<xsql:include-param name=”deptno” />
<xsql:query>
select * from emp where deptno={@deptno}
</xsql:query>
</page>
Session Parameters
So far, all of our examples about parameters have been of page-private parameters These parameters function much like parameters to scripts Session parameters, on the other hand, exist across invocations of XSQL Your servlet engine maintains the session
on behalf of the XSQL servlet This has the implication that only servlets will be able to make use of session parameters
Setting session parameters is quite simple You set them just like you set cookie parameters The following XSQL will set a session parameter named ename and one named deptno:
<?xml version=”1.0”?>
<page xmlns:xsql=”urn:oracle-xsql” connection=”demo”>
<xsql:set-session-param name=”ename” value=”{@r-p-ename}” />
<xsql:set-session-param name=”deptno”>
select deptno from emp where ename=’{@ename}’
</xsql:set-session-param>
Trang 6Now, save the file as set-session-param.xsql, and access it with the URL http://localhost/xsql/momnpup/set-session-param.xsql?r-p-ename
=ADAMS&
If you now go back to the include-request-params.xsql page that you cre-ated earlier, you’ll see the output that is shown in Figure 6.5 These parameters will be part of your session until the session ends Your servlet engine ultimately controls the session itself It usually continues until the browser window is closed or until some period of inactivity
If you know that a given XSQL page will only be called within a session, then you can use session parameters instead of having to deal with the complexities of request parameters or page-private parameters For instance, let’s suppose that you want var-ious kinds of information about a particular employee You can create a simple form that has an input field named r-p-ename and then set its action to the set-session-param.xsqlpage you created previously Alternatively, you can just use the URL that you just used
parameter, ename, have different names, though they refer to the same entity A
session parameter can’t be assigned the value of a request parameter of the
same name (It is legal for parameters of different types to have the same
name—the rules for resolving the naming of conflicts are laid out later in this
section.)
Figure 6.5 Session parameters and <xsql:include-request-params>.
Trang 7Now, the ename and the deptno parameters are set for the entire session If you want a list of everyone in the department, you can do that with a very simple XSQL page:
<?xml version=”1.0”?>
<?xml-stylesheet type=”text/xsl” ?>
<page xmlns:xsql=”urn:oracle-xsql” connection=”demo”>
<xsql:query>
select * from emp where deptno={@deptno}
</xsql:query>
</page>
Cookies
HTTP cookies try to solve a fundamental problem of HTTP How do you create state when using a stateless protocol? You saw cookies at work in the previous section If you look back at Figure 6.5, you’ll see an entry in the cookies element This cookie is actually the one that is used by the servlet engine to control the session
The basic mechanism is that a cookie is set on the Web browser The cookie itself is really just a string The Web browser stores that cookie in some way on the local machine That cookie is passed back on subsequent requests The browser will only pass a cookie back on requests for which the cookie was specifically meant This means that if www.yahoo.com sets a cookie, there is no way that the cookie will be passed to your Web application, assuming that your Web application isn’t running in the yahoo.com domain Further, you can restrict cookies so that they are only sent back to certain URLs within your own domain Cookies can be either session based (i.e., they are erased when the Web browser closes down) or long lived Long-lived cookies can stay on the browser virtually forever
When the cookies return, your application is able to assume that the current transac-tion is originating from the same Web browser as previous transactransac-tions Thus, you are able to maintain state on the server side This is exactly what the servlet engine does with the cookie that it sets It attaches all of the session information to that particular cookie on the server side That single cookie can act as a key to a lot of different infor-mation When you set cookies manually, you can create the same kind of architecture This is the way cookies generally work However, it is very important to understand that the individual users ultimately have control of whether cookies will work this way for them Users can set their browser so that they don’t accept cookies, or don’t accept long-lived cookies They can go in and choose to delete cookies that your application uses If you depend on cookies for authentication, you may find your users trading their cookies around When using cookies, it’s important to remember that you can’t depend fully on their full and appropriate use Cookies certainly make the developer’s life easier If you can require your users to have cookies enabled on their browser, then you’ll have an easier time designing your application However, if you can’t, you need
to consider ways that your application will degrade gracefully
Trang 8With an understanding of the problems of cookies, let’s look at how to use cookies with XSQL The basic model is the same as with page-private parameters and session parameters, but with some extensions Let’s cover the basics first The following XSQL page will set the employee name and the department number as cookies:
<?xml version=”1.0”?>
<page xmlns:xsql=”urn:oracle-xsql” connection=”demo”>
<xsql:set-cookie name=”ename” value=”{@r-p-ename}” />
<xsql:set-cookie name=”deptno”>
select deptno from emp where ename=’{@ename}’
</xsql:set-cookie>
<xsql:include-request-params />
</page>
Save this as set-cookies.xsql You can call it with http://localhost/xsql /momnpup/set-cookie-param.xsql?r-p-ename=SMITH& You can then invoke the include-request-params.xsql page that you developed previously and see the results that are shown in Figure 6.6
Figure 6.6 Setting cookies with XSQL.
Trang 9An obvious question is, “Why would I want to set cookies manually instead of just using the session?” In most cases, you wouldn’t Cookies do have one advantage over session parameters: You can request that cookies live past the current session You are able to do this with the max-age attribute as follows:
<?xml version=”1.0”?>
<page xmlns:xsql=”urn:oracle-xsql” connection=”demo”>
<xsql:set-cookie name=”long-living-cookie” max-age=”999999”
value=”To_Life” />
<xsql:set-cookie name=”deptno”>
select deptno from emp where ename=’{@ename}’
</xsql:set-cookie>
<xsql:include-request-params />
</page>
If you invoke this XSQL page, shut down your browser, and then restart it, the cookie will survive A call to include-request-params.xsql will confirm this The max-agevalue is in seconds, so in our example, the cookie will live for about 11 days You can also control the URLs to which a cookie should be returned Previously, you learned that your application isn’t going to receive cookies set by www.yahoo.com In fact, by default, no URL outside of the original directory where XSQL first set the cookie will see it To demonstrate this, create another directory named test-cookies
in the demo directory and copy include-request-params.xsql in it When you
go to http://localhost/test-cookies/include-request-params.xsql, you won’t see the long-living cookie Go back to the original include-request -params.xsqlpage, and there you will find it
For many applications, this is too restrictive If nothing else, it means that all of your application must be in the same directory or subdirectories Luckily, you can control this behavior very easily Using the path attribute of the xsql:set-cookie action, you can make the cookie generally available to all of the application This XSQL page sets another cookie that should be available anywhere on your server:
<?xml version=”1.0”?>
<page xmlns:xsql=”urn:oracle-xsql” connection=”demo”>
<xsql:set-cookie name=”long-living-remote-cookie” value=”To_Life” path=”/” max-age=”999999”/>
</page>
You can reference cookies just like you can any other parameter by using the {@cookie-name}syntax You aren’t limited solely to parameters set by XSQL You can reference any cookies that come your way, including cookies set by other applica-tions in your system
Setting Default Parameters
In the previous section, you learned that you can’t depend on cookies always being available If you can’t depend on them, then can you set a default value? Can you set default values for other parameters? You can, and the mechanism is pretty simple
Trang 10Let’s look back at our very-unsecure.xsql page For that example, you had to specify three parameters for the action to work at all This is an ideal case for setting default values The following XSQL will accomplish this You should save it as very -unsecure-with-defaults.xsql
<?xml version=”1.0”?>
<page fields=”*” conn=”demo” tables=”emp” xmlns:xsql=”urn:oracle-xsql”
connection=”{@conn}” >
<xsql:include-request-params />
<xsql:query>
select {@fields} from {@tables}
</xsql:query>
</page>
If you execute this page with no arguments, you’ll get the same results as before Attaching arguments will yield different results, of course, providing that the default values are more graceful and reusable If you only get one parameter, you don’t fail entirely
You can provide multiple default values for the same parameter This is useful if you have multiple queries in the same XSQL page The following example sets the default for the max attribute for all queries, while still allowing a lesser default for a couple of queries
<?xml version=”1.0”?>
<page max=”10” conn=”demo” xmlns:xsql=”urn:oracle-xsql”
connection=”{@conn}” >
<xsql:query>
select * from table1
</xsql:query>
<xsql:query max=”5” max-rows=”{@max}”>
select * from table2
</xsql:query>
<xsql:query>
select * from table3
</xsql:query>
<xsql:query max=”7” max-rows=”{@max}”>
select * from table4
</xsql:query>
<xsql:query>
select * from table5
</xsql:query>
</page>
Using Bind Variables
So far, you’ve been using lexical parameters when you’ve made references with {@param} When the XSQL document is parsed, a lexical substitution is made After this parsing, it’s as if all of the parameters were hard-coded This is fine in a lot of ways,