Configure player

Close

WWDC Index does not host video files

If you have access to video files, you can configure a URL pattern to be used in a video player.

URL pattern

preview

Use any of these variables in your URL pattern, the pattern is stored in your browsers' local storage.

$id
ID of session: wwdc2002-710
$eventId
ID of event: wwdc2002
$eventContentId
ID of session without event part: 710
$eventShortId
Shortened ID of event: wwdc02
$year
Year of session: 2002
$extension
Extension of original filename: mov
$filenameAlmostEvery
Filename from "(Almost) Every..." gist: ...

WWDC02 • Session 710

JSP and Servlet Integration

WebObjects • 57:27

Learn about JSP and Servlet integration with WebObjects, such as the WOComponent and WODirectAction tag libraries, accessing WebObjects, EOF and Foundation from within a JSP or Servlet. This session explains how to build a hybrid WO/JSP/Servlet site, and how to deploy it.

Speakers: Karl Hsu, Megan Moore

Unlisted on Apple Developer site

Transcript

This transcript was generated using Whisper, it has known transcription errors. We are working on an improved version.

Welcome back everybody, and hopefully the rousing music got you guys awake and everything. Does everybody want like a stretch first, or are we ready to go here? Okay, it is my pleasure to introduce Karl Hsu. Good morning, everybody. And I say good morning because you've just had lunch, you're going into a food coma, and I'm trying to fool you into thinking it's Monday morning, you're ready for the big commute, you're ready to go to work.

Is that having the wrong effect? I think so. Anyway, so this is JSP and Servlet integration. Actually, it didn't fit on the slide, but it's JSP and Servlet integration with WebObjects. And so we assume that you guys are here with the understanding that WebObjects is involved. If you think this is just a general JSP/Servelet overview course, you should probably go to a different session somewhere. OK.

JSPs and Servlets. What are we talking about? We're talking about the ability to run a WebObjects application as a Servlet. This is different from the J2EE talk, the EJB stuff that they talked about earlier, where you're talking about running EJBs in WebObjects. Now we're talking about running WebObjects in a J2EE server. It's sort of a weird relationship. We're also talking about the ability to access WebObjects components and direct actions from inside of a JSP page, sort of a way to generate HTML for you.

Okay, before we begin, we'll make these first couple assumptions. You have to know what a Servlet is. You also have to know what a JSP is. But in case you don't, we're going to go over it anyway. Let's begin. Servlets. Servlets are a programmatic way of generating dynamic HTML. You run inside of a Servlet container, for instance, Tomcat or WebLogic. You then write a Servlet subclass. You get a request and a response object, and then you have to do all the work. It doesn't do anything else for you at all.

We talk about this, and before we go on, in case you missed the deployment talk, we'll show you. This is how WebObjects work. We have a client, a web server, and a WebObjects application. The client makes a request, goes to the web server, and this request, of course, is usually HTTP.

The web server passes the request into the WebObjects adapter, basically using an API plug-in, or sometimes using environment variables if it's a CGI process. The WebObjects adapter does a whole bunch of neat stuff, some mapping, some load balancing, writes a checkbook. And it passes the information using HTTP back to the WebObjects application. And when the application is finished processing, it'll return the response the same path.

What's different about a servlet? Well, a servlet works a little bit different. Same thing begins. The client makes an HTTP request to the web server. The web server has a container adapter, which is invoked through an API. And the container adapter then somehow invokes the container. In a lot of containers, I'm not certain why, this is just some proprietary mechanism. It's not necessarily HTTP. But then the thing is that you can have multiple servlets running inside of a single servlet container. So, in fact, then you have to take that request and through an API invoke the correct servlet. That's what I was talking about before.

On to WebObjects. This is the good part. This is new in WebObjects 5.1. It's something we just added. And it allows your WebObjects application, any WebObjects application, to run as a Servlet inside of a Servlet container. I'm going to say this a bunch of times because it's very easy to get this confused. We are not a Servlet container. We run as a Servlet. It also lays the foundation for JSP integration, which is the second half of my talk.

Why? You've got to be wondering. WebObjects is such a great, perfect application server. Why would you need anything else? Why did Apple spend the time to do this? And the answer is, so you don't have to fight. We got this, you know, people come up to us and they say, wow, you guys have such a cool application server. You can do all this powerful stuff. You know, EOF is great. We can do all these template things. It's wonderful.

But, you My boss, or the client that I'm working for, came up to me and said, you know what? We've standardized on WebLogic. We don't care if your application works and makes money for us. We're going to standardize. And now you can say to them, we can all be happy.

Now I can use WebObjects. You know, in the year that it takes them to write their one Servlet application, you can go in the back end, hook up your database, get everything going, deploy web services, direct to web, whatever, Java client, leave them in the dust, and still on WebLogic or Tomcat or whatever they've decided to standardize. You can now treat us as the world's most powerful Servlet library. All that work that they have to do by hand, we do for you.

So you're probably wondering now, well, that's interesting. How did they do that? Just in case you can't read the slides. How did we do this? Servlets are generally deployed in self-contained little WAR files. WAR files are actually JAR files renamed, just like JAR files are actually zip files renamed. So, they are, don't ask, but they use a tar format. I don't know why. We actually run, as a Servlet, we're inside of a WAR file. We have a Servlet subclass that we wrote that takes the place of the WO default adapter.

So, normally the request would come in to the application, and we act as sort of a mini web server. We handle the request, we pass it on, blah, blah, blah. What we did now is, instead of that WO default adapter, we have a Servlet. We take in the Servlet request, translate it to a WebObjects request, let your application handle it, take the response, translate it back to a Servlet response, and hand it off to the container again. down.

The goal when we did this was to make it as transparent as possible. And we wanted to do this for two sets of people. First set of people is you as the developer. We tried to minimize the amount of work that you would need to do to take advantage of this. Ideally, unless you've done some particular things in your application, you should be able to take any regular WebObjects application, drop in some, you know, do a little bit of stuff, and bingo, you can now deploy in a WebObject, in a Servlet container.

The other group that we tried to take advantage of was the non-WebObjects deployer. I mean, we understand that a lot of you end up working on client site or working in a situation where you don't have access to the deployment machine. And when they say, well, how do I deploy this application? And then you give them this, you know, the quite well-written Deploying WebObjects Applications book, they kind of look at it and go, I have to do all this? Right? And they already know how to use WebLogic or Tomcat or WebSphere or whatever. So now you can hopefully just hand them something that's much simpler to use, where they don't have to learn how the adapters work, what do all these settings mean, how do I use monitor, when they already know how a certain set of deployment tools work.

One thing to remember is that we weren't quite able to make it completely transparent. Because the Servlet adapter has to load the rest of the WO classes at runtime, primarily because of the NSBundle architecture, WebObjects has to be installed on the application server. OK. So you still need to have an install, which is, you know, it's a very minimal install. On Solaris, for instance, we now have a Servlet install that doesn't install the adapters, doesn't do anything with WoTasty or Java Monitor. It just installs the necessary run time. And even that may be minimized. We'll talk about that in a future direction later in the talk.

What can you run? Well, I was serious. You can run any regular WebObjects application. You can run direct web applications. You can run Java client applications. You can even run direct-to-Java client applications. For all practical intents and purposes, it should work fine. Later on, once we have the web services support in, that should work perfectly fine as well.

Where can you run? Well, because all Servlet containers are supposed to behave the same, theoretically we could run anywhere, but there are actually a number of differences. Some of them are implementation, some of them are because the Servlet spec is unintentionally vague in some areas. So the ones we've tested on, the ones that we've done QA, Tomcat 3 and 4 on Mac OS X and Mac OS X Server, WebLogic 6.1 on Win 2000 and Solaris. And then we've looked at a couple of other ones. We're working on qualifying WebSphere in a future release, which I'm sure you've heard many times now. Future release, future release, it will all be fixed in a future release.

What about deployment? Well, it is different from a typical WebObjects deployment. Normally, you use Monitor and Wotasty, and they control your instances, they, you know, the HTTP adapter talks to them, it's all like this nice circular relationship. You can't do that in a Servlet, because we're not an independent process anymore. Wotasty didn't start it. Wotasty doesn't know what it's doing anymore.

Right? The fact that it stopped doesn't mean the container is stopped. So we don't really have a choice. You have to use the container's management tools. Sometimes this is good. Tomcat, you know, mostly is a command line tool. There's a little bit of a GUI, but not much of one. And then, you know, all the way on the other end of the spectrum, you have WebLogic, which has an administration tool that takes a good ten minutes to load.

So the other caveat, as you might have guessed from looking at my previous diagram, the WebObjects HTTP adapter isn't in the equation anymore. We're running in the container. We don't know, we don't care whether you're running through a web server or you're connecting directly to the container, which you can still do. I mean, it's similar to our version of Direct Connect. Most containers support the ability to talk directly to the container without having a web server in the way.

How do we convert an existing project? It's very complicated. You have to follow me very carefully here. Step one, you want to open the project. Step two, you want to add the Java WO/JSP/Servelet framework. This could be complicated, because you can either choose add framework or you can drag it in.

If you're on a project builder WO project, either on Mac OS X or Windows, you have to add some missing makefile preamble variables. Don't worry, we'll go over them. You're not expected to just magically know them. Oh, and that's it. Okay, and you're thinking, wow, that was complicated. How much harder do you think it would be to make a new project? Well, a new project's even more complicated. You create a new project. When it pops up the little wizard and it says, do you want to deploy in a JSP/Servlet container, you say yes. And I lied, there's no step three.

Yes, yes, I know, I cribbed off of the iMac commercial, blah, blah. But we're easier than the iMac. Really! Okay, so actually it's a little bit more complicated. Let's talk about some of the details. Project Builder is a Mac OS X. We add some new files and folders. Either when you create a new project or when you drag in the framework, we automatically create them. You don't have to go off and do anything.

Inside of the resources folder, we create a Servlet resources subfolder. We have some predefined directories that you can drop stuff into. We have some, a template file that you can use to customize your Servlet deployment. And then you're allowed to drag anything you want in here. Anything you put into this folder will get copied directly into the root of the war file, which means that you can put it in the webinf, and it'll be only for your application to access, or you can put it at the root and it'll be accessible as if it were on the web server.

The WebXML template file, which we add, is used to customize the WebXML. The WebXML in Servlet deployments is used as a deployment descriptor. You can use it to pass custom arguments to your Servlet. You can use it to configure your Servlet from the container's point of view. Should I start it lazy the first time somebody makes a request? Should I start it immediately on startup? What URLs map to using this Servlet, blah, blah, you know, that sort of thing. Because you can actually have more than one Servlet inside of a single WAR file. So you can map, like, if I use this URL, invoke this Servlet. If I use that URL, invoke this other Servlet.

What we do is we have a template file with placeholders. The placeholders are surrounded by percent characters. And at compile time, we replace them with the appropriate values for your development environment. You can also customize it directly for your deployment environment if you know what that's going to be. There's also another way to customize it.

We'll mention that When we get there. All right, we also add some new build settings. There's the Servlet WebAppster. This is mostly to make it easy during testing. Tomcat, for instance, automatically will deploy any WAR file that happens to be in a particular directory when it's started. So what you can do is you can, rather than build, copy, test, build, copy, test, what you can do is just set the WebAppster directly to where Tomcat wants it to be, restart Tomcat, and you're off. And then you only have to build, test, build, test.

It's easy to get sidetracked. Servlet copy jars. This is a little bit more complicated. We're going to talk at length about this at the end of the conversation. It's not really a conversation. It's more like a monologue. Servlet copy jars. Should all of the jars for your frameworks and your application be copied into the lib directory? What it means is that we'll copy the jar files into a place where the Servlet container will automatically load them when your application is run. We don't have to load them in, you know, independently. And that gives you a little bit more freedom at the cost of space.

This is only used for accessing WebObjects classes directly from inside of a JSP or Servlet. Normally, you shouldn't need to do this. This is only if you're going to do some sort of interesting custom project. If you're just deploying a WebObjects application as a Servlet, like a regular WebObjects application, you shouldn't need to do this, because we do all the work for you in the Servlet adapter. If you're using the WebObjects and Direct Actions code later from JSP, you shouldn't either, because again, we take care of it all in the taglib code.

This will look very familiar, but I want to be thorough. Project Builder Wo. Project Builder Wo adds, again, two new files and folders, or two more folders in the file. It adds the JSP/Servlet webinth folder, which is used to hold jars, classes, TLDs that you're interested in deploying.

And this is sort of an auto-routing folder. Anything you drop in there will put into the correct place. But don't drop anything else in there, or otherwise it may not end up in the right place. If you're interested in adding additional resources into the WAR file, you use the JSP/Servlet resources file, folder. It's not very complicated. We also have a web.xml.template file included in Project Builder Wo. It behaves exactly the same as it does on Project Builder.

One caveat is because of the nature of Project Builder WO, nested directories retain their structure. So if you have some directory structure that you want to drop into, say, the JSP/Servlet resources folder, you can do it. But you won't be able to edit from inside of Project Builder WO. You can only see the top level folder. You'll have to edit it, you know, using Finder or Windows Explorer or something.

Project Builder details the new makefile variables. These are the makefile variables that you need to add in. One thing to kind of keep in mind is that they should be exported. The easiest way to do this is create a new project using Project Builder. Well, take a look at the, you know, big chunk where we have lots of comments and these variables, and then just copy and paste that into your old project. That's probably the easiest way to do it.

Servlet Web Appster and Servlet CopyJar, as you should be familiar with, they behave, again, exactly the same as in project builder. The only new one is Servlet App Mode. Servlet, because in project builder we have a notion of a deployment install, explicitly, when you do a deployment install, we set something in the Web XML so the application knows whether it should treat images and web server resources as being served from the web server.

So, you know, you'll have image source equals slash web objects slash blah blah blah something dot gif. Or if you're in development mode, it'll treat it as if we have to serve it explicitly. That's when you get the WR resource with the enormously long, hard to understand URL.

With the make files, we don't have any way of telling. So you can set it explicitly, Servlet app mode, you can set it to development or deployment. Obviously if you set it to deployment, we act like you're going through the web server. If you set it to development, we act like you're hitting us direct connect. So, I apologize, that was a lot of information.

How do you deploy? Well, you go through your process. You've, you know, developed your application, you're all ready to do this. You build your application once you've set all this stuff. We'll create a WAR file for you, and we'll build it in the Servlet Web App Store. If the Servlet Web App Store isn't built, it'll show up right next to wherever your WOA is set to show up by default inside of your build, build products directory.

You then use the container's tools to deploy the application. Some containers have tools, you know, like WebSphere, for instance. You have to use their GUI. It's, you know, you point it at the WAR file, it explodes it, does some munging, and then you're set to go. Tomcat, you just drop stuff into a particular directory, restart the container, you're set to go. So it depends on the tool, you know. But we leave it entirely up to them. We create the WAR file, and we let the container go.

This is the URL that you would use to hit it. It's a little bit different from a regular WebObjects URL, and there's a specific reason for it. When you run a WebObjects application, you can only run one application, right, on a port. When you run a container, you can have 20, 30, hundreds, probably not hundreds, Servlets running inside of it. It doesn't know, given a particular URL, it doesn't know where to dispatch that Servlet. So what it does is it uses the URL.

That's this, the myapp, WebObjects, myapp.woa. The myapp is what it uses to dispatch to the correct application. So it was easy to be lazy when you were running in Direct Connect in standalone, you know, localhost:port, and you'll just hit the first page. If you do that here, you're going to get back the container's index page. You have to have this thing. And then, of course, you still have to have WebObjects myapp:woa, because the WebXML defines that as the path to the particular Servlet that we're going to be servlet that we need to invoke.

There are a couple of quibbles. Do you remember how the Servlet adapter loads the WO classes at runtime? One consequence of this is that it needs to know where to find the WebObjects classes. We define three variables that let you specify where these are. These are defined inside the WebXML, and they get passed as Servlet context parameters to your application. And the Servlet adapter takes care of it. You shouldn't normally need to worry about it. But the thing is that because we do this at compile time, they're set for your development environment.

Wherever it thinks that your WAR file and your WOA and your frameworks and the system frameworks are, when you compile the application, that's where it's going to make the settings. Obviously, this isn't necessarily appropriate all the time. So what you can do is set system properties at the container level.

So anything you set in the system property with the same name as these variables, will override anything in the WebXML. Of course, this also has the logical conclusion that all of them have to be the same for all of the WebObjects applications running inside of a single container.

I'll bet you thought I forgot which three variables. But I didn't. All right. The woa install route. This is the directory where your woa is located. So if you installed hello world dot woa into library WebObjects applications, that path would be library WebObjects applications. Local route is where your, your frameworks are. Typically, for instance, on Mac OS X, this would be library frameworks. And WoRoot should be easy. That's the director where the system frameworks are typically installed. Java WebObjects framework, Java Foundation framework. And for instance on Mac OS X, that's system library frameworks, blah blah blah.

Some more details about what we're doing. Session handling. One of the interesting things is the sessions, the way we're doing WebObjects sessions is that we're actually going to piggyback them on top of the JSP/Servlet session store. This means that we no longer have our own session store implementation. We have sort of a thin shell on top of the containers session store.

In a lot of containers, their session store is actually very advanced. It's very nice. And while it's not officially supported, it's possible that for something like WebLogic, where they automatically support persistent sessions traveling between instances, their whole clustering thing, it's possible, at least, that our sessions could be carried around as long as everything inside the session was also serializable.

The other comment is that some of the WebObjects properties aren't used. This should actually come as a no-brainer. Many of the properties that aren't used are the ones that deal with things like the WoE default adapters. Since we no longer have a WoE default adapter that's listening on a socket and doing all this work, you don't need any settings for it.

The other thing, though, is-- and this may bite some people-- you can't pass arguments on the command line, because we're not starting it, right? The container could already be running. It won't have a chance to read anything in. In a lot of the containers, you have a running container, you point it at your app, and it says, oh! And starts your app up.

We've never had a chance. So the way you would want to do that is using the properties file. And that was talked about in the deployment course. You can have properties files in frameworks, you can have them inside the WOA, and those will set properties for you. If you're brave, you can also set them in the WebXML, pass them a Servlet context, and do some interesting stuff to pull them out.

Remember, though, when you do this, you have to be a little bit careful. System properties are shared between all applications in a container. So if you have five applications and you have a single setting that you need to be different between those applications, it may not work. Because the last one to run will set the system properties for the entire container. Okay? This is something you need to be careful of. It's also something we're aware of.

Obviously, I've mentioned this several times, the WO default adapter isn't used. So if you're expecting it to do something in particular, I'm not certain what, because it's not really public. But if you were, it's not going to do it. The other thing, and this is probably the one that's going to be the most trouble, is we have a custom WoContext subclass. It's called the WoServletContext. So if you have a subclass of WoContext, you need to look at subclassing the WoServletContext instead.

Now I'm going to have a very brief sort of over here sort of moment. If you start working with this in any detail, you're going to see the ServletContext compared to the WoContext. These are totally separate. For us, for WebObjects developers, a WoContext is a per-request object. It's something that keeps track of what's going on in the request that I'm processing now, and it has no idea what's going on outside of that. And in fact, we just throw it away after each request. In the Servlet world, a ServletContext is the application.

I don't know how they came to this conclusion, but it's all right. We speak English. A Servlet context literally represents your application. It's roughly equivalent to the WO application object in WebObjects. So when you're, when you kind of look at this, and if you're talking about it or working with them, you have to keep this in mind. You have to be very explicit so you don't start suddenly trying to treat the Servlet context as a temporary object. Okay. Back to the WebObjects people.

Okay. Looks like it's time for a demo. That's what the slides tell me. So, I'd like to invite Megan Moore. So, what we're going to do first, just in case you didn't believe me, we're going to convert an existing project. To make it kind of interesting, we're going to actually convert Java Client Rental Store. It's actually a direct-to-Java client application. It's one of the examples that ships with WebObjects. So, we begin. We're going to add the framework.

And of course, we have to add it to the correct target, because if we don't add it to the correct target, Godzilla will come and kill us all. All right. You notice that what happened, as soon as she added the framework, we got this new directory that I was talking about, the Servlet resources directory.

There's nothing else in it by default, because frankly we don't put anything in it by default. You can drag whatever you want in. The only thing we have is the WebInf. The WebInf has a classes, a lib, a tld directory, and the WebXML that we talked about before. Let's take a quick look at the WebXML.

So here, right at the top, you can see that we have these three context parameters that we talked about, the ones that you use to set where the Servlet adapter goes off and looks for the classes. WO route, LOCO route, WOA install route. Currently, they're the placeholders. They'll get replaced, again, by the appropriate values for development at compile time. I sound like a broken clock. All right, WO app mode. Here we have it. You can set it explicitly if you like. Project Builder is a little bit smarter about what to set it to when you build.

The most interesting thing will end up being the WO class path. The WO class path is what we end up using. That's the class path that NSBundle uses to build up all its bundles, find all your application, all your code and everything like that. You want the font? What? The font. Oh, you want the font bigger? Yeah.

[Transcript missing]

syntax coloring. Oh, sorry. Yeah, that's it. Font. Oh, set. There we go. One of the interesting things that you can actually do is you can just... - Bigger, bigger. - There we go. - Try 14. - How about 18? No, I think 18 is probably fine.

: Hit OK. There we go. OK, so they're big. There we go. These are really important variables. Very weighty. All right. You go on. You have to specify the--well, we find the WO application class for you. We do all this nice stuff. The WO class path builds into a series of paths where it'll be like, WO root slash library frameworks, blah, blah, blah.

So what we try to do, what you can also do here, it's very simple when you deploy your application. If you have additional jars, just add them after, you know, you know, after a WOClassPath with the percent signs, just hit enter and, you know, add a list of jars that you want to include and hit enter after each. It's not very hard. We'll find them and do them at runtime. If we don't find it, we'll just ignore it.

So, The classes directory and the lib directory and the tld directory are pretty much standard. Classes is where you would drop unjarred, like, just .class files, so that the Servlet container will load it. The lib directory is, ta-da, where you would put jar files so the Servlet container will load it. Remember that variable Servlet copy jars? Well, it copies all your jars into the lib directory, so the Servlet container will load it.

And the TLD is where it's a convenient place to put and I are going to talk about the tag library definition files. They're XML files that define the behavior and ex-- Excuse me. I hope that wasn't me. The XML files that define a custom tag library. It's empty for now.

You can drop in stuff and reference it there for ease. We also drop something in there when we compile. That's the tag libraries that we use to call WebObjects components and direct actions later. So, the other thing we wanted to take a look at was the targets, those new build targets, or build settings, rather.

Servlet CompiJars, currently set to no, because, like I mentioned, this is just a regular WebObjects application. It's not needing to do anything special. Megan, in Servlet WebAppster, what she's doing is, because we're going to use Tomcat 4 to demo this, we're going to use Excuse me. She's just going to drop the jar in there directly so we don't have to do anything complicated because it's a demo. We build.

We restart. Actually, sorry, my bad, we start. All right, you can see here, we found the main bundle. That's the list of properties files, and you notice that it is much shorter. A good number of the properties just don't matter anymore. They're not anything we care about in particular. Double check the Java client application and, again, the correct URL, Java client rental store, blah, blah, blah. Wait a few minutes.

There we go. So that's Java client rental movies running in a Servlet container. Just to be thorough, Now that we've seen that it works, who did you find? Lisa Matthews. Okay, I don't know So what we're going to do now, stop the container, and because I'm an engineer, I like to be thorough, we're going to show making a new project. Okay, so let's do a directed web application. And let's call it DTWServlet.

Does anybody have any problems with that? It's OK? It's OK. All right. This is what I was talking about. Here's the really complicated part. Deploy in a JSP/Servlet container. There's a line, copy all jars into the JSP/Servlet webinf directory. That's pretty much a cover method for changing the setting for Servlet copy all jars. Generally, again, you don't really want to worry about it. So let's build it. Or, well, let's go next. And let's find a random model. Movies is good.

Let's go neutral. I don't want to offend anyone. All right, normally you can build and launch. That's fine. What we're really going to do here is, the only reason we didn't build and launch is because I do want to set the WebApp stir so it builds in the correct place. Go, Megan, go. Type like the wind. There's no pressure. We're all just waiting on you. I'm not that fast a typer. Sorry. Oh, come on. You can do it. You should practice more.

Come on, you can do it. Go, little Mac, go. All right, we're starting it again. Actually, if you haven't noticed, we didn't bother to remove the old one, so we're actually going to end up launching both applications. This first one happens to be-- Oh, we're building DTWS first.

And there you go. It's a directed web application. It's running as a servlet. There's no WebObjects running, well, WebObjects isn't running independent. Megan, thank you. Mm-hmm. Wasn't she wonderful? We are now on to the second half of our presentation. For those of you who were hoping for an intermission, you slept through it. Next. Alright. So, JSPs. What does the acronym mean? Well, the acronym means Java Server Pages. It's sort of a takeoff of app server page, you know, the whole ASP thing.

Alright. It's a template-based way of generating dynamic HTML. It's essentially what happened when somebody at Sun said, you know, it's kind of mean for us to make them write everything when they're writing Servlets. I mean, you know, you're sitting here going system out, or like, system out println, you know. Open bracket, blah, blah, blah. Quote, end bracket, return. I mean, it's really a pain in the butt. Isn't there a better way we can do this? So they came up with the innovative idea of using templates.

And then, of course, you know, because it's good to leverage code, they're compiled into Servlets at runtime by a Servlet container. This basically means that, of course, every JSP container is also a Servlet container, though I think in one case they may not actually expose the Servlet interface. Essentially, it is just template-based. You write HTML, and you have little bits of embedded Java code.

Recently, things have been getting a little bit better, especially with the advent of Bean, so in a lot of cases now, you just ask a Bean to return the information that you're interested in. But you're still capable of writing Java code directly in the HTML itself. You can also call out the other Servlets. You can include other bits of JSP pages. It's, you know, it's your standard template-based system. ColdFusion, WebObjects. We all do it. Some of us do it better.

Tada! This slide should look really familiar. I sort of cobbled it from an early one. It's new to WebObjects 5.1. It requires Servlet integration. Remember I told you, you know, all the JSPs get compiled to Servlets, so on and so forth. This means, obviously, you must run as a Servlet in a Servlet container. What it does is it lets you use WO components and direct actions to generate HTML or XML or actually whatever you want for your JSP pages.

Why? Well, we let you write this sort of weird mixed JSP and WebObjects application, where bits of it are written in WebObjects, bits of it are written in JSP. Why would you want to do this? Well, there are two big reasons. The thing is that despite the fact that it's this wonderful, powerful template-based system, JSPs are still a pain in the butt to use for a lot of people. What you can do is you can use a JSP, and then you can use WebObjects to do the really hard stuff, because we do that really well.

Custom WO components. You can have WO components with these really, really complex templates, component contents, switch components, all this stuff like that. You know, WO repetitions, WO progress bars, all the nice elements and, and built-in components that we build for you. And of course, the kicker, instead of JDBC, you can use EOF to do your data persistence. And for a lot of people, that's really nice.

How did we do this? Well, we implemented it as a taglib. Taglibs, tag libraries, are custom JSP tags. You can see one here. You sort of say, all right, any time I use the prefix tt, it means to use the taglib at this URL. And then you can define your custom tags.

When the JSP engine reaches those tags, it calls out to your code and does whatever. In our case, of course, you know, it hits a WebObjects tag, calls out to our code, we invoke request response loop to grab the HTML or whatever you're returning, and then hand that back to the JSP engine.

Voila. We define it in a TLD file, wo-taglib_1_0-TLD. It's located inside the Java WO/JSP Servlet framework. We also copy it into the TLD file of the built warp. Ta-da! OK. Part one of using WO components, the component tag. The component tag has--pardon me. I'm going to take a drink.

Do you guys hear me swallow? No? Good. It's always embarrassing. So, attributes. You can have the class name, which is the name of the component. So if you have a component, myComponent or main or whatever, that's required, obviously. It needs to know what component. BodyContentOnly. Because a lot of people will want to try and reuse existing components, and some existing components think they're the whole page.

But in this case, because you're doing it inside a JSP page, it may not be. So what you can do is you can set body content only to true, and we'll try and strip everything except the content between the first and the last body tags. OK. This is mostly to avoid having you end up with two components, one to use separately, one to use inside of a JSP page where one is basically the other with bits just cut out or commented. And merge response headers.

Obviously, we give you a little bit more control. When you are generating a component, you can stuff custom headers or modify existing headers in a response. And this tells us whether we should take the WoW response headers and merge it into the real servlet response. You have to be really careful doing this.

The servlet response has its own idea of what's going on, and you could have multiple components on a page. They could conflict. Again, the component can't think of itself as the only component on a page, nor will it be the entire page almost definitely, even if it was originally intended to be.

You can specify things. You are, you know, in order to invoke a component, you need to pass things. Like in the WAD file, you would need to pass bindings and such like that. So the two things we let you do is we let you pass extra headers incoming, you know, in case your component expects that some previous bit did some processing and wants, you know, passes it through the header.

So you can pass it. It's very easy. It's key in value. It's optional. And the binding. These are the important bits. These are pretty much analogous to what you would pass in the WAD file. Right. You have a key and a value, and they are passed as ta-da, key, value. Yeah. OK.

I apologize, the code is a little bit small. It's only like half a foot high. And you can see, we define where to find the tag lib. We do a little bit of embedded Java code. Again, please note, if this is anything complicated, you usually would shop it out to a bean so you don't end up editing the JSP page directly every time you want to do this. And then finally, we invoke WoCompletionBar, and we just pass a whole bunch of information. You can see, you know, the general syntax of how we do And it works. Looks good. You have a nice WOCompletion bar, and you basically didn't have to write much code at all.

Now we move on to direct actions. Direct actions live in, are invoked through a direct action tag, analogous to the component tag. We're very original here at WebObjects. OK. We have the action name, and that's the name of the direct action that you would invoke. You have an optional class name. I mean, if you're familiar with the way direct actions are invoked, you can, you know, you can say, I want to invoke this action on this class.

You can do this here. If you don't specify an action, it uses the default action of the class. If you specify an action but no class, it uses the default class, direct action class. The others are the same, body content only. It's the same as the WO component. Merge response headers, the same as the WO component code.

The extra header tag, sub tag that you can use with direct actions, same. Form value is similar, but of course, because direct actions don't have component values, we allow you to pass these. They basically, you take the key and the value and then we merge it into the query string and pass that on to the direct action, so you can do whatever you want with it.

And so, of course, the requisite code example. This is a little bit bigger, a little bit less code. Yeah, so I have my action. I can tell it. My action, this will get invoked on the default direct action class, and it'll return everything. That's actually the default anyway. You have form value keys and pass them, and again, they'll get folded into the query string. Query string gets passed, and then it gets chopped up. The whole WebObjects engine goes to work, has a nice day.

So, now that we've talked about JSPs, what else can we talk about? Servlet copy jars. Yes, once again, we're back to this annoying variable that I keep mentioning and don't explain. We're talking about the ability to directly reference a WebObjects class from inside of a JSP or Servlet without using the tag libs.

You can also use it in conjunction with the tag libs. An easy example, for instance, is may--say I want to have a woe repetition. Well, you may be thinking, but that's funny. Woe repetitions don't take vectors. Woe repetitions take NSArrays. If you need to pass an NSArray to the woe repetition, you need to do it using this.

OK. Or you could do it inside of a bean or something like that. But for now, that's the idea. The only important thing about this is that you have to make sure that the WebObjects stack is initialized first, unless you're guaranteed that somebody either hit your application as a Servlet or-- Yeah. Or invoked a tag lib earlier. Obviously, you know, in the Servlet adapter and in the tag lib code, we initialize the WebObjects stack for you if it hasn't been already.

But in case that hasn't happened, you need to init it, and that's the line to do it. OK. It's pretty cheap, so if you're uncertain, if there's like, you know, four or five pages where you're thinking, oh, somebody could hit the page, you know, any one of these pages first, feel free to put it on all of them. It's not very expensive once it's actually been initialized.

And for instance, this is some direct references code. So I had a WO, a WO, custom WO component, my WO rep component, which is basically has a WO repetition that spits out some interesting information about each EO in the array. So I init the statics, create a fetch specification, which I'm not going to sing about, grab the editing context, get an array, pass it in, everything's hunky dory and spanky good. I don't know where that came from.

Okay, so we have, we're just going to give a quick, for a quick example. So this is the welcomeJSP class. You can take a look at it. And the JSP's not terribly complicated. We only have a single component, hello, and it doesn't really take any bindings. See? Really, it doesn't take any bindings. So when we run the application and we take a look at it, it looks pretty simple.

Dum dum da dum dum dum dum dum. Hello. OK. So let's look at something a little bit more complicated. And the next one we're going to look at is the dining well. And this is basically an example of using two components. We use the hello world component, or the hello component that we used before, and we have a favorite food component that takes a couple of windings. We also strip body content out of it. So let's take a look at the component, or the favorite food component real quick.

: Yeah, it doesn't hurt. Yeah, so it's your basic component. It takes two bindings. Everybody's happy. And you can see, because Megan jumped the gun on me, it works. Worf's favorite food is actually gach. That's French, isn't it? Oh, sorry. Okay. So now let's take a look at direct action code.

The direct action code is pretty similar. It's pretty easy. We're being very explicit about it. We're invoking the login action on the direct action class. We could have actually omitted the direct action call, but again, you know, it never hurts to be sure and safe. So we pass in two form values, visitor name and favorite food. Let's take a look at the code. Oh, sorry. Wait, wait. Don't make it go away yet. We can do this in a different order. Is that okay? All right.

Too late. No, it's back. You're teasing me. Stop it. OK. So we have the favorite food, you know, we have the food inquiry component. You have a visitor name and a favorite food. It's very simple. It's your basic hello world thing. You take some input, you spit it back out. Those are just woe strings. Let's take a look at the direct action.

Really big direct action. You can see the log in action. All we do is we grab the form values. We don't have to, I mean, this should look very simple. Grab the form values, stuff them into the, the result page, and return the result page. And there we are. So let's try it.

If you haven't noticed, actually, because of the fact that the JSPs are set to compile to Servlets, and Tomcat is set to do this the first time a JSP is hit, the first time you hit the JSP, it'll be a little bit slow. You can actually set most containers so that it'll precompile all the JSPs for a particular context. Almost got you. For a particular context right at startup.

All right. Pooh's favorite food is honey. My favorite food is honey. That's good. I'm Pooh. All right. And finally-- Do I not look like a teddy bear? The Chinese poo. It works. All right. So this is the direct references code. This is a little bit simpler. We init the statics, and then what we do is just create an NSMutable array of strings. We just create an NSMutable array, add some strings, and then we just pass it to a component. OK. Finish. Yeah. Music genres. So scroll down a bit.

I think you can see we just passed in the genres. And then, you know, you saw where we had to import com WebObjects scroll all the way to the top. And it's really Java code, right? Import com WebObjects Foundation, import com WebObjects JSP Servlet. We do all this nice stuff.

Again, this isn't really a tutorial on how to write good JSP pages, because honestly we would prefer you to write WebObjects pages. But if you were doing this in JSP, you would probably spit this out into a bean or something somewhere. And let's run it. And does it work? Boy, do I hope so.

It worked. Yay! Okay, so that was our demo of using JSP, Direct Actions, and Direct References with the WebObjects application in a Servlet container on Thursday. Thank you, Megan. All right. Demo. Let's talk about where we're going. We, you know, we obviously know that there are some shortfalls in the way that we're doing this. And the biggest shortfall, of course, is the need to install WebObjects on the server that has the servlet container. So what we're trying to do for a future version of WebObjects is something called servlet single directory deployment.

This is a very complicated name, and basically what it means is we have, instead of a war file and then a WebObjects installation, we have a single directory, a single folder that has everything inside of it. It'll be totally stand-alone. All you need to do is take that one folder and deploy it in your servlet container and all will be happy.

OK. You won't need to set system properties. You don't need to modify the WebXML to change those wo root, local root, wo install root, or anything else like that. It's completely self-contained. You can take this folder, you can move it from app server to app server, platform to platform.

Now, the caveat is that this works on most, but not all, servlet containers. This is one of those areas where the spec is a little bit, you know, Weasley, I mean, most containers will let you do it. There are a couple that have some bugs because it's not, you know, it's not amazingly common.

But so far it seems to work pretty well. We've tried it with Tomcat on various settings, and we've tried it with the new WebLogic and some other apps, some other servers, and it seems to work okay. It's controlled by a new build setting, or makefile variable. Servlet singled or deploy, and it's not complicated. You say yes or no, and it just does the thing.

And we have come to the end of my presentation. I hope you've enjoyed listening to me talk and babble for almost an hour now about JSPs, Servlets, and WebObjects. And we're hoping that you can use this to go out and really, you know, put WebObjects in places where you want to use it, where it's going to make you money, where it's going to make other people money, and at the same time you can make all the pointy-haired people happy. So, thank you very much for attending, and we're on to the end slides.

Sorry, the ending was weak. Anyway, so the WebObjects beta. Just in case you haven't heard it before, Appleseed.apple.com/webobjects. It's also a good anime in case any of you haven't seen it. Appleseed, very good. OK. The WebObjects lab has a lot of times which are in the past. And it's--well, it's true.

And it's still open today. It'll be open tomorrow. I suggest you can go down there. There's at least one machine down there that has Tomcat installed, and we may be able to demo this for you if you're interested in looking at it. And, you know, you can always chat. I think I'll be down there from, you know, about 5 to 6 or something like that today. So if you have any additional questions or you want to see if something works, come ask me.

The roadmap. EJB is gone. It's totally passe. It was this morning. And deploying WebObjects applications was really cool, but it's done. It's deployed. We're talking about a different thing now. And finally, the only chance you have, the feedback forum. That's pretty much it. So, go to the feedback forum. Tell them that you want to be able to run WebObjects on your Palm Pilot or whatever. OK, please, don't. Because I'll probably have to do it, and I don't.

So who do you talk to? Tony Trujillo. She's the director. You can reach her at [email protected]. There's also Bob Fraser, who apparently from the email address is actually Tony Trujillo in disguise, because she's also at [email protected]. It's very interesting that I've never seen the two of them in the same place at the same time.

In case you're having trouble, of course, you know we offer our standard training, support consulting. It's right there. It's an NSRA printed out. Apple Professional Services, and we have this nice phone number and services at apple.com, blah, blah, blah. It's good for you. You should try it sometime.

For more information, I'm not even going to try to read all of these URLs to you. You can either copy them down, or I'm sure there's, isn't there some sort of, like, one URL that you can go to that has all of these things on it, like a single page with everything? Right. Find that page.

It's the one page to-- It's true. It's the one page to rule them all. You hit that, you get all of these end slides. You won't have to worry about a dang thing. You won't be sitting here like, oh, wait, what was that URL? But you're good now. It's fine. I'm calm.

This is the documentation plug. We were working on the presentations and the documentation guy came running up to me. He's like, "You have to plug the documentation. It's so good." And I said, "Yeah, it's good, so let's plug it." All right. This is the documentation. Isn't it a nice picture? It's developing applications using Java server pages and servlets. It pretty much just walks through the entire presentation that I did.

You know, it walks you through creating that last application that I showed you where you build, you know, a couple of JSP components and the WebObjects stuff. It's actually quite well written, so it's worth looking into. And of course, the basic discovering WebObjects for HTML, which you can actually get a free copy of because they're sitting over there. They're also going to be down in the lab later, and probably at the feedback forum.

It's a good book. It's a nice beginner book, sort of a get to know WebObjects sort of thing, and we're giving them out. So take one. Give it to your friends. Hang it up in your car or something so that people walk by and say, what is Discovering WebObjects for HTML? And you can, you know, hand it to them and say, it's this wonderful application server that Apple has that will make you tons and tons of money. And then they look at you and say, but I train parakeets. And, you know, you say, well, you could do it over the Web.

It's All right. The best way to access documentation, the most up to date is always the PDF and the HTML on the website, because Apple has control of that, and they can't really, you know, like, telnet into your machine and fix your documentation. Actually, we could. Oh, I wasn't supposed to say that on stage. I'm just kidding. All right. So, you know, all the standard stuff. You can hard copy print on demand. It's on the CD. You did buy the CD, right? No piracy here. We're all very good developers.

And it's in the box. The nice thing about the box, of course, is it's localized. Everybody's happy. And then, you know, ADC. Check up on it. You can sign up for free. You know, if anybody asks, you can sign up for ADC for free, and I believe you can get a free download, a trial download at 5.1, right? Yeah.

And it doesn't cost anything, right? So if you're interested in this stuff, go to ADC, sign on as a free developer, download the demo. It's a trial. It lasts until, like, the end of June or June, end of June. And play with it. Tell your friends about it. Do whatever. I mean, you can download the trial for free. We're giving out the intro book for free. Have a blast.