JSP advanced technology how to develop dynamic websites (with a complete online store)
In recent years, JSP technology has become an excellent dynamic website development technology. Java developers love JSP for various reasons. Some people love the performance of "one-time development and everywhere", while others think that JSP makes Java a user-friendly server-side scripting language. However, the maximum length of JSP is that it separates the page performance from the business logic of the page. In this chapter, we will discuss in depth how to use the JSP Mode 2 architecture to develop websites. This mode can be seen as a server implementation in the common mode browser control mode (Popular Model-View-controller, MVC.
What are the defects of servlets?
When JSP becomes the main technology for developing dynamic websites, someone may ask why we do not emphasize servlets in JSP technology. There is no problem with the application of servlets. They are very suitable for server-side processing and programming, and they will stay in their current location for a long time. However, in terms of structure, we can regard JSP as a high-level abstract Implementation of servlet, especially under servlet 2.2 API. However, you still cannot use servlets without restrictions; they are not suitable for everyone. For example, page designers can easily use HTML or XML tools to develop JSP pages, but servlet is more suitable for backend developers. Is their tool ide ?? A development field that requires more programming training. When publishing a servlet, each developer must be careful to determine that there is no close association between page performance and page logic. You can use third-party HTML packaging tools such as htmlkona to mix HTML and Servlet code. Even so, this flexibility is not enough for you to freely change the style itself. For example, if you want to change from HTML to DHTML, the packaging itself needs to be carefully tested to ensure that the new format can be correctly used. In the worst case, packaging is not available, and you need to respond to Malay dynamic content. Therefore, a new solution is required. You will see that one solution is to mix JSP and servlet.
Different Methods
Early jsp standards provided two methods to use jsp. These methods can be summarized into jsp Mode 1 and jsp Mode 2, the main difference is that the location of processing a large number of requests is different. In Mode 1 (Figure 1), the jsp page responds to the request and returns the result to the customer. There is still a separation between performance and content, because all data is processed by bean. Although Mode 1 can meet the needs of small applications, it cannot meet the requirements of large applications. Mode 1 is widely used, which often causes the page to be embedded with a large number of scripts or java code. Especially when the business logic to be processed is complicated, the situation becomes serious. This may not be a big problem for java programmers. But if the developer is a front-end interface designer ?? This is very common in large projects ,?? It is difficult to develop and maintain code. In any project, such a pattern always leads to unclear responses and difficulties in project management.
The Mode 2 structure shown in Figure 2 is a dynamic content-oriented implementation that combines servlet and jsp technologies. It utilizes the advantages of the two technologies, uses jsp to display pages, and uses servlets to complete a large amount of processing. Here, servlet acts as a controller and is responsible for responding to customer requests. Then, the servlet creates the bean and object required by the jsp, and then decides to send the jsp page to the user based on the user's behavior. Note that the jsp page does not have any commercial processing logic; it simply retrieves the bean or object previously created by the servlet and inserts dynamic content into the predefined template. From the perspective of development, this mode has a clearer page performance and a clear division of developer roles, allowing developers to make full use of the interface designers in the development team. In fact, the more complex the project is, the more obvious the benefits of adopting Mode 2.
To clearly understand the development process of Mode 2, let's take an online music store as an example.
We created a store named "music without borders" to sell music products. The main interface of the "music without borders" online store is a page called "music without borders" (Code 1 ). As you can see, this page is completely focused on the user interface and has nothing to do with the processing logic. In addition, pay attention to another jsp page, Cart. jsp (in Code 2), use <jsp: include page = "Cart. jsp "flush =" true "/>. embedded Eshop. jsp.
Listing 1:
Eshop. jsp
<% @ Page session = "true" %>
<HTML>
<Head>
<Title> music without Borders </title>
</Head>
<Body bgcolor = "#33 CCFF">
<Font face = "Times New Roman, Times" size = "+ 3">
Music without Borders
</Font>
<HR> <p>
<Center>
<Form name = "shoppingform"
Action = "/examples/servlet/shoppingservlet"
Method = "Post">
<B> Cd: </B>
<Select name = Cd>
<Option> yuan/the Guo brothers/China/$14.95 </option>
<Option> Drums of Passion/Babatunde Olatunji/Nigeria/$16.95 </option>
<Option> Kaira/Tounami Diabate/Mali/$16.95 </option>
<Option> The Lion is Loose/Eliades Ochoa/Cuba/$13.95 </option>
<Option> Dance the dedevil Away/Outback/Australia/$14.95 </option>
<Option> Record of Changes/Samulnori/Korea/$12.95 </option>
<Option> Djelika/Tounami Diabate/Mali/$14.95 </option>
<Option> Rapture/Nusrat Fateh Ali Khan/Pakistan/$12.95 </option>
<Option> Cesaria Evora/Cape Verde/$16.95 </option>
<Option> Ibuki/Kodo/Japan/$13.95 </option>
</Select>
<B> Quantity: </B> <input type = "text" name = "qty" SIZE = "3" value = 1>
<Input type = "hidden" name = "action" value = "ADD">
<Input type = "submit" name = "Submit" value = "Add to Cart">
</Form>
</Center>
<P>
<Jsp: include page = "Cart. jsp" flush = "true"/>
</Body>
</Html>
Listing 2:
Cart. jsp
<% @ Page session = "true" import = "java. util. *, shopping. CD" %>
<%
Vector buylist = (Vector) session. getValue ("shopping. shoppingcart ");
If (buylist! = Null & (buylist. size ()> 0 )){
%>
<Center>
<Table border = "0" cellpadding = "0" width = "100%" bgcolor = "# ffffff">
<Tr>
<TD> <B> album </B> </TD>
<TD> <B> artist </B> </TD>
<TD> <B> country </B> </TD>
<TD> <B> price </B> </TD>
<TD> <B> quantity </B> </TD>
<TD> </TD>
</Tr>
<%
For (INT Index = 0; index <buylist. Size (); index ++ ){
CD anorder = (CD) buylist. elementat (INDEX );
%>
<Tr>
<TD> <B> <% = anorder. getalbum () %> </B> </TD>
<TD> <B> <% = anorder. getartist () %> </B> </TD>
<TD> <B> <% = anorder. getcountry () %> </B> </TD>
<TD> <B> <% = anorder. getprice () %> </B> </TD>
<TD> <B> <% = anorder. getquantity () %> </B> </TD>
<TD>
<Form name = "deleteform"
Action = "/examples/servlet/shoppingservlet"
Method = "Post">
<Input type = "Submit" value = "delete">
<Input type = "hidden" name = "delindex" value = <% = index %>
<Input type = "hidden" name = "action" value = "delete">
</Form>
</TD>
</Tr>
<% }%>
</Table>
<P>
<Form name = "checkoutform"
Action = "/examples/servlet/ShoppingServlet"
Method = "POST">
<Input type = "hidden" name = "action" value = "CHECKOUT">
<Input type = "submit" name = "Checkout" value = "Checkout">
</Form>
</Center>
<% }%>
Here, Cart. jsp processes SESSION-based shopping Cart based on MVC mode 1. See the code at the beginning of Cart. jsp:
<%
Vector buylist = (Vector) session. getValue ("shopping. shoppingcart ");
If (buylist! = Null & (buylist. size ()> 0 )){
%>
Essentially, this code extracts the "Shopping Cart" from the SESSION ". If the "Shopping Cart" is empty or is not created, it will show nothing. Therefore, when the user first accesses the application, the interface
If the "Shopping Cart" is not empty, the items selected by the user are retrieved from the car and displayed on the page in sequence:
<%
For (int index = 0; index <buylist. size (); index ++ ){
CD anorder = (CD) buylist. elementat (INDEX );
%>
Once an item description is generated, JSP is used to insert it into the static html page according to the preset template. The following figure shows the user interface after purchasing some items:
One important thing to note is that there is a control Servlet and shoppingservlet. Java for eshop. jsp and cart. jsp processing. The code is in source code 3:
Listing 3:
Shoppingservlet. Java
Import java. util .*;
Import java. Io .*;
Import javax. servlet .*;
Import javax. servlet. http .*;
Import shopping. CD;
Public class shoppingservlet extends httpservlet {
Public void Init (servletconfig conf) throws servletexception {
Super. INIT (CONF );
}
Public void dopost (httpservletrequest req, httpservletresponse res)
Throws servletexception, ioexception {
HttpSession session = req. getSession (false );
If (session = null ){
Res. sendRedirect ("http: // localhost: 8080/error.html ");
}
Vector buylist =
(Vector) session. getValue ("shopping. shoppingcart ");
String action = req. getParameter ("action ");
If (! Action. equals ("CHECKOUT ")){
If (action. equals ("DELETE ")){
String del = req. getParameter ("delindex ");
Int d = (new Integer (del). intValue ();
Buylist. removeElementAt (d );
} Else if (action. equals ("ADD ")){
// Any previous buys of same cd?
Boolean match = false;
CD aCD = getCD (req );
If (buylist = null ){
// Add first cd to the cart
Buylist = new vector (); // first order
Buylist. addelement (ACD );
} Else {// not first buy
For (INT I = 0; I <buylist. Size (); I ++ ){
CD = (CD) buylist. elementat (I );
If (CD. getalbum (). Equals (ACD. getalbum ())){
CD. setquantity (CD. getquantity () + ACD. getquantity ());
Buylist. setelementat (Cd, I );
Match = true;
} // End of if name matches
} // End of
If (! Match)
Buylist. addelement (ACD );
}
}
Session. putvalue ("shopping. shoppingcart", buylist );
String url = "/JSP/shopping/eshop. jsp ";
Servletcontext SC = getservletcontext ();
RequestDispatcher rd = SC. getRequestDispatcher (url );
Rd. forward (req, res );
} Else if (action. equals ("CHECKOUT ")){
Float total = 0;
For (int I = 0; I <buylist. size (); I ++ ){
CD anOrder = (CD) buylist. elementAt (I );
Float price = anOrder. getPrice ();
Int qty = anOrder. getQuantity ();
Total + = (price * qty );
}
Total + = 0.005;
String amount = new Float (total). toString ();
Int n = amount. indexOf (.);
Amount = amount. substring (0, n + 3 );
Req. setAttribute ("amount", amount );
String url = "/jsp/shopping/Checkout. jsp ";
ServletContext SC = getServletContext ();
RequestDispatcher rd = SC. getRequestDispatcher (url );
Rd. forward (req, res );
}
}
Private CD getCD (HttpServletRequest req ){
// Imagine if all this was in a scriptlet... uugly, eh?
String myCd = req. getParameter ("CD ");
String qty = req. getParameter ("qty ");
StringTokenizer t = new StringTokenizer (myCd ,"/");
String album = t. nextToken ();
String artist = t. nextToken ();
String country = t. nextToken ();
String price = t. nextToken ();
Price = price. replace ($,). trim ();
CD cd = new CD ();
Cd. setAlbum (album );
Cd. setArtist (artist );
Cd. setCountry (country );
Cd. setPrice (new Float (price). floatValue ());
Cd. setQuantity (new Integer (qty). intValue ());
Return cd;
}
}
Each time a user adds a product with Eshop. jsp, the page requests control SERVLET. Control the SERVLET to Decide further actions and process the added items. Then, control the SERVLET to instantiate a new bean cd to represent the selected item, and update the shopping cart object before returning to the SESSION.
Listing 4:
CD. java
Package shopping;
Public class CD {
String album;
String artist;
String country;
Float price;
Int quantity;
Public CD (){
Album = "";
Artist = "";
Country = "";
Price = 0;
Quantity = 0;
}
Public void setAlbum (String title ){
Album = title;
}
Public String getAlbum (){
Return album;
}
Public void setArtist (String group ){
Artist = group;
}
Public String getArtist (){
Return artist;
}
Public void setCountry (String cty ){
Country = cty;
}
Public String getCountry (){
Return country;
}
Public void setPrice (float p ){
Price = p;
}
Public float getPrice (){
Return price;
}
Public void setQuantity (int q ){
Quantity = q;
}
Public int getQuantity (){
Return quantity;
}
}
Note that our SERVLET has additional intelligence. If an item is repeatedly selected, no new record is added, but the count is updated on the previous record. The control SERVLET also responds to behaviors in Cart. jsp, such as modifying quantity, deleting products, and checking out. If you check out, you can use the following statement to switch to the Checkout. jsp page (source program 5 ):
String url = "/jsp/shopping/Checkout. jsp ";
ServletContext SC = getServletContext ();
RequestDispatcher rd = SC. getRequestDispatcher (url );
Rd. forward (req, res );
Listing 5:
Checkout. jsp
<% @ Page session = "true" import = "java. util. *, shopping. CD" %>
<Html>
<Head>
<Title> Music Without Borders Checkout </title>
</Head>
<Body bgcolor = "#33 CCFF">
<Font face = "Times New Roman, Times" size = + 3>
Music Without Borders Checkout
</Font>
<Hr> <p>
<Center>
<Table border = "0" cellpadding = "0" width = "100%" bgcolor = "# FFFFFF">
<Tr>
<Td> <B> ALBUM </B> </td>
<Td> <B> ARTIST </B> </td>
<Td> <B> COUNTRY </B> </td>
<Td> <B> PRICE </B> </td>
<Td> <B> QUANTITY </B> </td>
<Td> </td>
</Tr>
<%
Vector buylist = (Vector) session. getValue ("shopping. shoppingcart ");
String amount = (String) request. getAttribute ("amount ");
For (int I = 0; I <buylist. size (); I ++ ){
CD anOrder = (CD) buylist. elementAt (I );
%>
<Tr>
<Td> <B> <% = anOrder. getAlbum () %> </B> </td>
<Td> <B> <% = anOrder. getArtist () %> </B> </td>
<Td> <B> <% = anOrder. getCountry () %> </B> </td>
<Td> <B> <% = anOrder. getPrice () %> </B> </td>
<Td> <B> <% = anOrder. getQuantity () %> </B> </td>
</Tr>
<%
}
Session. invalidate ();
%>
<Tr>
<Td> </td>
<Td> </td>
<Td> <B> TOTAL </B> </td>
<Td> <B >$ <% = amount %> </B> </td>
<Td> </td>
</Tr>
</Table>
<P>
<A href = "/examples/jsp/shopping/EShop. jsp"> Shop some more! </A>
</Center>
</Body>
</Html>
The checkout page simply retrieves the shopping cart from the SESSION and displays each item and total amount. The key here is to end the SESSION, so there is a session. invalidate () call in the page. There are two reasons for this. First, if the SESSION is not terminated, the user's shopping cart will not be initialized. If the user wants to continue purchasing, the car will keep the items he has paid. In addition, if the user leaves without checkout, the SESSION will continue to occupy valid resources until it expires. The expiration time is usually 30 minutes. On a large site, such a situation will soon cause resource depletion. Of course, this is what we don't want to see.
Note that all resource allocation is SESSION-based in this example. Therefore, you must make sure that the control SERVLET is not accessed by users, even unexpected access is not allowed. This can be handled by a simple redirect error page when the control detects an illegal access. See Source Code 6.
Listing 6:
Error.html
<Html>
<Body>
<H1>
Sorry, there was an unrecoverable error!
Please try <a href = "/examples/jsp/shopping/EShop. jsp"> again </a>.
</H1>
</Body>
</Html>
Summary
The discussion in this chapter shows that in usage mode 2, JSP and SERVLET functions can be separated to the maximum extent. Correct use of Mode 2 leads to a centralized control SERVLET and only display JSP pages. On the other hand, the implementation of Mode 2 is very complicated. Therefore, in simple applications, you can consider using mode 1.