Chapter: Internet & World Wide Web HOW TO PROGRAM - Rich Internet Application Server Technologies - Web Services

| Study Material, Lecturing Notes, Assignment, Reference, Wiki description explanation, brief detail |

Creating a Blackjack Web Service

Our next example is a web service that assists you in developing a blackjack card game.

Creating a Blackjack Web Service


Our next example is a web service that assists you in developing a blackjack card game. The Blackjack web service (Fig. 28.13) provides web methods to shuffle a deck of cards, deal a card from the deck and evaluate a hand of cards. After presenting the web service, we use it to serve as the dealer for a game of blackjack (Fig. 28.14). The Blackjack web service uses an HttpSession object to maintain a unique deck of cards for each client ap-plication. Several clients can use the service at the same time, but web method calls made by a specific client use only the deck of cards stored in that client’s session. Our example uses the following blackjack rules:


Two cards each are dealt to the dealer and the player. The player’s cards are dealt face up. Only the first of the dealer’s cards is dealt face up. Each card has a value. A card numbered 2 through 10 is worth its face value. Jacks, queens and kings each count as 10. Aces can count as 1 or 11—whichever value is more beneficial to the player (as we will soon see). If the sum of the player’s two initial cards is 21 (i.e., the player was dealt a card valued at 10 and an ace, which counts as 11 in this situation), the player has “blackjack” and immediately wins the game—if the dealer does not also have blackjack (which would result in a “push”—i.e., a tie). Otherwise, the player can begin taking additional cards one at a time. These cards are dealt face up, and the player decides when to stop taking cards. If the player “busts” (i.e., the sum of the player’s cards exceeds 21), the game is over, and the player loses. When the player is sat-isfied with the current set of cards, the player “stands” (i.e., stops taking cards), and the dealer’s hidden card is revealed. If the dealer’s total is 16 or less, the dealer must take another card; otherwise, the dealer must stand. The dealer must continue taking cards until the sum of the dealer’s cards is greater than or equal to 17. If the dealer exceeds 21, the player wins. Otherwise, the hand with the higher point total wins. If the dealer and the player have the same point total, the game is a “push,” and no one wins. Note that the value of an ace for a dealer depends on the dealer’s other card(s) and the casino’s house rules. A dealer typically must hit for totals of 16 or less and must stand for totals of 17 or more. However, for a “soft 17”—a hand with a total of 17 with one ace counted as 11—some casinos require the dealer to hit and some require the dealer to stand (we require the dealer to stand). Such a hand is known as a “soft 17” because taking another card cannot bust the hand.


The web service (Fig. 28.13) stores each card as a String consisting of a number, 113, representing the card’s face (ace through king, respectively), followed by a space and a digit, 03, representing the card’s suit (hearts, diamonds, clubs or spades, respectively). For example, the jack of clubs is represented as "11 2", and the two of hearts is represented as "2 0". To create and deploy this web service, follow the steps presented in Sections 28.3.2–28.3.3 for the HugeInteger service.


154   // Fig. 28.13:


155   // Blackjack web service that deals cards and evaluates hands


156   package com.deitel.iw3htp4.ch28.blackjack;


203   import java.util.ArrayList;


204   import java.util.Random;


205   import javax.annotation.Resource;


206   import javax.jws.WebService;


207   import javax.jws.WebMethod;


208 import javax.jws.WebParam;


209 import javax.servlet.http.HttpSession;


210 import javax.servlet.http.HttpServletRequest;


211 import;


212 import;


205 @WebService( name = "Blackjack", serviceName = "BlackjackService" )


206 public class Blackjack

207 {


208       // use @Resource to create a WebServiceContext for session tracking


209       private @Resource WebServiceContext webServiceContext;


210       private MessageContext messageContext; // used in session tracking


211       private HttpSession session; // stores attributes of the session


1             // deal one card


2             @WebMethod( operationName = "dealCard" )


3             public String dealCard()

4             {


5                    String card = "";


7                    ArrayList< String > deck =


8                          ( ArrayList< String > ) session.getAttribute( "deck" );


10                 card = deck.get( 0 ); // get top card of deck


11                 deck.remove( 0 ); // remove top card of deck


39                 return card;


40          } // end WebMethod dealCard


1             // shuffle the deck


2             @WebMethod( operationName = "shuffle" )


3             public void shuffle()

4             {


5                    // obtain the HttpSession object to store deck for current client


6                    messageContext = webServiceContext.getMessageContext();


7                    session = ( ( HttpServletRequest ) messageContext.get(


8                          MessageContext.SERVLET_REQUEST ) ).getSession();


9                    // populate deck of cards


10                 ArrayList< String > deck = new ArrayList< String >();


19                 for ( int face = 1; face <= 13; face++ ) // loop through faces


20                       for ( int suit = 0; suit <= 3; suit++ ) // loop through suits

53                      deck.add( face + " " + suit ); // add each card to deck


24                 String tempCard; // holds card temporarily during swapping


25                 Random randomObject = new Random(); // generates random numbers


26                 int index; // index of randomly selected card


31                 for ( int i = 0; i < deck.size() ; i++ ) // shuffle

32                 {


33                       index = randomObject.nextInt( deck.size() - 1 );


36                       // swap card at position i with randomly selected card


37                       tempCard = deck.get( i );


38                       deck.set( i, deck.get( index ) );


39                       deck.set( index, tempCard );


40                 } // end for


41                 // add this deck to user's session


42                 session.setAttribute( "deck", deck );


43          } // end WebMethod shuffle


46          // determine a hand's value


47          @WebMethod( operationName = "getHandValue" )


48          public int getHandValue( @WebParam( name = "hand" ) String hand )

49          {


50                 // split hand into cards


51                 String[] cards = hand.split( "\t" );


52                 int total = 0; // total value of cards in hand


53                 int face; // face of current card


54                 int aceCount = 0; // number of aces in hand


53                 for ( int i = 0; i < cards.length; i++ )

54                 {


55                       // parse string and get first int in String


face = Integer.parseInt(

87        cards[ i ].substring( 0, cards[ i ].indexOf( " " ) ) );


89        switch ( face )

90        {



91        case 1: // if ace, increment aceCount

92        ++aceCount;

93        break;

94        case 11: // jack

95        case 12: // queen

96        case 13: // king

97        total += 10;

98        break;

99        default: // otherwise, add face

100      total += face;

101      break;

102      } // end switch

103      } // end for



105      // calculate optimal use of aces

106      if ( aceCount > 0 )

107      {


108      // if possible, count one ace as 11

109      if ( total + 11 + aceCount - 1 <= 21 )

110      total += 11 + aceCount - 1;


111      else // otherwise, count all aces as 1


112      total += aceCount;

113      } // end if


115      return total;


116      } // end WebMethod getHandValue


117      } // end class Blackjack


Fig. 28.13 | Blackjack web service that deals cards and evaluates hands.


Session Tracking in Web Services

The Blackjack web service client first calls method shuffle (lines 40–71) to shuffle the deck of cards. This method also places the deck of cards into an HttpSession object that is specific to the client that called shuffle. To use session tracking in a Web service, you must include code for the resources that maintain the session state information. In the past, you had to write the sometimes tedious code to create these resources. JAX-WS, how-ever, handles this for you via the @Resource annotation. This annotation enables tools like Netbeans to “inject” complex support code into your class, thus allowing you to focus on your business logic rather than the support code. The concept of using annotations to add code that supports your classes is known as dependency injection. Annotations like @Web-Service, @WebMethod and @WebParam also perform dependency injection.


Line 20 injects a WebServiceContext object into your class. A WebServiceContext object enables a web service to access and maintain information for a specific request, such as session state. As you look through the code in Fig. 28.13, you’ll notice that we never create the WebServiceContext object. All of the code necessary to create it is injected into the class by the @Resource annotation. Line 21 declares a variable of interface type MessageContext that the web service will use to obtain an HttpSession object for the current client. Line 22 declares the HttpSession variable that the web service will use to manipulate the session state information.


Line 44 in method shuffle uses the WebServiceContext object that was injected in line 20 to obtain a MessageContext object. Lines 45–46 then use the MessageContext object’s get method to obtain the HttpSession object for the current client. Method get receives a constant indicating what to get from the MessageContext. In this case, the constant MessageContext.SERVLET_REQUEST indicates that we’d like to get the HttpServlet-Request object for the current client. We then call method getSession to get the HttpSession object from the HttpServletRequest object.


Lines 49–70 generate an ArrayList representing a deck of cards, shuffle the deck and store the deck in the client’s session object. Lines 51–53 use nested loops to generate Strings in the form "face suit" to represent each possible card in the deck. Lines 59–67 shuffle the deck by swapping each card with another card selected at random. Line 70 inserts the ArrayList in the session object to maintain the deck between method calls from a particular client.

Lines 25–37 define method dealCard as a web method. Lines 30–31 use the session object to obtain the "deck" session attribute that was stored in line 70 of method shuffle. Method getAttribute takes as a parameter a String that identifies the Object to obtain from the session state. The HttpSession can store many Objects, provided that each has a unique identifier. Note that method shuffle must be called before method dealCard is called the first time for a client—otherwise, an exception occurs at line 33 because get-Attribute returns null at lines 30–31. After obtaining the user’s deck, dealCard gets the top card from the deck (line 33), removes it from the deck (line 34) and returns the card’s value as a String (line 36). Without using session tracking, the deck of cards would need to be passed back and forth with each method call. Session tracking makes the dealCard method easy to call (it requires no arguments) and eliminates the overhead of sending the deck over the network multiple times.

Method getHandValue (lines 74–116) determines the total value of the cards in a hand by trying to attain the highest score possible without going over 21. Recall that an ace can be counted as either 1 or 11, and all face cards count as 10. This method does not use the session object because the deck of cards is not used in this method.


As you’ll soon see, the client application maintains a hand of cards as a String in which each card is separated by a tab character. Line 78 tokenizes the hand of cards (rep-resented by hand) into individual cards by calling String method split and passing to it a String containing the delimiter characters (in this case, just a tab). Method split uses the delimiter characters to separate tokens in the String. Lines 83–103 count the value of each card. Lines 86–87 retrieve the first integer—the face—and use that value in the switch statement (lines 89–102). If the card is an ace, the method increments variable aceCount. We discuss how this variable is used shortly. If the card is an 11, 12 or 13 (jack, queen or king), the method adds 10 to the total value of the hand (line 97). If the card is anything else, the method increases the total by that value (line 100).


Because an ace can have either of two values, additional logic is required to process aces. Lines 106–113 of method getHandValue process the aces after all the other cards. If a hand contains several aces, only one ace can be counted as 11. The condition in line 109 determines whether counting one ace as 11 and the rest as 1 will result in a total that does not exceed 21. If this is possible, line 110 adjusts the total accordingly. Otherwise, line 112 adjusts the total, counting each ace as 1.


Method getHandValue maximizes the value of the current cards without exceeding 21. Imagine, for example, that the dealer has a 7 and receives an ace. The new total could be either 8 or 18. However, getHandValue always maximizes the value of the cards without going over 21, so the new total is 18.

Study Material, Lecturing Notes, Assignment, Reference, Wiki description explanation, brief detail

Copyright © 2018-2020; All Rights Reserved. Developed by Therithal info, Chennai.