Java程序辅导

C C++ Java Python Processing编程在线培训 程序编写 软件开发 视频讲解

客服在线QQ:2653320439 微信:ittutor Email:itutor@qq.com
wx: cjtutor
QQ: 2653320439
CSCI398  
Exercise 4: "Enterprise Java Beans"  
This exercise provides some practice in the creation of EJB applications in NetBeans 
and their deployment onto a Glassfish application.  Netbeans 7 for Glassfish version 3.1 
has slightly changed the way in which an application must be built; the examples should work 
in the lab but won’t work with an older version. 
 
There are many additional examples at the NetBeans site 
 
Stateless Session Bean 
 
The first example has a simple stateless session bean with web and “professional” 
client applications.  It is, of course, a variation on the Guru example used elsewhere. 
 
1 Create a new EJB project in NetBeans. 
 
New Java EE Enterprise Application 
 
 
 
 
 
 
 
 
 
 
 
Name the project 
 
Select Glassfish server 
 
 
 
 
 
2 NetBeans creates several separate projects.  There is an overall project, an 
EJB beans project, and a war project (the web client stuff). 
 
 
 
3 The current Netbeans development setup now requires a separate “Java 
library” project to hold the “Remote Interface” components that will be 
generated for client (non-web) applications. 
This “Java library” project must be created before you start to define any 
EJB session beans. 
 
 
 
4 The application client project must also be created: 
 
 
 
 
Should now have the following projects: 
 
 
5 Within the Guru-ejb project, first create a new Java package and then add a 
stateless session bean to this package.   
 
 
 
 
Specify that it should support both local (web) and remote (application-
client) interfaces.  (Netbeans will offer a list of all “Java library” projects 
that it currently knows about – pick the project created for the remote 
interface). 
 
Should now have the following: 
 
 
 
 
6 Write click in the code window for the bean, and pick the “Insert Code” 
option.  It will provide a pop-up menu from which it is possible to select 
the “add business method” option.  This will add a stub to the bean class 
and put the method signature into the local and remote interfaces. 
 
 
 
7 The dialog that pops up for “Add Business Method” has fields for method 
name, return type, arguments, and exceptions: 
 
 
 
8 The stub is added to the bean, and the method is declared in both 
interfaces. 
(A warning appears advising against having same method in both 
interfaces.  This relates to fact that treatment of arguments does differ.  If 
there are no arguments, or the arguments are effectively “const” then there 
are no problems.) 
 
 
 
 
(It’s rare to have to edit the “local” and “remote” interfaces directly; but if 
the methods of your bean use arguments or return results of specialized 
class types you may have to edit the generated interface files to add 
“import” statements.) 
 
9 Define the typical implementation of the Guru’s enlightenMe() method: 
 
 
 
10 Edit the application client.  Again, right-click in the code and pick “Insert 
Code”/”Call Enterprise Bean”.  A dialog will be displayed showing the 
beans that are known to NetBeans at this point; obviously, the only one 
currently defined should be the GuruBean.  The application client will 
need to use this bean through its “Remote” interface. 
  
 
 
The code added is the declaration of a static variable referencing “the 
session bean” and an “annotation”.  You can then add code that invokes a 
method of the “injected” bean. 
 
 
 
The code relyies on “resource injection” – just like the arrangement for 
servlets using JPA.   
 
But what is going to “inject” a reference to the bean? 
 
EJB clients are not run directly (java guruclient.Main).  They are run using 
a “client container” program (“appclient”).  When you run an EJB 
application client, it is actually the appclient program that starts.  It 
examines the code generated for the client that you wrote.  It finds the 
need to “inject” a bean.  It identifies the glassfish server process where that 
bean exists.  (How does it know the server?  There is a deeply hidden 
configuration file in amongst the other files that were created when you 
first set up Netbeans.  It has the address and port number of the glassfish 
server.) 
 
What bean does it use?  Well, the startup code makes contact with the 
glassfish server asking for a reference to a stateless session bean – an 
instance of the GuruBean class.  There isn’t one.  But the server side code 
can create one and return a reference to the one that it created. 
 
 
11 Build the Guru (EJB) project. 
 
12 Make sure Glassfish is running. 
 
 
 
13 Deploy the Guru project 
 
14 Build the GuruClient 
 
15 Run the client (Right-click on project in projects window).  It should run 
(the output here is the line from Oscar Wilde concerning contradiction): 
 
 
 
16 Web-application: 
 Index.jsp – “welcome” page with a link to a servlet 
 GuruServlet – “processRequest” method seeks enlightenment from an 
injected Gurubean; forwards string to JSP for display. 
 Gurudisplay.jsp – page formatting response, embeds enlightenment into 
web page. 
 Guru.gif – image for response page. 
17 Edit the Guru-war project.   
The generated index.jsp page needs some content and a link to a servlet. 
 
 
18 Add a package to the source files section for a new servlet class, and add 
the servlet. 
 
Again, write click in the code and pick “Insert Code”/ “Call Enterprise 
Bean” option: 
 
 
 
The GuruBean will again be selected, but here the local interface will be 
used: 
 
 
 
NetBeans will add the member for referencing the bean along with the 
@EJB annotation (that will in effect expand out to code that gets the 
application engine to “inject” the correct reference). 
 
19 Define an implementation for the servlet that will use the bean to get some 
advice and will forward this advice to a JSP page where it will be 
displayed. 
 
 
 
20 Define the Gurudisplay.jsp page and have it print the advice that gets 
passed as a String attachment to the request object: 
 
 
 
21 Reuild the overall Guru project – it will build the ejb, war, and application 
client projects. 
22 Deploy the overall Guru project. 
If there are problems, you may need to use Glassfish admin console to 
remove existing deployed versions of the Guru.  Then you may need to 
restart Glassfish and again deploy the Guru project.  (The current 
Netbeans/Glassfish combination doesn’t seem to like overwriting existing 
deployments.) 
23 “Run” the project – the default configuration for “run” involves invoking 
the web project.  It should display the “welcome” page (i.e. index.jsp): 
 
(Note, your appserver will almost certainly be using a different port.) 
 
24 Seek advice from the Guru: 
 
 
 
 
. 
Stateful Session Bean 
 
(Grumble: it seems that every year I have to re-work all these examples because of some little change to Netbeans and/or 
Glassfish.  Current (2012) scheme requires that any class – e.g. an application defined exception – that is used in both client and 
server will have to be a part of a separately built “Java library”.  This library has to be compiled and added to other projects 
before any of their code gets defined.) 
 
The second example is a stateful session bean with web and “professional” client 
applications.  It is the “HangMan” game illustrated in lectures 
 
– Game state, held in stateful bean, includes 
– Target word for this player 
– Number of guesses 
– Letters already used as guesses 
. 
1 Create a new Enterprise project “Stateful”.  This should result in Netbeans 
creating an EJB project Stateful; a Stateful-ejb project; and a Stateful-war 
project. 
 
Add a “Java library” project that will be used for the remote interface – 
HangmanRemote 
 
Add another “Java library” project – used to hold an exception class and a 
little struct class used in both clients and server. 
 
Finally, add a class for the client application. 
 
 
 
Should have something like: 
 
 
 
 
2 The classes that go in the Auxclasses project (in an “others” package) are 
the MyException class and the “ResultOfGuess” class (as in lecture notes). 
 
 
 
3 The Auxclasses project should be built and added to the other projects. 
 
 
 
 
 
 
 
 
 
 
 
 
4 Next edit the Hangman-ejb project. 
 
This will need two packages – one for the session bean, and the other for 
auxiliary classes like the dictionary and the string images of hanged men.  
(The source for theses classes can be found in the /share/cs-
pub/398/A4/exercises directory.) 
 
 
5 Add the session bean: 
 
 
 
The stateful session bean holds the data that define the state of play of the 
game: 
The HangManBean has to supply three methods; so add these business 
methods (should appear in both local and remote interfaces): 
 
 
 
ResultOfGuess newGame(); 
boolean gameOverMan(); 
ResultOfGuess handleGuessedLetter( 
  final String guessedLetter) throws MyException; 
 
 
 
  
  Got to add parameters and exceptions. 
 
 
 
 
 
6 NetBeans fills in stubs for these methods in the bean class (and adds them 
to the two interfaces): 
 
 
7 Implement the business methods. 
 
OK – here is the code: 
 
public class HangmanBean implements HangmanRemote, HangmanLocal { 
 
    private boolean gameInProgress; 
    private int numGuesses; 
    private int badGuessCount; 
    private String guessedLetters; 
    private String wordToGuess; 
    private String knownLetters; 
    private static final String letters = 
       "abcdefghijklmnopqrstuvwxyz"; 
 
    public ResultOfGuess newGame() { 
        gameInProgress = true; 
        numGuesses = 0; 
        badGuessCount = 0; 
        guessedLetters = ""; 
        wordToGuess = Dictionary.pickAWord(); 
        int wordlength = wordToGuess.length(); 
        StringBuffer temp = new StringBuffer(); 
        for (int i = 0; i < wordlength; i++) { 
            temp.append('-'); 
        } 
        knownLetters = temp.toString(); 
 
        ResultOfGuess rog = new ResultOfGuess(); 
        rog.setWon(false); 
        rog.setImageString(StringImages.getImage(0)); 
        rog.setLettersGuessed(guessedLetters); 
        rog.setKnowLetters(knownLetters); 
 
        return rog; 
    } 
 
    public ResultOfGuess handleGuessedLetter( 
   final String guessedLetter) throws MyException { 
        if (!gameInProgress) { 
            throw new MyException("No current game"); 
        } 
        if (badGuessCount >= StringImages.maxMoves()) { 
            throw new MyException( 
"You have been hung.  You are dead. You cannot keep guessing!"); 
        } 
        if (guessedLetter.length() != 1) { 
            throw new MyException("Invalid Guess"); 
        } 
        char ch = guessedLetter.charAt(0); 
        if (letters.indexOf(ch) < 0) { 
            throw new MyException("Invalid Guess"); 
        } 
        if (guessedLetters.indexOf(ch) != -1) { 
            throw new MyException("Letter already used"); 
        } 
        numGuesses++; 
        guessedLetters = guessedLetters + guessedLetter; 
        StringBuffer temp = new StringBuffer(); 
        boolean goodGuess = false; 
        for (int i = 0; i < wordToGuess.length(); i++) { 
            if (ch == wordToGuess.charAt(i)) { 
                temp.append(ch); 
                goodGuess = true; 
            } else { 
                temp.append(knownLetters.charAt(i)); 
            } 
        } 
 
        knownLetters = temp.toString(); 
 
        if (!goodGuess) { 
            badGuessCount++; 
        } 
        ResultOfGuess rog = new ResultOfGuess(); 
 
        if (knownLetters.indexOf('-') == -1) { 
            // All letters guessed. 
            rog.setWon(true); 
            rog.setImageString(null); 
            rog.setLettersGuessed(guessedLetters); 
            rog.setKnowLetters(knownLetters); 
 
        } else { 
            rog.setWon(false); 
            rog.setImageString(StringImages.getImage(badGuessCount)); 
            rog.setLettersGuessed(guessedLetters); 
            rog.setKnowLetters(knownLetters); 
 
        } 
 
 
        return rog; 
    } 
 
    public boolean gameOverMan() { 
        return (!gameInProgress) ||  
   (badGuessCount>=StringImages.maxMoves()); 
    } 
     
     
} 
 
 
8 Deploy the application. 
 
? 
 
Yes – deploy the application.  OK, there isn’t an application yet really as 
haven’t yet defined either a web client or an application client.  But one 
needs to have the EJB bean deployed. 
 
When it is deployed, the Glassfish server prints out the JNDI name for the 
bean (well, really it is the name of the factory object that creates beans).  
This string will be needed when defining the web client. 
 
 
The name was something along the lines java:global/Stateful/Statful-
ejb/Hangmanbean. 
 
 
9 Next, edit the application client. 
 
As in the previous example, we can rely on the appclient container 
“injecting” a reference to the stateful bean.   
 
 
 
If you run several application clients concurrently, each will work with its 
own EJB bean reference.  Each of these will refer to a different instance of 
the stateful bean that will get to be created in the server. 
 
10 Write the client code: 
 
 
 
11 Run the application: 
 
 
 
12 If you are losing, you can always cheat.  The EJB bean code prints the 
word to System.out so it will appear in the Glassfish console log: 
That makes it easier to win: 
 
 
 
13 There are some extra issues with a web application. 
 
You cannot use resource injection to inject a reference to a stateful bean. 
 
A stateful bean holds user specific data.  So each user of a servlet must 
have a reference to a different instance.  Obviously, this reference cannot 
be a simple member of the servlet class.   
 
Servlet session state must be used. 
 
In the web app servlet you start a web session.  You use an explicit JNDI 
lookup request to get a reference to a distinct instance of the stateful bean.  
You store this reference as an attribute of your session context. 
Also, if you want to access the web-app from another machine, you may have to 
open a port in your Ubuntu fire wall – but you probably won’t have permissions 
to do this. 
 
14 Edit the default generated index.jsp to have a reference to the servlet that 
will handle game play. 
 
 
 
15 Define a package and a servlet 
 
Its “doGet” method (as invoked via the link in the welcome page) should 
start a new game and respond with an initial form page that allows the user 
to select a first letter. 
 
The “doPost” method processes the user’s guess, and (if the game is not 
yet over) responds with another form page showing progress. 
 
16 The Servlet has to use JNDI to get references to EJB beans: 
 
 
 
17 The session context and bean reference will get created at the start of the 
doGet method: 
 
 
 
18 Both doGet and doPost utilize the bean 
 
 
 
 
 
19 Build and redeploy the application. 
 
20 Try with multiple clients: 
 
 
 
 
 
 
 
Stateless session bean used to retrieve entities 
 
This simple example uses a table that you might have created on Oracle for an 
exercise in CSCI399: 
 
drop table soccerleague; 
drop sequence leagueseq; 
 
create sequence leagueseq increment by 1 start with 1; 
 
create table soccerleague ( 
 gameid number primary key, 
 played date, 
 location varchar(64), 
 team1 varchar(32), 
 team2 varchar(32), 
 score1 number, 
 score2 number 
); 
 
insert into soccerleague values ( 
  leagueseq.nextval, 
  TO_DATE('2007-08-26','YYYY-MM-DD'), 
  'Members Equity Stadium', 
  'Perth', 'Newcastle', 0, 0); 
 
  ... 
 
The application retrieves details of soccer games, allowing a user to choose to receive 
all data, or just data for drawn games, or home wins, or away wins.  (If you don’t have 
your Oracle table any longer, create something similar on MySQL.) 
 
The example only uses a single JPA Entity class (Soccerleague) which just has simple 
data members.  There are no relationships amongst different entities, and there are no 
Collection data members representing one-to-many relations.  This simplifies the set 
up slightly.  The client application (and the “web” part of the application) do not need 
to link with a JPA implementation library EclipseLink.  The “entity” part of the 
application uses only the Java Persistence jar file. 
 
The application consists of an “entities” Java class library project, and an Enterprise 
project with the usual ejb, client-app, remote interface, and web subprojects. 
 
Entity project (Java library) 
 
1 Create the “entity” project 
 
 
 
2 Define a package for the classes, and use “New entity class from database” 
to generate the JPA class from the soccerleague table definition in the 
database: 
 
 
 
3 Add the JPA definitions from the Java Persistence library (the entity class 
library that is being created doesn’t need to define a persistence unit or 
link with a JPA implementation library): 
 
 
 
4 If you generate the class from the Oracle table, it will end up using a 
BigDecimal for its primary key field, and BigInteger variables for scores 
(expecting a high scoring soccer match).  Change these to Integer and int. 
 
5 Generated class: 
 
 
 
6 Build the entity project.  NetBeans will create a .jar file for the entity class.  
Add this .jar file the other projects. 
Enterprise project and sub-projects 
 
1 Create a new Enterprise application project; and a library project for the 
remote interface, and a client application project: 
 
 
 
 
Add the generated entities library to the projects: 
 
 
2 Edit the ejb-subproject, adding first a package for the session bean and 
then the definition of the session bean with its remote and local interfaces. 
 
 
The ejb project needs the created entities library, along with the actual JPA 
implementation library.  It also needs to define a persistence unit. 
 
 
The persistence unit definition needs to be edited to reference the entity 
classes already generated: 
 
 
 
The bean needs to support business methods that can be used to retrieve all 
games, drawn games, home wins, and away wins. 
  
 
 
 
 
3 Create the application client. 
 
“Inject” a bean reference for the SoccerSessionBean and invoke its 
methods: 
 
 
 
 
4 Build and deploy the EJB project. 
 
5 Build and run the client application: 
 
 
 
 
6 Create the web client. 
 
Modify the auto-generated index.jsp page so that it has a form that will 
allow a user to select games of interest.  This form should submit data to a 
servlet. 
 
 
 
A reference to the bean gets injected into the servlet.  The reference is used 
to invoke processing, with the results being forwarded to a JSP for final 
display. 
 
 
 
A final JSP is required to format the data.  Of course, this will use JSTL 
(add the JSTL library to the war project): 
 
 
 
 
 
7 Build, deploy, and test: