Beyond Java Servlet Programing OReilly Conference on Java
Beyond Java Servlet Programing O'Reilly Conference on Java March, 2000 Copyright 2000, K&A Software
Introductions Jason Hunter jasonh@kasoftware. com K&A Software http: //www. kasoftware. com http: //www. servlets. com Author of "Java Servlet Programming" (O'Reilly)
Overview • This talk will: – Explain the history of servlets – Describe in detail what's new in API 2. 2 – Introduce the exciting new Web Application concept – Show to use deployment descriptors – Explain the new rules for distributed apps – Describe how to control response buffering – Show the new header manipulation methods – Demonstrate new internationalization support – Explain the new role-based security mechanism – Talk about Project Jakarta • If you want an introduction to servlets, THIS IS NOT IT!
Servlet Timeline • December 1996 – Java. Soft Servlets first introduced (Java Web Server) • June 1997 – Servlet API 1. 0 finalized (JSDK 1. 0) • December 1997 – Servlet API 2. 0 introduced (JWS 1. 1) • April 1998 – Servlet API 2. 0 finalized (JSDK 2. 0) • November 1998 – Servlet API 2. 1 introduced (specification) • April 1999 – Servlet API 2. 1 finalized (JSDK 2. 1) • August 1999 – Servlet API 2. 2 introduced (specification) • December 1999 – Servlet API 2. 2 finalized (Jakarta)
Differences From 1. 0 to 2. 1 • Differences between 1. 0 and 2. 0 – Support for internationalization – Support for cookies – Support for built-in session tracking – New Single. Thread. Model interface – Support for HTTP/1. 1 • Differences between 2. 0 and 2. 1 – The API was been "cleaned up" – Support for request dispatching – Support for sharing information via contexts – Support for getting resources in an abstract way – More control over session management – First release of a specification!
Differences From 2. 1 to 2. 2 • Differences between 2. 1 and 2. 2 – Servlets are now part of J 2 EE – Introduced notion of pluggable Web applications – Clarified rules for back-end server distribution – Added response output buffering – Enhanced control over HTTP headers – Gave new ways to do request dispatching – Provided advanced error handling – Several method signatures have been changed for consistency
Servlets in J 2 EE • The servlet API is now a required API of the Java 2 Platform, Enterprise Edition (J 2 EE, jatooee) • No real effect to servlet developers – Except "servlet engine" has become "servlet container" • Enterprise developers are guaranteed support for servlets along with the other enterprise APIs – Lucky developers!
Web Applications • Web Applications may change the way the Web works. – A collection of servlets, Java. Server Pages (JSPs), HTML documents, images, and other Web resources – Portably deployable across any servlet-enabled Web server – Simple install, with full configuration information in the web app – Plug in a search engine, guestbook app, store front, etc • Web apps can be deployed using a single archive file – Have file extension. war – Stands for "Web application archive" – Created using "jar" tool – Can be digitally signed
This is WAR • Inside a war you might find these files: index. html feedback. jsp images/banner. gif WEB-INF/web. xml WEB-INF/lib/jspbean. jar WEB-INF/classes/Corp. Servlet. class WEB-INF/classes/com/corp/db/Support. Class. class • On install, a war is mapped to a URI prefix on the server – Assume this war is assigned prefix /demo – /demo/index. html serves index. html – /demo/servlet/Corp. Servlet serves Corp. Servlet
Inside WEB-INF • WEB-INF contains classes and configuration info – Modeled after META-INF in JARs – Content is not served directly to the client – WEB-INF/classes contains servlets and supporting class files – WEB-INF/lib contains JAR files, automatically searched – WEB-INF/web. xml is a deployment descriptor • The deployment descriptor contains app configuration info – It's an XML file with a DTD specified in the Servlet specification
The web. xml File • The web. xml deployment descriptor DTD contains over 50 tags to specify: Graphical icon files for the application – For GUI manipulation A description of the app – What the app does, who wrote it, where it can be found A flag indicating whether or not the app can be distributed – Distributed apps can be spread across multiple back-end servers, must follow stricter rules than non-distributed apps Parameter information for the app – Essentially app-level init parameters
The web. xml File, Cont'd Registered servlet names – A place to register servlets and give them names Servlet init parameters – Alter servlet behavior via params Servlet load order – Which servlets are preloaded, and in what order. URL mapping rules – Standardized mappings from URLs to servlets – Can be explicit (/foo. html), prefix-based (/lite/*), or extension-based (*. jsp) Session timeout defaults – How many minutes of client inactivity before a timeout File extension to MIME type mappings – Say. java should be served as text/plain
The web. xml File, Cont'd A welcome file list – An ordered list of files to serve by default (index. jsp, index. html, index. htm) Error-handling rules – Custom handling for error codes or exceptions References to external data sources, such as JNDI – Add resources into the JNDI lookup table Security constraints – Dictate which pages must be protected, and how – Includes built-in form-based authentication • For the full DTD see http: //java. sun. com/j 2 ee/dtds/web-app_1_2. dtd
Web Apps: A Programmer's View • To a programmer, a web app corresponds to one Servlet. Context object – All servers have at least a default context – Shared app data can go in the context using set. Attribute() and get. Attribute() – Each context also has separate Http. Session data • Web app parameters are available using context. get. Init. Parameter(String name) • The URI prefix can be retrieved with req. get. Context. Path() – Returns "/demo" or "" for default • Make sure not to use the URI prefix with get. Request. Dispatcher() and get. Resource() – To do so would limit portability
Context Method Example public void do. Get(. . . , . . . ) throws. . . { res. set. Content. Type("text/plain"); Print. Writer out = res. get. Writer(); out. println("My context path is: " + req. get. Context. Path()); out. println("My context parameters are: "); Servlet. Context context = get. Servlet. Context(); Enumeration e = context. get. Init. Parameter. Names(); while (e. has. More. Elements()) { String name = (String) e. next. Element(); Object value = context. get. Init. Parameter(name); out. println(name + ": " + value); } Request. Dispatcher dispatcher = context. get. Request. Dispatcher("/servlet/Buy. Now"); dispatcher. include(req, res); } • Remember, this code won't compile on most of today's servers.
Lifecycle Clarifications • Newly defined: There's exactly one servlet instance per definition (registered name) per context. – Allows instance variables to hold state information – Servlets did this before, now it's guaranteed to work • Also defined: Servlets sharing information via their context must not experience any unexpected Class. Cast. Exception – Thrown when same class is loaded by different class loaders – So now any servlet reload may cause a full context reload
Distributed Applications • Mark an app "distributable" using the deployment descriptor • A distributed app must put only Serializable objects in user sessions – Supports the server moving data between servers – Server may throw Illegal. Argument. Exception if the stored object is not Serializable – Servers use session affinity for efficiency – (So requests from a particular user are handled by one JVM at a time) • A distributed app must use external resources (database, EJB) to share app information – There's one Servlet. Context instance per JVM – Information placed into the context is not transferred
Response Buffering • In 2. 2, servlets can control response buffering – Previously servers had control over buffering – Most had buffers around 8 K – Now servlets can specify the minimum buffer required • This allows flexibility in error handling – In HTTP the status code (indication of error) must come first – Impossible to set once response has been "committed" with data sent – Larger buffers allow more output to be written before commit
Response Buffering Methods • void set. Buffer. Size(int size) – Specifies minimum buffer size in bytes – Server may use a larger buffer than requested – Set before writing output! • int get. Buffer. Size() – Returns actual buffer size • boolean is. Committed() – Returns if response is committed • void reset() – Empty buffer and unset headers – Called by send. Error() and send. Redirect() • void flush. Buffer() – Sends buffer contents and commits
A Response Buffer Example • This servlet demonstrates response buffering in action. public void do. Get(. . . , . . . ) throws. . . { res. set. Buffer. Size(16 * 1024); // 16 K buffer res. set. Content. Type("text/html"); Print. Writer out = res. get. Writer(); // returns 16384 or greater int size = res. get. Buffer. Size(); out. println("The client won't see this"); reset(); out. println("Nor will the client see this!"); reset(); out. println("Nor this if send. Error() is called"); if (req. get. Parameter("important") == null) { res. send. Error(400, "important param needed"); } }
Support for Double Headers • A servlet can now retrieve and set multiple headers of the same name. • Enumeration get. Headers(String name) – Returns multiple values for a given header as Enumeration of String objects – Useful for headers like Accept-Language: en Accept-Language: fr Accept-Language: ja • void add. Header(String name, String value) – Adds another value for the given header – Unlike set. Header() which replaces previous values – Also add. Int. Header() and add. Date. Header()
Now This Is Just Temporary • Servlets often need to write temporary files – There's now a standard location – Each context has a separate directory – Attribute "javax. servlet. context. tempdir" // The directory is given as a File object File dir = (File) get. Servlet. Context(). get. Attribute( "javax. servlet. context. tempdir"); // Make temp file in temp dir (JDK 1. 2) File f = File. create. Temp. File("xxx", ". tmp", dir); // Prepare to write to the file File. Output. Stream fout = new File. Output. Stream(f); //. . .
No More Amnesia • Previously servlets had no way to determine their own name! • The name is now available using get. Servlet. Name() – This helps servlets store state information – Using the name as part of the lookup key keeps data unique per instance public void do. Get(. . . , . . . ) throws. . . { // Inherited from Generic. Servlet String name = get. Servlet. Name(); Servlet. Context context = get. Servlet. Context(); Object value = context. get. Attribute(name + ". state"); }
So, Where Are You From? • More internationalization (i 18 n) support has been added in 2. 2. • Locale req. get. Locale() – Returns the client's most preferred locale, based primarily on the Accept-Language header • Enumeration req. get. Locales() – Returns all the client's preferred locales • void res. set. Locale(Locale loc) – Specifies the locale of the response – Automatically sets the Content-Language and Content-Type appropriately – Call this method after calling set. Content. Type(), before get. Writer()
Locales in Action • This servlet demonstrates the new i 18 n support: public void do. Get(. . . , . . . ) { res. set. Content. Type("text/html"); Locale loc = req. get. Locale(); res. set. Locale(loc); Print. Writer out = res. get. Writer(); // Write output based on loc. get. Language() } • Note this isn't as powerful as com. oreilly. servlet. Locale. Negotiator – See http: //www. servlets. com/resources
Servlet Security • A deployment descriptor can set up portable security constraints – Security is role-based – Certain pages can be viewed by users that are part of a given role – For example, only managers can view salary information • The deployment descriptor specifies the access granted to each role – Role to user or role to group mappings are done during deployment – Server-specific tools facilitate this – Users may come from the server, OS, database, and so on
Servlet Security Methods • Two methods were added to support role-based security • java. security. Principal req. get. User. Principal() – Returns a Principal with the name of the client user – Returns null if the user hasn't logged in • boolean req. is. User. In. Role(String role) – Returns true if the current user belongs to the specified role • boolean req. is. Secure() – Returns true if the request was made over a secure channel (HTTPS)
Servlet Security Example • This example snoops the current security information. public void do. Get(. . . , . . . ) { res. set. Content. Type("text/plain"); Print. Writer out = res. get. Writer(); out. println("The current user is: " + req. get. User. Principal()); out. println("Is the user a Manager? " + req. is. User. In. Role("Manager")); out. println("Is our connection secure? " + req. is. Secure()); }
Better Dispatching • API 2. 2 has more convenient request dispatching. • Request. Dispatcher context. get. Named. Dispatcher(String name) – Lets a servlet dispatch to a component specified by name instead of URI path • Lets components stay "private" • Request. Dispatcher req. get. Request. Dispatcher(String path) – Lets a user specify a relative URL target – The context. get. Request. Dispatcher() method must be absolute – No need for that method anymore
Better Redirecting • Finally, API 2. 2 also makes it more convenient to do simple redirects. • void res. send. Redirect(String url) – The redirect URL can now be relative – Clients still demand absolute URLs so the server does translation before sending!
Summary • To summarize… – Java Servlet API 2. 2 makes servlets part of a complete Web application framework – Whole subsections of Web sites can be easily deployed on any Web server that supports API 2. 2 – Servlets have solid rules for distribution across multiple back-end servers – Response buffering has been added to make error handling more robust – HTTP header control has been improved – Request dispatching has been made easier with support for relative paths and named dispatchers
- Slides: 31