• Aucun résultat trouvé

What about the XML Syntax?

Dans le document Beginning JSP, JSF and Tomcat (Page 191-195)

stmt.executeUpdate(sql);

}

Listing 6-13 shows the other method, insertOrderDetails.

Listing 6-13. The OrderDetailsPeer.insertOrderDetails Method

public static void insertOrderDetails(Statement stmt, long orderId, Hashtable shoppingCart) throws SQLException {

String sql;

Enumeration enumList = shoppingCart.elements();

while (enumList.hasMoreElements()) {

CartItem item = (CartItem)enumList.nextElement();

sql = "insert into order_details (order_id, book_id, quantity,"

+ " price, title, author) values ('" + orderId + "','"

+ item.getBookID() + "','" + item.getQuantity() + "','"

+ item.getPrice() + "','" + item.getTitle() + "','"

+ item.getAuthor() + "')"

;

stmt.executeUpdate(sql);

} }

The methods throw the SQL exception rather than catch it locally, so that the data manager’s method catches it.

What about the XML Syntax?

In the previous chapter, you have learned about writing JSP documents instead of JPS pages. What impact does that have on what I just said about database access? None! This is a consequence of the MVC model: JSP is the view, while only the model has to do with databases.

However, the switch from traditional to XML syntax has an impact on how you execute the data manager methods. For example, you can write the JSP page OrderConfirmation.jsp to save an order in the database with a couple of scriptlets, as shown in Listing 6-14.

Listing 6-14. OrderConfirmation.jsp

07: <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>

08: <title>Order</title>

09: <link rel="stylesheet" href="/eshop/css/eshop.css" type="text/css"/>

10: </head>

11: <body>

12: <jsp:include page="TopMenu.jsp" flush="true"/>

13: <jsp:include page="LeftMenu.jsp" flush="true"/>

14: <div class="content">

15: <h2>Order</h2>

16: <jsp:useBean id="customer" class="eshop.beans.Customer"/>

17: <jsp:setProperty property="*" name="customer"/>

18: <%

19: long orderId = dataManager.insertOrder(

20: customer,

33: %><p class="error">Unexpected error processing the order!</p><%

34: } 35: %>

36: </div>

37: </body>

38: </html>

Or you can write the JSP document OrderConfirmation.jspx, as shown in Listing 6-15. I have included the whole E-shop project converted to XML format in the software package for this chapter.

You will find it both in WAR format and already expanded in the folder named eshopx. To launch it, similarly to eshop, type http://localhost:8080/eshopx/shop.

Listing 6-15. OrderConfirmation.jspx

15: doctype-public="-//W3C//DTD XHTML 1.0 Strict//EN"

16: doctype-system="http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"

17: />

18: <c:url var="cssUrl" value="/css/eshop.jspx"/>

19: <html xmlns="http://www.w3.org/1999/xhtml">

20: <head>

21: <title>Order</title>

22: <link rel="stylesheet" href="${cssUrl}" type="text/css"/>

23: </head>

29: <jsp:useBean id="customer" class="eshop.beans.Customer"/>

30: <jsp:setProperty property="*" name="customer"/>

31: <eshop:insertOrder var="orderID" customer="${customer}"/>

32: <c:choose>

40: <p class="error">Unexpected error processing the order!</p>

41: </c:otherwise>

Let’s concentrate on the highlighted code, where the actual work is done. The saving of the order information in the database, which you do in the JSP page (Listing 6-14) by executing a data manager’s method (lines 19–22), you do in the JSP document (Listing 6-15) by executing a custom action (line 31).

The same custom action also invalidates the session (which was done in line 24 of the JSP page).

The if/else Java construct in lines 23, 31–32, and 34 of the JSP page becomes in the JSP document the JSTL core construct choose/when/otherwise in lines 32–33, 38–39, and 41–42.

Informing the user of the order acceptance is in HTML and remains basically the same (JSP lines 26–

29 become JSPX lines 34–37). In fact, you could have replaced the scripting expression of the JSP page with the EL expression of the JSP document, making the code identical.

The introduction of the custom action insertOrder is necessary because scriptlets, being Java code, can make assignments and execute methods, while EL expressions cannot. Therefore, when you remove scriptlets because they’re not valid XML code, you have to move the computation to Java beans or custom actions.

In line 5 of OrderConfirmation.jspx, you declare eshop.tld, which contains the definition of the insertOrder action (see Listing 6-16).

Listing 6-16. InsertOrderTag Definition in eshop.tld

<tag>

<description>Insert an order into storage</description>

<display-name>insertOrder</display-name>

<name>insertOrder</name>

<tag-class>eshop.tags.InsertOrderTag</tag-class>

<body-content>empty</body-content>

<attribute>

<name>var</name>

<required>true</required>

<rtexprvalue>true</rtexprvalue>

</attribute>

<attribute>

<name>customer</name>

<required>true</required>

<rtexprvalue>true</rtexprvalue>

</attribute>

</tag>

As you can see, you pass two parameters to the custom action: the name of the variable where the order ID is to be returned, and an object containing the customer data (name, address, and credit-card information). You don’t absolutely need the second parameter, because the action code could have retrieved the customer data from the page context as follows:

(Customer)pageContext.getAttribute("customer")

On the other hand, you could have passed to the action a third parameter referencing the shopping cart, but I decided to let the action retrieve it from the session as follows:

(Hashtable)pageContext.getSession().getAttribute("shoppingCart")

It’s not always obvious what constitutes a better design. I felt that the shopping cart, being a session attribute, was obviously shared across JSP documents. Therefore, it was OK for the action to retrieve it directly from the session. The customer data, however, was a page attribute, normally not shared with other modules. Passing it “behind the scenes” to a Java class didn’t seem appropriate. Listing 6-17 shows you the action code in its entirety.

Listing 6-17. InsertOrderTag.java

public class InsertOrderTag extends TagSupport { static final long serialVersionUID = 1L;

private String var;

private Customer customer;

public void setVar(String var) { this.var = var;

}

public void setCustomer(Customer customer) {

this.customer = customer;

}

public int doEndTag() {

ServletContext context = pageContext.getServletContext();

DataManager dataManager =(DataManager)context.getAttribute("dataManager");

HttpSession session = pageContext.getSession();

@SuppressWarnings("unchecked") Hashtable<String, CartItem> cart =

(Hashtable<String, CartItem>)session.getAttribute("shoppingCart");

long orderID = dataManager.insertOrder(customer, cart);

if (orderID > 0L) session.invalidate();

pageContext.setAttribute(var, new Long(orderID).toString());

return EVAL_PAGE;

} }

Notice how you obtain the servlet context (corresponding to the JSP implicit object application) from pageContext, and from it the data manager, so that you can then execute the same insertOrder method you invoked directly from within the JSP page.

The highlighted line shows that I suppressed a warning. I did it because Eclipse kept complaining about typecasting of a generic Object to the Hashtable type. Normally, a warning tells you that something might be wrong. The use of @suppressWarnings is usually bad practice and encourages a sloppy programming style. In this particular case, I was left with no choice, because Eclipse’s warning was unjustified.

Dans le document Beginning JSP, JSF and Tomcat (Page 191-195)