CATEGORII DOCUMENTE |
Asp | Autocad | C | Dot net | Excel | Fox pro | Html | Java |
Linux | Mathcad | Photoshop | Php | Sql | Visual studio | Windows | Xml |
Web Applications
Chapter 1 outlined the concepts of MVC and gave a brief discussion of web frameworks. The main reason for that discussion was to help you understand any major web frame-
work that has come out since 2000. In this chapter, however, I want to go over two things: a more detailed review of the web server side, and an introduction to the web applica- tions used in this book.
The fundamental component of any Java web application today is the servlet. It is the common denominator, and back in the '90s many of us wrote entire applications using only servlets. In this chapter, I will quickly cover what a servlet is and then we will get into some actual web application design. You will investigate a few implementation patterns. As I cover each of these implementation patterns used in Seam, I will highlight (when appropriate) the similarities and differences as compared to the Struts framework. This will expose you to more Seam code and should prepare you for Seam coding in Chapter 5.
Three major web applications are used in this book. In this chapter, you will learn about the main applications we are going to build throughout this book.
Servlets
Servlets are the basis for any web application written today. However, they may be one of the least known APIs for new Java developers who started their web development by using a framework such as Struts. The Java Community Process ( JCP) designed the
Servlet specification in 1997 as JSR 53. The most current version of it is defined by JSR 154
and was released in September 2005.
A Servlet object in the most basic sense allows for communication between a client and a server via the Hypertext Transfer Protocol (HTTP). The most common application of this is of course dynamic web pages, although you will find client-side applets talking to servers in the same manner as well.
The Servlet class file resides in the javax.servlet package. Because servlets are a specification and not a Sun implementation, in order to use servlets, one relies on an individual web container vendor such as JBoss (which uses Apache Tomcat) to imple-
ment the specification. The most common implementation of the Servlet interface is the
23
HttpServlet object, which is the basis for most web frameworks. HttpServlet will accept requests (HttpServletRequest), allow for a method for processing, and return a response (HttpServletResponse). In addition, it can keep track of a ServletContext and HttpSession object; I will go over that in more detail in a bit. The HttpServlet object is called by the application server and calls methods (doPost(..), doGet(..), service(..)) that then con- tain data to process the request.
Contexts in Servlets
A context represents an area where serializable objects (classes that implement java.io.Serializable) are stored. These objects differ mainly in their life cycles. Some of the objects are saved indefinitely, whereas others are around for just a short period of time. In servlets there are three contexts by default: the ServletContext context, the ServletRequest context, and the HttpSession context. Each context uses maps for storage.
ServletContext
The ServletContext context is represented by the interface javax.servlet.ServletContext, which you can retrieve with the getServletContext() method on the Servlet object A ServletContext context contains application data that is not user specific. This data can be set at any time and will be stored for as long as the server is alive. The type of data that is stored in a ServletContext context is usually something such as names of states or names of countries-items that are the same for any user and generally not too large.
ServletRequest Context
The ServletRequest context is represented by the interface javax.servlet.ServletRequest, which is passed as a parameter to the Servlet(s) processing methods. The data that is set on ServletRequest is typically tied to a response for a single round-trip to the server. A round-trip consists of a request that originates from the web page, is sent to the servlet, and is then sent back to the web page. After the web page has finished rendering, ServletRequest gets recycled. This object will store data that was sent over-for exam- ple, when you fill out a form online and submit it, the data is saved to the HttpServletRequest object.
HttpSession Context
The HttpSession context is represented by the interface javax.servlet.http.HttpSession, which is stored as a property on the HttpServletRequest interface. HttpSession is created for the user explicitly by the server-side application calling getSession() or getSession(true) on HttpServletRequest. The HttpSession data will persist across multiple
requests to the server on one connection. To understand what I mean by one connection, think of opening a web browser and connecting to a server-that represents one connec- tion to the server. Opening more browser windows will each represent new connections to the server.
The HttpSession data can be destroyed in one of three ways: by explicitly calling the invalidate() method on HttpSession, by shutting down the browser window, or by the connection timing out (which is a configurable option on HttpSession).
Closing Thoughts on Servlet Contexts
Even though all three of these contexts are extremely useful, you cannot do everything you want with them. However, they provide the basis to create other contexts that can be customized to have more functionality. Seam, in fact, uses seven contexts that are all in some ways derived from these three. I will touch on these contexts in Chapter 5 and then go into much greater depth with them in Chapters 6 and 7. For now we will stick with these three.
Servlets and Frameworks
One final thought about servlets before we go on: you can be an experienced developer and have never touched an HttpServlet object. This is because the servlet layer is where frameworks (in general) start their abstraction. So if you are a developer who started cod- ing after about 2002, odds are that you have never had to write a servlet for a job. Even if you were developing before that, you probably had just one servlet sending you some- where else (or for the most part, you should have). However, I wanted this section to give those who are not familiar with servlets a chance to review the basics.
Implementation Patterns
In this section, I am going to present some challenges that arise when designing web applications. Developers face various challenges when creating web applications. These tasks can be described through implementation patterns. For the experienced devel- oper, these patterns will seem quite familiar-for example, displaying lists and logging on to a page. For the entry-level developer, these patterns will seem new but should seem obvious if you have spent any decent amount of time surfing the Web.
Table 2-1 summarizes the patterns discussed in this section. Most of these imple- mentations will be used in this section for finding, updating, and viewing restaurants in a given zip code.
Table 2-1. Presentation Implementation Patterns
Topic Description
Displaying dynamic data We make a request to the server to get the best restaurant and save it to the request object to be displayed on the page.
Requesting and saving data We make a request to the server to get the best restaurant as in the first pattern. However, the user will then be able to change the name of the best restaurant.
Logging in The user passes in a username and password for validation.
If the user is validated, the username will be saved to the
HttpSession context.
Listing and viewing a page We display a list of restaurants. The user can then select one restaurant to view the details of it.
For each pattern, I will explain to you the task at hand and the problem we are try- ing to solve. Then I will present a standard activity diagram indicating how this issue will be solved.
I will first present the Struts implementation of it and then the Seam implementa- tion. I decided to use Struts for the examples mainly because it is simple to understand a Struts Action class even if you have no knowledge of Struts. Also, because Struts is so prevalent in the marketplace, it will either be familiar or provide helpful exposure to the majority of developers out there.
Now the thing to remember is that these are not 100 percent complete code samples. I have left out the JSPs (for Struts) and the JSF pages (for Seam). Also, for the Struts exam- ples I am not actually implementing the business class created. However, the business class will get implemented for the Seam example. This is because Seam essentially skips having to write any servlet-based class and gets you directly to the EJB3 page.
The purpose of these pages is not to give you lots of code examples to learn from, but to give you an ability to compare and contrast what the code looks like in Struts as com- pared to Seam. My hope is that you will start to gain an appreciation for Seam and some of the benefits to using it. As you read along the rest of the book, we will use these imple- mentation patterns at various points to cut down on coding time and increase the clarity of the code. So for right now just look at these patterns from an abstract point of view of how they could help you more.
Before diving into the patterns, you will take a look at brief explanations of the Struts and Seam pages that will be used in the examples.
Understanding the Parts of Our Examples
As I said, these examples are going to have two Java files for them: a Seam one and a Struts one. Because not everyone is going to understand each, I will present a crash course on each example setup.
Struts
For those of you who have never seen Struts, think of this as a crash course. If you understand a Servlet object, you will understand an Action class. The Action classes very much mimic the way a Servlet object looks. Listing 2-1 provides an example of an Action class.
Listing 2-1. An Example of a Basic Struts Class
public class GenericStrutsAction extends Action
}
A couple of these attributes should be familiar to you-HttpServletRequest and
HttpServletResponse, which we have just gone over. The other two objects will take a bit more explanation.
ActionForm is a Struts object used to represent the request data that the user has sent over. This object allows us to have a more concrete implementation that is defined in an XML file. Notice that in the method itself, ActionForm is casted to DynaActionForm. DynaActionForm is a DynaBean, which are type-safe maps. This means that in a configura- tion file, you can specify that this object is being stored as a Boolean. This is useful because all objects sent over from the browser-whether numbers or letters-are strings by default.
Finally, you have ActionMapping, which is used to look up what page to forward the next request to. This allows the user to map names to actual JSP pages. This way, if you decide to change to a different page, you can do it in the XML file instead of changing your code.
Throughout the Struts examples, I will be referring to a business service that is a global property on the Action class. You can think of this as an EJB that has been injected into the Action class. I won't provide concrete implementation of these inter- faces because what they specifically do is not important. The important thing is what the Struts page is doing and how it interacts with the business service.
Seam
Now although it may seem unfair to display a bunch of Seam pages without more expla- nation, the purpose is just to appreciate Seam's simplicity. However, I do want to make a few notes about these pages. The classes are all annotated with @Stateless, which indi- cates that these are all actual stateless session beans (SLSBs). There will be no plumbing code such as Action or Servlet classes to write; that is all handled by the framework. Also the Seam objects each implement an interface. I have not provided a concrete represen- tation of the interface, but just assume it contains the same methods that are on the Seam component itself.
Now that you have the basics underway, I'll start showing some code.
Displaying Dynamic Data
Aside from a perfectly static page of text, a page that is generated by dynamic data is probably one of the most commonly used types of pages. In this example, we have a request made to the server to find the best restaurant for an inputted zip code.
Figure 2-1 shows an activity diagram outlining the steps to take when creating this page. As you can see, after the request is made, the server will retrieve the name of the best
restaurant for display on the page. In Struts this will happen by an Action class calling a business service. Listing 2-2 provides this code.
Listing 2-2. The Struts Action for Retrieving the Best Restaurant
public class LookupRestaurantStrutsAction extends Action
}
|
|
|
|
|
|
|
|
||||
|
|
Figure 2-1. Activity diagram of a call to a stateless page
This code is fairly straightforward, and its steps can be outlined as follows:
1. Retrieve the zip code passed as a request parameter called zipCode.
2. Use our business service to look up the best restaurant by zip code.
3. Set an attribute so we can pass back the restaurant on a request attribute called
bestRestaurant.
4. Finally, look up the success page and return to that page.
Although this is not that complex, remember that we still have to code and inject the business class for it to work, and we have basically spent this entire page setting variables to be sent over and then retrieving the variables. So now let's take a look at the Seam ver- sion of this page in Listing 2-3.
Listing 2-3. The Seam Component for Retrieving the Best Restaurant
@Stateless
@Name("restAction")
public class LookupRestaurantAction implements ILookupRestaurantAction
}
In this page we do not have to explicitly set any variables because that is done for us
by Seam through injection of the variables labeled by the annotations. Additionally, we are already in our business object, so there is no need to call anything else except maybe a database. Not only does the code look cleaner now, but we do not have to worry about the HttpRequest and HttpSession data explicitly; it is handled behind the scenes by Seam.
Requesting and Saving Data
The previous example, although somewhat trivial in problem solving, hopefully exposed you a bit to the power of using Seam over traditional Struts applications. In the following example, we will still be using our restaurant, but this time we are going to save the
restaurant's name. So you will first have to find the restaurant, and then the user can save it back to the page. This is drawn out for you in Figure 2-2.
Figure 2-2. Activity diagram of a call to a page that wants to save and validate data
Just as before, the user makes a request to the server to find the best restaurant, which is a retrieval process. Now the user can also input data and send it back to the server to save a new restaurant. Listing 2-4 shows the Struts version of this code.
Listing 2-4. The Struts Action for Retrieving and Saving the Best Restaurant
public class ChangeRestaurantStrutsAction extends Action else
}
}
Notice that I have introduced a Boolean to decide to save or update. We could have
done this instead with two separate method calls by using DispatchAction. However, for those not too familiar with Struts, I did not want to add to the code's complexity. Also, this example introduced DynaForm. The following steps indicate what the code is doing:
1. Cast the form to its instantiated type.
2. Retrieve the Boolean value to know whether this is a save or update.
3. If it is a save, perform the following:
a. Retrieve the new best restaurant name that we are going to save.
b. Retrieve the zip code we are going to save it to.
c. Save the new best restaurant based on the preceding two parameters.
d. Return to the completePage mapping.
4. If it is not a save, you request the best restaurant for the zip code by performing the following:
a. Retrieve the best restaurant by using the lookup service.
b. Save the best restaurant to the request attribute as we did before.
So as you can see, this code is a bit more complex than before, but using the form object does save some time on more-complex matters. Now let's take a look at the Seam example in Listing 2-5.
Listing 2-5. The Seam Component for Retrieving and Changing the Best Restaurant
@Stateless
@Name('changeRestAction')
public class ChangeRestaurantAction implements IChangeRestaurantAction
public String saveBestRestaurant()
}
As you can see in this example, we only had to add another method to save the restaurant, and we had to simply add another annotation to declare that the restaurant variable can be inputted as well. Quite the minimal modifications for the performance increase.
Logging In
So now that we have covered two basic examples of retrieving and saving data, we are going to go on to another common type of code-for logging in. Now there are lots of different ways to log in to a website and many authentication models to use. In fact, Chapter 8 covers some Seam-specific ways of logging in.
For this example, however, we are going to stick to a very basic authentication process: you attempt to log in with a username and password; if you are verified, your username will be saved to the session. The HttpSession object is a common object for saving login data because it will persist the entire time that you are active on the site. When you read this, do not get too worked up about this login model, but look at it as a way of saving session-related data. Figure 2-3 shows an activity diagram of what we are going to do.
This is a simple one-request run-the user either correctly inputs the username and password and continues, or is rejected to a failure page. Listing 2-6 provides the Struts version of this code.
Listing 2-6. The Struts Page for Logging In to a Website
public class LoginStrutsAction extends Action else
}
}
Figure 2-3. Activity diagram of a call that is for logging in to a page
The biggest difference between this page and the pages you have seen before is that now we are saving to the HttpSession object. Another thing to keep in mind when using Struts or any HttpSession object directly is that even if you retrieve an object from the ses- sion, you cannot just change the object but you will have to reset the attribute on the session again. The steps that this page goes through are as follows:
1. Retrieve the username.
2. Retrieve the password.
3. Call the business service to see whether this is a valid login.
4. If it is a valid login, save the username to the session and return to the
"success" page.
5. If you are not successful, forward to a "failed" page. Listing 2-7 provides the Seam version of this page.
Listing 2-7. The Seam Page for Logging In to a Website
@Stateless
@Name('loginAction')
public class LoginAction implements ILoginAction else
}
}
Again, the majority of this page should seem simple, except all we have to do is label the variable to describe that the object is exposed to HttpSession. You will notice that this code is clean, and once again the amount of code is less. Furthermore, we are even in the business service already!
Listing and Viewing a Page
For our final example, I am going to show off one my favorite features with Seam: its ability to display lists and retrieve them. For this example, we are going to access a page with a list of restaurants. The user then has the ability to click on any of the restaurants and retrieve detailed information about it. Figure 2-4 shows the activity diagram for
our request.
This type of request is fairly standard with web operations. Listing 2-8 shows how we perform this with Struts.
Listing 2-8. The Struts Action for Displaying a List and Retrieving a Specific Restaurant
public class ListOfRestaurantStrutsAction extends Action
return mapping.findForward('success');
}
}
Figure 2-4. Activity diagram showing all the hooks the user needs into the system
Part of the complexity of this code is actually hidden from us right now because we will have to have the business service object retrieve the list. Also notice how having to retrieve the name of the restaurant can be wasteful because it requires a second call to the database. Finally, notice that we would have to keep retrieving the restaurants list each time we switch between viewing one and the list page. This could be resolved by saving the list to HttpSession, but that adds many more problems because you do not want to keep objects in the session forever and will have to determine when to destroy the session. The steps for this operation are as follows:
1. Retrieve the restaurant ID.
2. Retrieve the list of restaurants.
3. Save the list of restaurants to a request variable.
4. If the restaurant ID is populated, we want to retrieve one particular restaurant.
a. Retrieve the restaurant from the database, based on the restaurant ID.
b. Save the restaurant to the request.
Hopefully you can see not only the waste but the issues that can arise if you want to do anything including delete. Even if you saved the Restaurant object to the session and wanted to delete it, you would have to delete from the database and the list. This can all get complicated quickly, but fortunately Seam has a simplistic approach that takes care of all the plumbing for us. You can see this in Listing 2-9.
Listing 2-9. The Seam Component for Displaying a List and Retrieving a Specific Restaurant
@Stateless
@Name('listOfRestAction')
public class ListOfRestaurantAction implements IListOfRestaurantAction
}
Now at first glance this page may seem extremely confusing. After all, before we were
defining the returns, so the page knew where to go. The multiple returns are missing; we are clearly doing two calls as before, yet only one method exists. To explain briefly, we are using annotations to define our list; we then define the selected object on the list, and finally a method to retrieve our list. Chapter 5 provides more detail. This method is where you can start to see the power of Seam. In fact, unlike the other examples that clearly required writing some database code or logic, this is all the code you would need to write on the server, assuming that the Restaurant object is an EB.
Sample Applications
What's a book without examples? Obviously, we need applications on which to base our code. Many books have one example throughout the whole text, and although this can be a good method, it can make it overly complex to understand the sample code when trying to do simple things. Also, Seam provides a variety of business solutions, so one sample that incorporates all of these solutions would be extremely complex.
Instead, I took the approach of giving you a few examples to base your work on. I present examples sporadically throughout the book, depending on the problem needing to be solved. Most of these examples have deployable code in the downloadable source.
However, I present three main examples that create more-robust and solid applica- tions. These examples, more than others, will be referenced throughout the book in different parts depending on what we are doing. I will not provide complete details about each of these examples; however, the downloadable code will have complete working examples of them. The sample code will include everything you need to run the code, including Ant build scripts and database build scripts. You can either set up this code ahead of time, use the code as you go along, or wait until you are done with the
book; the choice is up to you.
■Note Sample code can be downloaded from https://www.integrallis.com/.
Garage Sale
Garage Sale is our basic application for CRUD-based examples (CRUD stands for create, read, update, and delete). The Garage Sale application allows users to add, edit, search, list, and delete garage sales. Within each garage sale is a list of items that a user can view. The person who created the garage sale can add and delete items from the garage sale. These are all the basic options any normal CRUD application gives you. Figure 2-5 pro- vides the database diagram for this application.
Figure 2-5. A database diagram of our Garage Sale application
The database has just two tables: one for the house that is having the sale, and the second for all the items they are selling. One house can therefore have multiple items for sale. Figure 2-6 provides a use case diagram of this event.
As you can see, there are two sets of paths into the application. A seller can go in, cre- ate a garage sale, and add sale items to it. The seller should also be able to delete an item after it's sold or after making a mistake. The seller will be able to get a simple list page of items back for the sale. The potential buyer has but one option, and that is to search for garage sales. After selecting a garage sale to view, the user can then see the items of the garage sale.
|
|
|
|
||
|
|||||
|
|
||||
|
|||||
|
Figure 2-6. Use case diagram of the Garage Sale application
Travel Reservations
The Travel Reservations application is a slightly more-complex system. The goal of this system is to allow booking of flights, hotels, and cars. This system is wizard based and has previous screen items feeding into the next screen. This application allows users to create multiple travel reservations in different screens. Each screen should know its own path, but also should be able to keep track of what's going on in different screens. Figure 2-7 shows the database diagram for the travel reservations database.
The travel reservations system is a more intermediate system. You have three base database lookup tables: Flight, Car, and Hotel. These tables should be loaded dynami- cally when a user enters the page. The list of items is generated on the fly for each page, but on the page itself the items will stay persisted for as long as the user is on the page.
You will notice that there are not many mechanisms to determine what days are available or a subtable for different car types. The main reason for this is to keep the com- plexity down and not worry about fillers.
The tables above the three base tables (FlightBooked, CarBooked, and HotelBooked) will keep track of the dates booked for the user's trip. Finally, the Booking table is there to keep all the data stored for one user. Figure 2-8 shows the user flow for this application.
|
|
|
|
|
|
Figure 2-7. Travel Reservations database diagram
Figure 2-8 shows the user flow for this application.
|
|
|
|
||
|
|||||
|
|
||||
|
|||||
|
Figure 2-8. User flow diagram for travel reservations
Despite having a more complex database than the Garage Sale application, the sys- tem is relatively simple. The user can select airfare, hotel, and a car. The user can choose to work in order or skip certain steps and go to the end. At the end, on the purchase, the transaction is committed to the database.
Ticketing System
Our final example application is a ticketing system. This is the kind of ticketing system that has multiple users requiring input to the same object. Users can interact with the ticket, and supervisors need to approve different areas of the system that other users inputted. Figure 2-9 provides the database diagram for the ticketing system.
Figure 2-9. Database diagram of the ticketing system
This database is simpler
in layout.
It is for a troubleshooting ticket system. There is a
name, description, and severity. You will also notice the
TicketOwner table; this is actually a temporal table.
The end date will be null for the entry that identifies the current owner
of the ticket. This allows you to keep track of who owned
the ticket and when.
Figure
2-10
shows the flow for this application.
|
|
|
||
|
||||
|
|
|||
|
||||
|
Figure 2-10. Navigation diagram for the ticketing system
This navigation diagram shows that there are multiple user interactions with the ticketing system. Users can access the same ticket and perform operations on the ticket within the work flow rules of the ticketing system. You will get to use this application in Chapter 7.
Summary
The goal of this chapter was to introduce you to basic web design concepts. These con- cepts were to make you think about the different problems you may encounter when creating web pages. I presented these problems so you can learn how Seam helps sim- plify handling the sometimes complex issues frequently encountered by web developers.
Even for those who are experienced developers, this chapter should have started to show you the ease that Seam brings you in designing web applications. Of course, you are going to have to wait a few more chapters before diving into full Seam development. I still need to go over the fundamentals of JSF and EJB3 to prepare you to use Seam.
I also briefly discussed the applications we are going to create. These three applica- tions form the backbone of our examples in later chapters. These examples each represent different levels of complexity. I will refer to these in later chapters, so you may want to at least take note of the database diagrams for them.
Politica de confidentialitate | Termeni si conditii de utilizare |
Vizualizari: 932
Importanta:
Termeni si conditii de utilizare | Contact
© SCRIGROUP 2024 . All rights reserved