Beruflich Dokumente
Kultur Dokumente
D53942GC10
Edition 1.0
January 2009
D57569
Authors Copyright © 2009, Oracle. All rights reserved.
Gary Williams This document contains proprietary information and is protected by copyright and
other intellectual property laws. You may copy and print this document solely for your
own use in an Oracle training course. The document may not be modified or altered in
Technical Contributors any way. Except where your use constitutes "fair use" under copyright law, you may
and Reviewers not use, share, download, upload, copy, print, display, perform, reproduce, publish,
license, post, transmit, or distribute this document in whole or in part without the
Ken Cooper express authorization of Oracle.
Joe Greenwald
The information contained in this document is subject to change without notice. If you
Taj-ul Islam find any problems in the document, please report them in writing to: Oracle University,
500 Oracle Parkway, Redwood Shores, California 94065 USA. This document is not
Pete Laseau warranted to be error-free.
Adam Leftik
Restricted Rights Notice
Mike Lehmann
Jacobo Marcos If this documentation is delivered to the United States Government or anyone using
Editors
Aju Kumar
Amitha Narayan
Graphic Designer
Priya Saxena
Publishers
Sujatha Nagendra
Joseph Fernandez
Contents
1 Introduction
Objectives 1-2
Course Objectives 1-3
Course Agenda 1-4
Fundamentals of Java EE Technology 1-9
Designing Java EE Applications 1-10
iii
Types of Enterprise JavaBeans 3.0 2-17
Enterprise JavaBeans 3.0 Component Architecture 2-18
Java Persistence API (JPA) 2-19
Quiz 2-21
Web Services 2-22
Java EE Web Services Architecture 2-23
Client-Tier Components 2-25
Java EE Web-Tier Components 2-26
Java EE Web Application Architecture 2-28
What Is a Servlet? 2-29
What Is a JavaServer Page? 2-30
iv
The View 3-10
The Controller 3-11
Designing a Java EE Application 3-12
Quiz 3-13
Struts: Overview 3-14
Struts Components 3-15
Struts Architecture 3-16
Struts Page Flow Design 3-17
JSF and Struts 3-19
Implementing the User Interface with JSF and Core Java EE Patterns 3-20
Selecting a Persistence Strategy 3-21
v
Error Handling 4-20
Debugging a Servlet 4-21
JDeveloper Environment 4-22
Servlet Mapping 4-23
Servlet Mapping in JDeveloper 4-24
Invoking a Servlet 4-25
Specifying Java EE Web Module Settings 4-26
Summary 4-27
Practice: Overview 4-28
vi
Tag Library Descriptor 5-38
Implementing Simple Tags 5-39
JSP Expression Language 5-40
Expression Language Implicit Objects 5-41
JDeveloper and JSPs 5-42
Summary 5-43
Practice: Overview 5-44
vii
Life Cycle of a Stateful Session Bean 7-12
Passivation and Activation Concepts 7-14
Creating a Stateful Session Bean 7-15
Defining the Stateful Session Bean 7-16
Analyzing the Remote and Local Interfaces 7-17
Creating a Test Client for the SFSB 7-18
Calling a Stateless Bean from a Stateful Bean by Implementing DI 7-19
Interceptor Methods and Classes 7-20
Interceptor Method 7-21
Interceptor Classes 7-22
Summary 7-23
viii
Accessing an EntityManager Instance in an Application 9-7
Creating a Container-Managed EntityManager Instance 9-8
Creating an Application-Managed EntityManager Instance 9-9
Specifying Database Operations with the EntityManager API 9-10
Commonly Used Methods in the EntityManager Interface 9-11
Quiz 9-13
Inserting New Data 9-14
Deleting Data 9-15
Updating and Synchronizing the Entity with the Database 9-16
Updating Data 9-17
Finding an Entity by Primary Key 9-18
ix
Creating the WSDL Document 10-23
Modifying the WSDL Document 10-25
Creating the Web Service by Using Oracle JDeveloper 11g 10-26
Implementing the Web Service Logic 10-27
Summary 10-28
Practice: Overview 10-29
x
Summary 11-39
Practice: Overview 11-40
xi
Event and Listener Execution Order 13-12
Validation in the JSF Life Cycle 13-13
Creating Custom Exception Handlers 13-15
Registering an Exception Handler 13-16
Changing Life Cycle Exception Reporting 13-17
JavaServer Faces Validators 13-18
Creating Backing Bean Validation in JDeveloper 13-19
Backing Bean Validator: Code Example 13-20
Input Validation 13-21
Summary 13-22
Practice: Overview 13-23
xii
Types of Transactions 15-5
Transaction Management 15-7
Two-Phase Commit Protocol 15-8
Successful Two-Phase Commit 15-9
Unsuccessful Two-Phase Commit 15-10
Quiz 15-11
Java Transaction API (JTA) 15-12
EJB Transaction Model 15-13
Managing Transactions with EJBs 15-14
Types of Transaction Management 15-16
Container-Managed Transactions 15-17
xiii
Configuring New Users in WebLogic Server 16-14
Adding Users to Groups 16-16
Logical Roles 16-17
Quiz 16-19
Configuring Security 16-20
Determining Protected Resources 16-21
Defining the Logical Roles 16-22
Defining and Using Logical Roles in Web Applications (web.xml) 16-23
Defining and Using Logical Roles in EJBs (ejb-jar.xml) 16-24
Mapping Logical Roles to Users and Groups 16-25
Setup Authentication 16-26
xiv
Deploying with the Oracle WebLogic Server Console 17-23
Deploying with Oracle JDeveloper 17-24
What Is Ant? 17-25
Ant Build Files 17-26
A Sample build.xml File 17-27
Creating a JAR File by Using Ant Task 17-28
Creating a WAR File by Using Ant Task 17-29
Creating an EAR File by Using Ant Task 17-30
Deploying an Application by Using Ant Task 17-31
Packaging Best Practices for Production Environments 17-32
Summary 17-33
xv
Printing Layout Panel Content B-9
Creating Collapsible Panes with the Panel Splitter Component B-10
Creating Collapsible Panes with the Panel Accordion B-11
Panel Accordion Overflow B-13
Setting Panel Accordion Properties B-14
Arranging Items in Columns or Grids B-15
Creating Stacked Tabs B-17
Hiding and Displaying Groups of Content B-18
Arranging Items Horizontally or Vertically, with Scrollbars B-20
Displaying Table Menus, Toolbars, and Status Bars B-22
Creating Titled Sections and Subsections B-24
Index
xvi
Handling Application Events
Objectives
In any application, it is important to initiate actions based on specific events. JSF allows events
to be specified for user interface (UI) components. A JSF application can listen for events such
as user input, and then use built-in validator and data converter classes to manipulate data. In
this lesson, you learn how to use built-in validator and converter classes, as well as how to create
custom classes for handling UI events.
JSF supports:
• Action events:
– Occur when a command component is activated—for
example, when a user clicks a button or a link
– Return a navigation case
• Value change events:
Types of Events
An action event occurs when a command component is activated. For example, when a user
clicks a button or a link, the form in which the component is enclosed is submitted, and
subsequently an action event is fired. An action event may affect only the user interface (for
example, a link to change the locale, causing different field prompts to display) or it may
involve some logic processing in the back end (for example, a button to add a new order after
entering values in some fields).
The return value of an action event is usually used for navigation.
A value change event occurs when the local value of an input component changes. For
example, when a user selects a check box, the value of the component changes to True.
A value change event is fired only after a component value has been validated successfully and
the form it is enclosed in is submitted.
A phase event or listener is executed as part of the standard JSF life cycle. Using a phase
listener, you can listen for phase events for any of the ADF life-cycle phases, and execute your
own code before and after the events. You listen for a phase event, and then use the
beforePhase() and afterPhase() methods to execute your own code.
Action Events
Action events are events that are associated with command components (such as
commandButton, commandLink, or commandMenuItem). Action event code can be in
either the page backing bean or a separate class. The benefit of having the code in the backing
bean is that the code that is associated with a specific page is local to the page (single source).
However, the benefit of a separate class is reusability. For example, if you have standard code
that should be executed regardless of the page, the separate-class approach makes more sense.
If you use the backing-bean approach, JDeveloper creates a method stub for you, and all you
have to do is add your custom code. JDeveloper also registers the action in the page source.
When the page is submitted, the action event is added to the queue of application events to be
executed. Action events are the last events to fire in the application phase of the life cycle.
• Two ways:
– Double-click a command component in the Visual Editor.
– Enter a method name (including the ()) in the Action
property of the component.
• JDeveloper:
– Creates a method in the backing bean
• Action listener:
– Is a class that wants to be notified when a command
component fires an action event
– Implements javax.faces.event.ActionListener
• Value change listener:
– Is a class that wants to be notified when an input component
fires a value change event
1 4
Apply Request Values. Update Model Values.
2
Process Validations.
5
Successful? Yes
Invoke Application.
7
No 7 Render Response: 6
Display either new page,
or same page with errors.
Summary
Event handling in JavaServer Faces is based on the JavaBeans event model, where event classes
and event listeners are used to handle events generated by the components. All JSF events
extend the javax.faces.FacesEvent class.
An action event occurs when a command component that implements ActionSource is activated.
For example, when a user clicks a button or a link, the form in which the component is enclosed
is submitted, and subsequently an action event is fired.
A value change event occurs when the local value of an input component changes—for example,
when a user selects a check box, the value of the component changes to True.
Backing beans can act as the state holder of user input and the components’ data. They are
useful for implementing validation methods and event handler methods that invoke back-end
application code with component values.
A Web application can store data of many types (int, long, date, and so on) in the model layer.
However, when viewed in a client browser, the user interface has to present the data in a manner
that can be read or modified by the user.
Messaging Systems
Messaging systems have existed for many years in different forms. A messaging system uses
messages rather than method invocation (for example, Remote Method Invocation [RMI]) to
communicate between components. In this way, components are loosely coupled and do not
need to know details of one another’s implementation or interface. Instead, each peer client
communicates with a message queue to send or receive messages.
Note: Email systems are not considered messaging systems because they are used for
communication between humans or between a system and a human, and not strictly between
systems.
Message-Oriented Middleware
Message-oriented middleware has been in use for several decades. In the mid-1980s, when
providers created architectures that could operate in a standard way on a variety of platforms,
message-oriented middleware became widely used.
These providers made inroads into bridging the gap between the many platforms for mainframes
and those for personal computers. Today, hundreds of companies position themselves as
middleware firms. Even though there is intense competition and variety in message-oriented
middleware products, they all tend to fall into one of these categories:
• Publish/subscribe
• Point-to-point
• Request-reply
Messaging Models
JMS supports point-to-point and publish/subscribe messaging models. The models are very
similar, except for the following:
• The PTP messaging model enables delivery of a message to exactly one recipient.
• The pub/sub messaging model enables delivery of a message to multiple recipients.
9 8 7 6 5 4 1 Subscriber
Queue Manager
Publisher WebLogic Server 2
Subscriber
Point-to-Point Queue
When using a PTP queue, multiple producers can put messages onto the queue. The queue
serializes the messages into a linear order. Multiple receivers can take messages off the queue;
the messages typically come off in a first-in, first-out (FIFO) order; the oldest message on the
queue is the first one to be taken off.
A message can be delivered only to one receiver. An example of when to use a PTP queue
would be at a call center. Calls are routed into the network through a PBX. The PBX places
incoming calls onto an “Incoming Call” queue. When a service representative becomes
available, the representative requests the next caller in the system. The system pulls the caller
who has been waiting the longest off the queue and routes the caller to the service
representative.
9 8 7 6 5 4 3 2 1 Subscriber
Topic Manager
Publisher WebLogic Server 3 2 1
Subscriber
Publish-Subscribe Topics
Having the publishers publish to a topic rather than directly to a list of subscribers decouples the
publishers and subscribers.
By doing this, a publisher is not required to manage the number of subscribers (if any) that must
receive the message. By delegating the work of the message delivery to the message-oriented
middleware server (which manages the topic), the publisher does not have to manage the
delivery of guaranteed messages, fault tolerance of its production, load balancing, or other
issues. By decoupling a subscriber from the publisher, the subscriber does not have to determine
whether its publisher is active. If the message-oriented middleware server is executing, the needs
of both publishers and subscribers are met.
An example of using a publish and subscribe topic is a stock ticker application. A typical system
would set up a topic for each stock that is traded on the exchanges. When a trade is made on a
stock, the respective exchange publishes a message to the topic associated with the stock traded.
Clients who are interested in receiving updates about the status of their stocks use a program to
subscribe to the topics of each stock they are interested in. When it receives a message, the
message-oriented middleware server broadcasts the message to all interested stock ticker
programs.
Answers: 2, 3
Create a Connection.
JNDI Tree
Connection
2 Destination: Queue
Destination: Queue
5
Session
Destination: Topic
Commit Commit
Transacted Messaging
JMS clients can participate in a distributed or local transaction. There are two scenarios:
• On the Producer side, a transaction begins and some operations, such as sending messages,
are performed. If the transaction commits, all the messages are sent to the destination. If
the transaction rolls back, none of the messages arrive at the destination.
• On the Consumer side, a transaction begins and some operations, such as processing
messages, are performed. If the transaction commits, the processed messages are removed
from the destination. If the transaction rolls back, the messages stay in the destination.
Queues
Queues
JMS Client Queues JMS Client
JMS …
… Topics
Topics
Queues
Queues
Queues
JMS
Topics
Topics
Topics Server B
WebLogic Server
Persistence
• A connection factory:
– Encapsulates connection configuration information
– Is used to create preconfigured connections
– Is stored in JNDI
– Can be targeted to servers or clusters
• WLS provides a default connection factory that is bound in
Connection Factory
A ConnectionFactory object encapsulates connection configuration information and
enables JMS applications to create a Connection. A system administrator configures
connection factories to create connections with predefined attributes.
A system administrator defines and configures one or more connection factories, and WebLogic
Server adds them to the JNDI space during startup. The application then retrieves a connection
factory using WebLogic JNDI.
The system administrator can establish clusterwide, transparent access to destinations from any
server in the cluster by configuring multiple connection factories and using targets to assign
them to WebLogic Servers. Each connection factory can be deployed on multiple WebLogic
Servers.
WebLogic JMS defines one default connection factory. It can be looked up using the JNDI
name, weblogic.jms.ConnectionFactory. You must define a connection factory only
if the default provided by WebLogic JMS is not suitable for your application.
JMS Destination
A JMS destination identifies a queue (point-to-point) or topic (publish/subscribe) for a JMS
server.
After configuring a JMS server, configure one or more queue or topic destinations for each JMS
server. You configure destinations explicitly or by configuring a destination template that can be
used to define multiple destinations with similar attribute settings.
Application JMS
Queue/Topic
Message-driven bean
JMS client JMS provider
EJB container
Message-Driven Beans
A message-driven bean is an EJB that acts like a JMS consumer. The bean is stateless (each
bean transaction spans only one method invocation), and thus it is much like a stateless session
bean. However, unlike SLSBs, MDBs are never directly invoked by clients; instead, MDBs have
an onMessage() method that is invoked by the EJB container when a message is sent to its
queue or topic.
Because there are no direct client calls to the MDB, an MDB has no remote or local interfaces.
Before EJB 3.0, MDBs had a MessageDrivenBean interface with a
setMessageDrivenContext() method that established its environment.
In EJB 3.0, the MessageDrivenContext is now set through dependency injection. MDBs
do implement a MessageListener interface.
Creation
Does not
Ready onMessage()
exist
@MessageDriven(mappedName = "jms/demoTopic", 1
name = "MessageBean",
activationConfig = { @ActivationConfigProperty(
propertyName="connectionFactoryJndiName",
2
propertyValue="jms/TopicConnectionFactory"),
@ActivationConfigProperty(
propertyName="destinationName",
propertyValue="jms/demoTopic"),
@ActivationConfigProperty(
MessageProducer publisher =
topicSession.createProducer(topic);
5
Message message = topicSession.createMessage();
6
message.setJMSType("theMessage");
message.setLongProperty("time",
System.currentTimeMillis());
message.setStringProperty("subject",
"Test EJB 3.0 MDB");
message.setStringProperty("message",
A transaction:
• Is a single, logical unit of work or a set of tasks that are
executed together
• May access one or more shared resources (such as
databases)
• Must be atomic, consistent, isolated, and durable (ACID)
Transactions: Overview
Transactions manage changes to multiple databases in a single application as a unit of work.
A transaction must be:
• Atomic: A transaction must either execute completely or not execute at all. For example,
in an account transfer transaction, both debit and credit must be successful as a unit, or
both must fail.
• Consistent: This refers to the integrity of the underlying database. In an account transfer
example, the amount of debit to one account must equal the credit to the other account.
• Isolated: The steps during a transaction cannot be affected by or be visible to any other
part of the system until the transaction is complete.
• Durable: All data changes that are made during a transaction must be written to some
physical storage before the transaction is successfully completed, so that even if the system
crashes, the changes are not lost.
$500
Withdraw: $100 -$100
Account 1
$400
B ATM Bank
Transfer: $100 Failed
From: Acct 1 Deposit Account 2 $1000
To: Acct 2
Example of a Transaction
Transactions are appropriate in the following scenarios. Each situation describes a transaction
model supported by the WebLogic Server system.
A client application must converse with an object managed by a server application, and it must
make multiple invocations on a specific object instance. The conversation can be characterized
by one or more of the following:
• Data is cached in memory or written to a database during or after each successive
invocation.
• Data is written to a database at the end of the conversation.
• The client application requires that the object maintain an in-memory context between
each invocation; each successive invocation uses the data that is maintained in memory.
• At the end of the conversation, the client application needs the capability to cancel all
database write operations that may have occurred during or at the end of the conversation.
Consider an Internet-based online shopping cart application. Users of the client application
browse through an online catalog and make multiple purchase selections. They proceed to check
out and enter credit card information to make the purchase. If the credit card check fails, the
shopping application must cancel all the pending purchase selections in the shopping cart or roll
back purchase transactions made during the conversation.
Types of Transactions
A resource, like a database, is controlled through a resource manager (RM). The coordination of
multiple resource managers is performed by a transaction manager (TM). A transaction is often
referred to as a transaction context. A transaction originator initiates the transaction. The
transaction originator can be a user application, an Enterprise JavaBean, or a JMS client.
A transaction manager manages transactions on behalf of the application programs. A
transaction manager coordinates commands from the application programs to start and complete
transactions by communicating with all resource managers that are participating in those
transactions. When resource managers fail during transactions, transaction managers help
resource managers decide whether to commit or roll back pending transactions. The
communication between the transaction manager and a specific resource manager is called a
transaction branch.
A recoverable resource provides persistent storage for data. The resource is typically a database.
A resource manager provides access to a collection of information and processes. Transaction-
aware JDBC drivers are common resource managers. Resource managers provide transaction
capabilities and permanence of actions; they are entities accessed and controlled within a
distributed transaction. Resource managers are software tools that are typically provided by the
vendor of the storage mechanism, such as Oracle, Sybase, DB2, and so forth. Some are available
from third-party vendors. You can write your own.
Oracle Fusion Middleware 11g: Build Java EE Applications 15 - 5
Types of Transactions (continued)
Software vendors provide an RM file that specifies configuration and login information used
when opening a database connection.
Application 1
Transaction Management
A transaction is a set of related operations. These operations should either be performed together
or none should be performed. For example, purchasing a product using a Web application is a
transaction that involves multiple operations, such as selecting a product, placing an order,
reducing the product quantity available in the application database, debiting the amount from the
buyer’s credit card account, and crediting the seller’s account. To complete this transaction
successfully, all the operations involved in the transaction must be performed. In this case, the
transaction is said to be committed. However, even if one operation fails, the transaction is
rolled back. This implies that the effect of all the operations that were performed before the
failed operation must be undone.
Transaction management refers to the end-to-end management of transactions between
applications and resources. Two essential components that provide end-to-end transaction
management are a transaction manager and a resource manager. A transaction manager contains
the logic for implementing transaction management. A resource manager is a driver that
interfaces between the resource and the transaction manager. A transaction manager manages
transactions on behalf of application programs. A transaction manager coordinates commands
from application programs to start and complete transactions by communicating with all
resource managers that are participating in those transactions.
prepare
Resource
Application Manager Database
Transaction Resource
Printer
Manager Manager
Resource Another
TLOG Manager App
ready
prepare
Phase 1 ready
Resource Another
TLOG Manager App
committed
commit
committed
prepare
Resource
Application Manager Database
Transaction Resource
Printer
Manager ready Manager
Resource Another
TLOG Manager App
not ready
prepare
Phase 1 ready
not ready
Resource Another
TLOG Manager App
rolled back
abort
Rolled back
Answer: 3
• Bean-managed transactions:
– Are performed programmatically using the
javax.transaction.UserTransaction interface
– Explicitly demarcate (start and end) transactions
– Enable a transaction to span method calls
• Container-managed transactions:
• Container-managed transactions:
– No transactional management code in the bean
– Chosen implicitly by default or explicitly by use of the
@TransactionManagement
(TransactionManagementType.CONTAINER) annotation
– Available to entities, session beans, and message-driven
beans
• @TransactionManagement(TransactionManagementTy
pe.CONTAINER)
• Container-managed transactions can specify one of the
following @TransactionAttribute annotations:
– REQUIRED (default)
– SUPPORTS
Container-Managed Transactions
CMT is used by default or where explicitly declared through the use of
@TransactionManagement(TransactionManagementType.CONTAINER).
CMT is guided by the use of @TransactionAttribute annotations. The Java EE
specifications defined the following transaction attribute values and their semantics:
• REQUIRED: The container starts a new transaction if one has not already been started.
• SUPPORTS: The container does not start a new transaction, but uses one if it already exists.
• MANDATORY: The container throws an exception if one is not already started.
• NEVER: The container throws an exception if a transaction has already started.
• REQUIRES_NEW: The container always starts a new transaction, suspending any
transaction already started.
• NOT_SUPPORTED: The container suspends any active transaction. Only REQUIRED and
NOT_SUPPORTED transaction attributes are valid for MDBs. The use of
REQUIRES_NEW and SUPPORTS with an MDB is not meaningful because there is no
preexisting client transactional context, and an MDB does not have a client to handle
exceptions for the MANDATORY and NEVER transactional attributes.
When the transaction attribute is declared on the bean class, that type of CMT is applied to all
business methods of the bean. When the transaction attribute is used on a bean method, that type
of CMT is applied to that particular method, overriding the CMT type specified at the bean
level.
Oracle Fusion Middleware 11g: Build Java EE Applications 15 - 17
Transaction Attribute: REQUIRED
A client has:
• No transaction: The bean starts a new one.
• A transaction: The bean uses it.
Client
A client has:
• No transaction: The bean does not start a new one.
• A transaction: The bean uses it.
Client
A client has:
• No transaction: The bean throws the
javax.transaction.EJBTransactionRequiredExc
eption exception.
• A transaction: The bean uses it.
Client
A client has:
• No transaction: The container calls the method with no
transactional context.
• A transaction: The container throws the
javax.ejb.EJBException exception.
Client
A client has:
• No transaction: The bean starts a new one.
• A transaction: It is suspended; the bean starts a new one
and commits it, and then reassociates the old one.
Threads of
Client
Suspended
Bean
(bean or servlet)
Resumed
Client transactional context Bean transactional context
A client has:
• No transaction: The bean does not start a new one.
• A transaction: The bean suspends it. The transaction
resumes when the client gains control.
Threads of
Client
Suspended
Bean
(bean or servlet)
Resumed
Transactional context No transactional context
Answer: 2
CMT: setRollbackOnly()
In a CMT bean, the bean cannot, and must not, directly invoke the commit() or
rollback() methods to end transactions.
Typically, an enterprise bean marks a transaction for rollback to protect data integrity before
throwing an application exception because an application exception does not automatically
cause the container to roll back the transaction. A CMT bean can invoke the
javax.ejb.EJBContext.setRollbackOnly() method to ensure that the container
will not commit the transaction and set the current transaction to roll back. The bean can use the
javax.ejb.EJBContext.getRollbackOnly() method to detect if the current
transaction has been marked for rollback.
@TransactionManagement(TransactionManagementType.CONTAINER)
@TransactionAttribute(TransactionAttributeType.REQUIRED) 1
@Stateful public CartBean implements Cart {
2 @TransactionAttribute(TransactionAttributeType.MANDATORY)
@TransactionAttribute(TransactionAttributeType.MANDATORY)
public void addItem(float taxRate) {
...
}
...
Bean-Managed Transactions
The use of bean-managed transactions is specified through the use of the
@TransactionManangement(TransactionManangementType.BEAN) annotation.
With BMT, the bean manages the transactions in its code by providing begin, commit, and
rollback statements.
Then the begin(), commit(), and rollback() methods of the UserTransaction
object are implemented in the bean. A reference to a
javax.transaction.UserTransaction object can be obtained by either using the Java
Naming and Directory Interface (JNDI) lookup() method, or by implementing dependency
injection.
@TransactionManagement(TransactionManagementType.BEAN) 1
@Stateful
public CartBean implements Cart {
@Resource
private UserTransaction utx; 2
utx.commit(); 5
} catch (Exception ex) {
utx.rollback(); 5
ex.printStackTrace();
}
...
Practice: Overview
In this practice, you configure a supplied application that enables new product records to be
added to the PRODUCTS table.
In the first example, you explicitly add annotations to the application implementing the default
container-manager persistent settings and observe application behavior.
In the second example, you modify the same stateful session bean to perform bean-managed
persistence by implementing the UserTransaction JTA methods in the session bean.
Note: This practice is independent of the course application. It works on the PRODUCTS table
data in the same database schema as the course application.
Authorization of a Client
The security roles that are defined by the application assembler provide the deployer with a
logical and simplified security view of the Web application or the EJB. The deployer is
responsible for mapping the logical security roles to principals or to groups of principals who are
defined in the target operational environment.
At run time, a client is allowed to access a URL or invoke a business method only if the
principal making the request is authenticated and authorized (by being associated with an
appropriate security role) to access the requested resource. The container provider enforces the
security policies at run time and provides the tools for managing security during deployment and
at run time.
The security view defines the various types of users of the application and their rights to invoke
a URL request or methods in the enterprise-bean interfaces.
Note: The security roles define the logical security view of an application. They should not be
confused with the user groups, users, principals, and other concepts that exist in the target
enterprise’s operational environment.
The security roles and information are configured and mapped in configuration files and
deployment descriptors, as discussed in the following slides.
Answer: 1
LDAP Provider
JNDI Tree
Client
WebLogic Server
EJB
WLS EJB
Client
Authenticate
login Login
Module(s)
sign
Subject
Principal
MyEJB.abc( ) Validator(s)
validate
and
Security Services
In simple authentication, a user attempts to log in to a system by using a username/password
combination. The WebLogic Server establishes trust by validating that user’s username and
password and returns a Subject that is populated with Principals. This process requires the use of
a JAAS Login Module and Principal Validation provider. After successfully proving a caller's
identity, an authentication context is established, which allows an identified user or system to be
authenticated to other entities.
During the authorization process, WebLogic Server determines if a given Subject can perform a
given operation on a given resource and returns the result of that decision to the client
application, this process requires the use of Access Decisions, an Adjudication provider, and
possibly multiple Role Mapping providers.
Roles are obtained from the Role Mapping providers and input to the Access Decisions. The
Access Decisions are then consulted for an authorization result. If multiple Access Decisions are
configured and return conflicting authorization results (such as PERMIT and DENY), an
Adjudication provider is used to resolve the contradiction by returning a final decision.
Security Realms
A security realm is a mechanism for protecting WebLogic Server resources such as
authenticators, adjudicators, authorizers, auditors, role mappers, and credential mappers. A
WebLogic Server resource is protected under only one security realm and by a single security
policy in that security realm. A user must be defined in a security realm in order to access any
resources belonging to that realm. When a user attempts to access a particular WebLogic Server
resource, WebLogic Server tries to authorize the user by checking the access privileges assigned
to the user in the relevant realm.
Logical Roles
A role definition is specific to a security realm. Roles are tightly coupled with the authorization
provider. A role can be defined as resource scoped or globally scoped. Resource scoped means it
is granted to a specific resource, such as a method of an EJB, or a branch of the JNDI tree.
Globally scoped means a role is granted to all resources in a security realm. WebLogic Server
defines a set of default global roles for protecting WebLogic resources. Roles can be assigned
statically by defining them in the deployment descriptor for specified users or groups or
dynamically through the administration console by defining a set of conditions.
Default Global Roles Provided by WebLogic Server
• Admin can display and modify all resource attributes and perform start and stop
operations. By default, users in the Administrators group are granted the Admin role. You
can change this association or add other group associations.
• Operator can display all resource attributes. Users can start, suspend, resume, and stop
resources. By default, users in the Operators group are granted the Operator role. You can
change this association or other group associations.
• Deployer can display all resource attributes. Users can deploy applications, EJBs and other
deployable modules. By default, users in the Deployers group are granted the Deployer
role. You can change this association or other group associations.
Answer: 1
Configuring Security
Configuration of the security environment involves:
• Defining logical roles in the Java EE application deployment descriptor
• Mapping the logical roles to users and groups in the WebLogic-specific deployment
descriptor
The other methods of authorization and authentication include the LDAP-based OID and the use
of single sign-on features. You can use the JAAS API to build custom providers.
Note: In case of EJB 3.0, the ejb-jar.xml deployment descriptor file is optional. You can
use annotations instead. The ejb-jar.xml file is not used for entities. Configuration in the
ejb-jar.xml file overrides annotations.
/*.jsp ...
/context/* ...
...
</weblogic-web-app> weblogic.xml
Setup Authentication
Configure how users will be authenticated in your Web application through the use of the
<login-config> element. Java EE provides three types of authentication:
• BASIC: Uses the Web browser to display a dialog box with fields for a username and
password
• FORM: Uses a specified HTML page, JSP, or servlet to display an HTML form with
username and password text fields. The generated form must conform to a set of
specifications. Use the <form-login-config> element to specify the resource
containing the form.
• CLIENT-CERT: Uses client certificates to authenticate the request
The <form-error-page> element defines the JSP, servlet, or HTML file to display if the
user’s credentials are invalid.
BASIC Authentication:
@Stateless 1
@RolesAllowed("admin")
public class AdminServiceBean implements AdminService {
@RolesAllowed("user") 2
public void sharedTask() {
System.out.println("Shared admin/user method called");
}
@DenyAll 4
public void badTask() {System.out.println("Error");}
Practice: Overview
In this practice set, you create JAAS users and roles for application authentication and you
modify the course application to implement Web-layer security by using JAAS and form-based
login authentication.
Directory/Files Description
What Is web.xml?
The web.xml deployment descriptor file follows the Servlet 2.4 specification from Sun
Microsystems. The web.xml file is packaged together with the Web application components in
a .war file, which is then deployed in WebLogic Server.
What Is weblogic.xml?
The weblogic.xml deployment descriptor follows a proprietary schema used only by
WebLogic Server. It maps resources defined in the web.xml file to resources defined in
WebLogic Server.
Static Resources:
HTML, text images
Deployment
Descriptors
Answer: 2
Directory / File
Directory/File Description
Description
Document root of enterprise application
META-INF directory
Enterprise application deployment descriptor
1
2
Deploying Entities
Entities can execute inside the EJB or Web container, or in a Java SE application. Thus, entities
can be packaged in a standard Java EE module (such as an EJB-JAR file, a WAR file, or a JAR
file), which can be stored in the root of an EAR module or as a library module in an EAR file.
Entities also contain a simple deployment descriptor named persistence.xml. The
persistence.xml file is a persistence descriptor file that defines one or more persistence
units in an EJB 3.0 application that uses entities.
<persistence> 1
<persistence-unit name="Entity" transaction-type="JTA">
<provider> 2
org.apache.openjpa.persistence.PersistenceProviderImpl
</provider>
<jta-data-source> 3
jdbc/MyDataSource
</jta-data-source>
<jar-file>order.jar</jar-file> 4
Persistence.xml File
The slide shows the different sections of the persistence.xml file.
1. Define a persistence unit with a name and transaction type.
2. Specify an optional factory class for the persistence provider.
3. Specify the data source that the JPA provider uses to connect to the database to store
retrieved entities.
4. Specify the entity classes that comprise a single persistence unit (in case you have multiple
persistence units in a single archive).
5. Specify the vendor-specific configurations using the properties element.
• Ant is:
– A Java build tool similar to GNU’s make utility
– Written in Java and is open source
– Developed and maintained by the Apache organization
– Downloadable from and documented at
http://jakarta.apache.org/ant
What Is Ant?
Apache Ant is a tool for automating application build processes. It is similar to “make” but is
implemented using the Java language, requires the Java platform, and is best suited to building
Java projects.
GNU is a UNIX-compatible software system developed by the Free Software Foundation (FSF).
The philosophy behind GNU is to produce software that is nonproprietary. Anyone can
download, modify and redistribute GNU software.
The make utility controls the generation of executables and other files from a program's source
files. It gets knowledge of how to build your program from a file called the makefile, which lists
each of the output files and how to compute it from other files.
For more information about make, see the Web site at
http://www.gnu.org/software/make/make.html.
Ant provides functionality similar to make, but is written with, and works with, Java.
<target name="compile">
<javac srcdir="${sourceDir}" destdir="classes"/>
</target>
Objectives
As much as we like to think of our first-cut application as flawless, there are times when we
need to fix problems. In this lesson, you learn how to identify problems in Java EE applications
and to create simple test harnesses to reproduce the error. You learn about the various tools that
are available to help you troubleshoot.
Troubleshooting Basics
The following slides examine each of the steps mentioned in the slide in detail.
Requesting Help
If you post a topic on the JDeveloper OTN Forum, try to include as much relevant information
as possible. You are not expected to include all the information listed for every problem; include
what is appropriate.
Provide concrete examples in your post rather than abstract descriptions. For example, you
might start a topic as follows: “My page contains an input form for editing customer
information. Each customer can have one or more phone numbers.” This is easier for the person
looking at the problem to understand than an abstract description, such as “My page contains an
input form for editing an object, one of whose attributes can have one or more values.”
Java Logging
The Logging API is part of Java Platform, Standard Edition (Java SE) in JDK 1.4 and later
versions, and it ships with the JDK. It is designed to let a Java program produce messages of
interest to end users, system administrators, and software developers. It is useful in production
environments where you cannot run the debugger, or where running the debugger might hide the
problem. For example, timing-related problems often cannot be reproduced when running the
application in the debugger.
Java logging has several predefined levels:
• SEVERE: Extremely important messages such as fatal errors
• WARNING: Warning messages
• INFO: Informational run-time messages
• CONFIG: Informational messages about configuration settings
• FINE: Used for greater detail when diagnosing problems
• FINER: Even greater detail
• FINEST: Greatest detail
There are two other values: ALL (log all messages) and NONE (no messages).
• Configure logging in
<jdk_path>\jre\lib\logging.properties.
• Useful settings:
– Where to send the output. For example:
handlers= java.util.logging.ConsoleHandler
com.sun.faces.el.level = FINE
java.util.logging.ConsoleHandler.level = INFO
handlers= java.util.logging.ConsoleHandler,
java.util.logging.FileHandler
ws.SimpleWebServiceSoapHttpPortClient myPort =
new ws.SimpleWebServiceSoapHttpPortClient();
System.out.println("calling " +
myPort.getEndpoint());
• FileMon
• JUnit
• HTTP Analyzer
• JDeveloper Debugger
Summary
The first step in diagnosing a problem is usually to find out where it occurs. Exceptions can give
valuable information.
When you document a problem, do not include all the information listed for every problem;
include what is appropriate.
Use a test case to reproduce the problem. If the problem is simple enough, you can describe the
steps to reproduce the problem. A test case is almost always worth the time it takes to create; it
saves time later in examining the problem, diagnosing the problem, and testing a fix.
Java logging is useful in production environments where you cannot run the debugger, or where
running the debugger might hide the problem.
Creating a sample client is a good way to isolate the client code from the business service code.
JDeveloper Debugger and the JUnit extension are two tools to use to isolate a problem.
c) Use the following connection details or use the screenshot as a visual guide:
Step Screen/Page Description Choices or Values
i. Step 1 of 4: Type Connection Name: fod
Connection Type: Oracle (JDBC)
ii. Step 2 of 4: Authentication Username: fod
Password: fusion
Select the Save Password check box.
Select the Deploy Password check box.
iii. Step 3 of 4: Connection Driver: thin
Host Name: localhost
JDBC Port: 1521
SID: XE
iv. Step 4 of 4: Test Click Test Connection to check whether the
connection is successfully established.
If the status is “Success,” click OK.
Following are the tasks that you need to perform for this practice set:
• Develop a simple servlet application in JDeveloper 11g.
• Test the servlet in a Web browser.
• Modify a login HTML form to access the servlet.
3) Analyze the code in the doGet() and doPost() methods in the LoginServlet
servlet class.
4) Compile the servlet class. In the Application Navigator pane of JDeveloper,
right-click LoginServlet.java and select the Make option from the shortcut
menu. Check the Message log to verify the successful compilation of the application.
...
import java.sql.*;
...
...
...
...
...
try {
con=getConnection();
Statement stmt= con.createStatement();
stmt.executeQuery("select password from login where
uname='"+theuser+"'");
ResultSet rs = stmt.getResultSet();
if(rs.next()) {
originalPassword=rs.getString(1);
}
stmt.close();
e) Add the code to the doPost() method to retrieve the user_name parameter
from the request object. Remember that the value being passed is the parameter
that you specified in step 1.b, (not “User Name”). The code extracts the user
credentials from the HTML form, validates the user, and prints appropriate
messages in HTML. Note that the out.println statements replace the default
messages in the doPost method.
...
name = request.getParameter("user_name");
pass = request.getParameter("user_password");
boolean result = verifyPassword(name, pass);
out.println ("<html>");
out.println ("<body>");
if (result == true){
out.println ("Hello " + name + ": Your login module is
working great!");
}
else{
out.println ("Invalid user name or password");
}
out.println ("</body></html>");
out.close();
}
...
In Web-based applications, it is common that data from one page is used on others. There
are several ways to exchange data between pages. One way is to use explicit objects such
as the JSP Session object. You can also use a JavaBean to store data, as well as execute
business logic and data validation. With JSPs, you can also create custom tags that
perform specific formatting or logic that you may use across applications.
In this practice, you create a JavaServer Page that pass values using Session variables.
You also use a JavaBean to execute some business logic. In the last section of this
practice, you create several custom tags to perform special formatting for your page.
The second page displays the values for the first page, creates session variables, and
accepts two additional values. When the user clicks the Submit button, the third page
appears displaying the values from the first two.
1) Open Application_05.jws.
Note: This opens a skeleton of all the JSP application projects used in this practice.
a) In JDeveloper, select File > Open or choose Open Application in the
Application Navigator.
6) Now that you have added the display tags, you add tags to store the values of
firstName and lastName on the session object. You use a Set tag for this.
Use the following details to accomplish this task:
The BookCart application enables you to add and remove books from a shopping cart.
You can also view the details of the books that you want to add in the shopping cart.
1) In the Application Navigator, expand JSPApplication02.
Note: Minimize or close the JSPApplication01 project.
2) Navigate to CartBean.java in the Application Navigator and double-click it to
open in the code editor. Modify the code in the CartBean class as follows:
Hint: Expand JSPApplication02 > Application Sources > oracle.jsp >
...
...
public CartBean() {
}
...
public String[] getItems() {
String[] s = new String[vector.size()];
vector.copyInto(s);
return s;
}
...
d) Define and implement the processRequest() method that you will be using
in your JSP page to invoke the CartBean.
...
<html>
<jsp:useBean id="cart" scope="session"
class="oracle.jsp.CartBean" />
<jsp:setProperty name="cart" property="*" />
<%
cart.processRequest();
%>
...
c) Add the <%@ include %> directive to insert an HTML file (Books.html) in
the JSP.
...
<html>
<jsp:useBean id="cart" scope="session"
class="oracle.jsp.CartBean" />
...
...
...
e) Add the following scriptlets to retrieve the content from the cart and display the
selected books.
...
<p align="left">
<font face="Comic Sans MS">
You have the following items in your cart:
</font>
</p>
<p align="left">
<select name="select" size="10">
<%
String[] items = cart.getItems();
for (int i=0; i<items.length; i++) {
%>
<option>
<% out.print((items[i])); %>
</option>
<%
}
%>
</select>
...
The BookDetails application displays the details of a book in different formats. It extracts
the book details from the BookDetailsBean.java bean. The different formatting
functions are defined in the Functions.java file.
1) In the Application Navigator, expand JSPApplication03.
2) Open bookdetails.oracle.tag > SearchBookTag.java.
...
<html>
...
...
</br>
<b><u>Result:</u></b>
<br></br>
<ns:searchBook var="book"/>
<table border="1">
...
c) Add the following expression language in the JSP code to retrieve the book title
and apply the formatting functions.
...
<tr>
<td width="91">Title</td>
<td width="182">
${book.title}
</td>
<td width="248">
${ns:caps(book.title)}
</td>
<td width="271">
${ns:reverse(book.title)}
</td>
</tr>
...
d) Add the code in the servlet’s class doPost()method to invoke the Enterprise
JavaBean’s validateCreditCard() business method that implements the
logic to validate a credit card.
...
public void doPost(HttpServletRequest request,
3) Compile DI_Application02.
4) Run CreditCardValidationForm.html to test the functionality.
5) The validateCC() method should be reflected in the session bean’s remote and
local interfaces. Execute the following steps to accomplish this task:
a) Open CreditCardValidator.java.
b) Add the following code in the CreditCardValidator.java class (session
bean’s remote interface) to define the validateCC() business method:
...
@Remote
public interface CreditCardValidator {
public String validateCC(int uid, int ccNum);
}
Note: Try to execute the test client by changing the values in the parameters field
of the validateCC() method. For example:
...
// Call any of the Remote methods below to access the EJB
// creditCardValidator.validateCC( uid, ccNum );
System.out.println(creditCardValidator.validateCC(10,
@EJB
private CreditCardValidator ccv;
...
public ShoppingCartBean() {
}
shoppingCart.setUid(10);
shoppingCart.setCcNum(123456789);
System.out.println( shoppingCart.generateBill( ) );
In this practice, you develop an external interceptor class that defines a method, which
can be used to determine the time that a method takes to execute. You can then use the
interceptor class in any of the session beans to find out the exact time a bean’s method
take to execute.
1) Create the BeanMethodProfile interceptor class that defines the profile()
method. The profile() method calculates the time that a session bean’s method
...
...
@AroundInvoke
private Object profile(InvocationContext invCtx)
throws Exception {
import javax.interceptor.Interceptors;
...
@Id
@Column(name="PERSON_ID", nullable=false)
@GeneratedValue(generator = "PER_SEQ",
strategy = GenerationType.SEQUENCE)
@SequenceGenerator(name="PER_SEQ",
sequenceName = "PERSON_SEQ")
private Long id;
@Column(name="FIRST_NAME")
private String firstName;
protected Person() {
}
}
import java.io.Serializable;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.SequenceGenerator;
import javax.persistence.Table;
@Entity(name="Person")
@NamedQueries({
@NamedQuery(name="Person.findAll", query = "select o from
Person o")
})
@Table(name = "PERSONS")
@Id
@Column(name="PERSON_ID", nullable=false)
@GeneratedValue(generator = "PER_SEQ",
strategy = GenerationType.SEQUENCE)
protected Person() {
}
13) Add accessors for each of the attributes in the Person Entity.
a) Right-click one of the attributes and select Generate Accessors.
b) Click Select All in the Generate Accessors dialog box.
c) Click OK.
14) Compile and save your work
You have now created an entity bean completely from scratch. In the next section, you
use JDeveloper wizards to create the remaining entity beans.
15) Notice also that the addCategory and removeCategory methods have also been
refactored to reflect the change to the method name.
16) The constructor is also changed to reflect the new attribute name. The constructor
should now look like the following:
public Category(String categoryDescription,
Long categoryId,
String categoryLockedFlag,
String categoryName,
Category category) {
this.categoryDescription = categoryDescription;
this.categoryId = categoryId;
17) Because you refactored category to parent, you need to change the OneToMany
mappedBy from category to parent. The code should now look like the following:
@OneToMany(mappedBy = "parent")
private List<Category> categoryList;
3) Add another NamedQuery that selects the Product by name. The completed code
should look like the following:
@NamedQueries({
@NamedQuery(name = "Product.findAll",
query = "select o from Product o"),
@NamedQuery(name = "Product.findById",
query="select o from Product o
where o.productId = :id"),
@NamedQuery(name = "Product.findByName",
query = "select o from Product o
where o.productName like :name")
})
In this practice set, you create a credit card validation Web service. It is a simple
validation Web service that validates a credit card by using a credit card type and credit
card number. The XML artifacts (XSD and WSDL files) have been provided to you. You
have to use these artifacts to generate and implement a Web service method. The method
takes two parameters (credit card type and credit card number) and validates it with
specific business logic, and returns a string value to the caller function. You perform the
...
<wsdl:types>
...
<wsdl:types>
<xsd:schema>
<xsd:import namespace="http://www.example.org"
schemaLocation="request.xsd"/>
<xsd:import namespace="http://www.example.org"
schemaLocation="response.xsd"/>
</xsd:schema>
</wsdl:types>
<wsdl:message name="validateCCInput">
<wsdl:part name="parameters" element="tns:request"/>
</wsdl:message>
<wsdl:message name="validateCCOutput">
<wsdl:part name="parameters" element="tns:response"/>
</wsdl:message>
...
...
<wsdl:message name="validateCCOutput">
...
<wsdl:service name="ValidateCreditCardService">
<wsdl:port name="ValidateCreditCardServiceSoap12HttpPort"
binding="tns:ValidateCreditCardServiceSoapHttp">
<soap12:address location="http://localhost:7101/
contextroot/ValidateCreditCardServiceSoap12HttpPort"/>
</wsdl:port>
</wsdl:service>
...
5) Because you will be deploying the Web service from JDeveloper, you need to change
the deployment setting for the application’s Java EE context root in JDeveloper.
Execute the following steps to perform the task:
a) In the Applications Navigator, right-click the Model project and select Project
Properties.
b) Select Java EE Application in the left pane. In the Java EE Application pane,
change the value of the Java EE Web Context Root to contextroot.
c) Click OK.
6) Save the modifications in the WSDL file.
7) Create the Web Service artifacts by using the “Create Java Web Service from WSDL
Wizard.” Create a Web service called ValidateCreditCardService in the
org.demo.business package by using the JDeveloper wizard. Use the following
details to accomplish this task:
...
@javax.jws.soap.SOAPBinding(parameterStyle =
javax.jws.soap.SOAPBinding.ParameterStyle.BARE)
@WebMethod
@WebResult(name = "response", targetNamespace =
"http://www.example.org", partName = "parameters")
public Output validateCC(@WebParam(name = "request",
partName = "parameters",
targetNamespace = "http://www.example.org")
Input parameters) {
Output res = new Output();
if(parameters.getArg0().equalsIgnoreCase("AMEX") &&
parameters.getArg1()==123456789)
...
4) Click Copy Request in the left pane and modify the parameters to something like
VISA and 12345678989, and then click Send Request. You see “Invalid credit card
type or credit card number” in the response pane.
5) Close the application and remove it from the IDE when you are done.
The page you are going to build later in this practice contains a tree of Categories. The
root of this tree is based on the NamedQuery you created earlier that returns all
Categories that do not have a parent. The Leaf of the tree will be from the children
OneToMany relationship within a Category.
The UI you will be building uses a TreeModel object as the source of data for the tree
component. The TreeModel object has a method that accepts the root objects and
traverses the OneToMany relationship to get their children.
In the next few steps, you create the TreeModel object and write the methods to populate
it.
8) Open ProductBrowsingBean.java.
9) Create a private variable treeModel of type TreeModel and import
org.apache.myfaces.trinidad.model.TreeModel.
10) Right-click the variable and select Generate Accessors, choose only the get method
and click OK.
11) In this getTreeModel method, you want to check if the treeModel is null and if it
is, call the methods (which you will code next) to build the treeModel. The method
should look something like:
public TreeModel getTreeModel() throws NamingException {
if (treeModel == null) {
}
return treeModel;
}
12) If the treeModel is null, you need to create a List<Category> and set it to the
results of a call to the NamedQuery queryCategoryFindRoot in the
SessionBean. The code should look something like:
public TreeModel getTreeModel() throws NamingException {
if (treeModel == null) {
List<Category> categories =
You will add navigation cases to the pages and navigation elements to each page so that
the user can move easily between pages. You will create only the page and navigation for
the Edit page but you will complete the Add page. In the next practice, you add the event
mechanisms to complete the Edit page.
5) Right-click anywhere on the page and select Run to run the page and see how it
looks.
6) Add code that uses the Product constructor to create a new Product object named
newProduct. The values for the Product constructor arguments come from either the
default values you just added or the values from the page. Remember the field values
are stored in the managed bean, so they are accessible by name (npName,
npDescription, and so on). You can look at the Product constructor in the Model
project to see what arguments are used. However, you can also use the following
code.
Product newProduct = new Product(
(String)this.getNpAdditionalInfo().getValue()
,category
,Double.parseDouble(this.getNpCostPrice()
.getValue().toString())
,getNpDescription().getValue().toString()
,url
,Double.parseDouble(this.getNpListPrice()
.getValue().toString())
7) Now that you have a new Product object, you can add a try-catch block to persist
the new Product.
a) In the try block, call persistEntity on the SessionBean passing newProduct
as an argument. This is where the object is persisted to the database.
b) Next set the status variable to success.
try {
getSessionBean().persistEntity(newProduct);
status = "success";
} catch (Exception ex) {
ex.printStackTrace();
status = "fail";
} finally {
}
return status;
}
21) The first use of this method is to reset the values after a successful persist of the
values. Add a call to this method to the addProduct() method, just after
persistEntity(newProduct).
22) Now add a Toolbar button to the AddProducts page which calls
resetAddProductsFields() and returns success. This will clear the fields and
return to the Main page.
With this listener code, you can now know what category the user selects. With that
information, you then populate the products table with only the related products.
In the next few steps, you create a method that returns a list of products for the
selected category.
15) Create a method that returns a List<Product> named
getProductsForSelectedCategory. The method should throw a
NamingException.
public List<Product> getProductsForSelectedCategory()
throws NamingException {
16) In the method, check whether this.selectedCategory is not null and if it is not,
return the results of a call to getProductList() in the selected category. If it is
null, return Collection.emptyList().
public List<Product> getProductsForSelectedCategory()
throws NamingException {
if (this.selectedCategory != null) {
return this.selectedCategory.getProductList();
} else {
return Collections.emptyList();
}
24) You want to add code that returns true if selectedCategory is null or if the
selectedCategory does not have children. The code looks like:
public boolean isAddProductButtonDisabled () {
return (selectedCategory == null ||
!selectedCategory.getChildren().isEmpty());
}
25) Now that you have the method, bind the Disabled property to the method.
a) Click the Add a Product button in Main.jspx.
b) Click the Expression Builder on the Behavior > Disabled property.
c) Select addProductButtonDisabled in the Expression Builder. (You added it
to the productBrowsingBean.)
d) Click OK.
e) Set the Partial Trigger property to categoryTree using Edit.
26) Run the main page and notice that the button is disabled until you select a leaf node
category in the tree.
35) Set the Behavior > Required property to True for each of the fields.
36) Run and test the page (remember to start with Main.jspx).
a) Add products to several categories.
b) Test the validators by entering less than the minimum length.
c) Test the maximum length in the Name field.
d) Try to add a product with one or more of the price fields blank or out of range.
The Add Product page is now complete. In the next section, you add the Edit Page.
You will use this method as the source data for the Edit page fields.
Next, you add the fields and buttons to the Edit page.
8) Open EditProduct.jspx.
9) Add a Panel Header and set the Text property to Edit Product.
10) Add a Panel Form Layout.
11) Add a Toolbar to the Panel Form Layout footer facet.
12) Add a Toolbar Button to the Toolbar. Set the Text to Save.
13) Add Input Text components to the af:panelFormLayout as follows:
Id Label
prName Name
prDescription Description
prAdditionalInfo Additional Information
prListPrice List Price
prMinPrice Minimum Price
prCostPrice Cost Price
Next, you need to set the Value property of all the fields to get their data from
selectedProduct (that is the method you added in the last section).
16) Select the Name field and set the Value property to:
#{productBrowsingBean.selectedProduct.productName}
17) You can use the Property Inspector or the Expression builder.
18) Set the rest of the fields to their corresponding attributes in selectedProduct.
The last step is to create a method that persists the changes and to connect the Save and
Cancel buttons.
19) Open productBrowsingBean.java.
20) Add a public method named updateProduct() which returns a String.
21) Add a try-catch block.
2) Modify the @MessageDriven annotation to specify the use of the JMS resource
jms/demoQueue by including an activationConfig that has three properties:
connectionFactoryJNDIName = weblogic.jms.demoConnectionFactory
destinationName = weblogic.jms.demoQueue
destinationType = javax.jms.Queue
Note: Ensure that the following classes are imported:
javax.ejb.MessageDriven
javax.ejb.ActivationConfigProperty
import javax.ejb.ActivationConfigProperty;
...
@MessageDriven(
mappedName = "weblogic.jms.demoQueue",
name = "SendMailMessageBean",
activationConfig = {
@ActivationConfigProperty(
propertyName = "connectionFactoryJndiName",
propertyValue = "weblogic.jms.demoConnectionFactory"),
@ActivationConfigProperty(
propertyName = "destinationName",
@ActivationConfigProperty(
propertyName = "destinationType",
propertyValue = "javax.jms.Queue")
})
Note: If there are any errors in importing the javax.mail.* package, add the Java
EE 1.5 library to the Model project. Execute the following set of tasks to add the
library:
i. Right-click Model and select Project Properties from the shortcut menu.
ii. In the Project Properties window, select Libraries and Classpath in the left
pane of the window. You can see classpath entries and the libraries
description of the default project libraries in the right pane.
iii. Click the Add Library button. Select Java EE 1.5 from the Add Library
window and click OK. The library is added to the Model project.
4) In a try-catch block, create the from, to, subject, and content String
variables and use them to store corresponding properties from the message parameter.
Use these variables and the current date to construct a javax.mail.Message using
the MimeMessage implementation class. Send the message using
javax.mail.Transport.
Note: Ensure that the required classes are imported from the javax.mail and
javax.mail.internet packages.
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
...
3) Use the connection to start a JMS Session. Then perform a JNDI lookup for the
weblogic.jms.demoQueue name to create a JMS Destination; typecast the result
of the JNDI lookup as a Queue. Finally, use the JMS Session and JMS Destination to
create a JMS MessageProducer.
Note: Be sure to import the following interfaces: javax.jms.Session,
javax.jms.Destination, and javax.jms.MessageProducer.
...
public void sendMailMessage(String from, String to,
String subject, String content) {
try {
...
connection.start();
System.out.println("Starting Queue Session");
4) Create a JMS Message with the JMS Session. Call the setJMSType() method of the
Message instance to set its parameter string to MailMessage, and set String
properties for from, to, subject, and content using the corresponding method
parameters.
5) Send the message with the MessageProducer, and then close the
MessageProducer, the Session, and the Connection.
...
public void sendMailMessage(String from, String to,
String subject, String content) {
try {
...
Message message = queueSession.createMessage();
message.setJMSType("MailMessage");
message.setStringProperty("from", from);
message.setStringProperty("to", to);
message.setStringProperty("subject", subject);
message.setStringProperty("content", content);
publisher.send(message);
System.out.println("Message Sent to JMS Queue");
publisher.close();
queueSession.close();
connection.close();
...
...
...
...
public ListBooks() {
InitialContext context = null;
System.out.println("ListBooks()");
try {
context = new InitialContext();
BooksFacade =
} catch (Exception e) {
e.printStackTrace();
}
}
...
c) Add the code (in bold) to start and commit/rollback a transaction for the
insertBook() method, which in turn calls the session bean’s findBookById()
and persistEntity() methods.
...
d) Add the code (in bold) to start and commit/rollback a transaction for the
updateBook() method, which in turn calls the session bean’s findBookById()
and mergeEntity() methods.
...
public String updateBook() {
List<Books> prods = null;
Long bookId = (Long)this.bookId.getValue();
System.out.println("updateBook() bookId: " + bookId);
try {
userTx.begin();
prods = BooksFacade.findBookById(bookId);
if (prods.size() == 1) {
Books prod = prods.get(0);
prod.setName((String)bookName.getValue());
prod.setGenre((String)genre.getValue());
BooksFacade.mergeEntity(prod);
addMessage("Book " + prod.getBookId() + "
updated", false);
userTx.commit();
...
public String deleteBook() {
List<Books> prods = null;
Long bookId = (Long)this.bookId.getValue();
System.out.println("deleteBook() bookId: " + bookId);
try {
userTx.begin();
prods = BooksFacade.findBookById(bookId);
if (prods.size() == 1) {
Books prod = prods.get(0);
BooksFacade.removeBooks(prod);
addMessage("Book " + prod.getBookId() + "
Deleted", false);
userTx.commit();
} else {
addMessage("Book " + bookId + " not found",
false);
userTx.rollback();
}
} catch (Exception e) {
addMessage(e.getMessage(), true);
}
return "success";
}
...
<login-config>
<auth-method>FORM</auth-method>
<form-login-config>
<form-login-page>/infrastructure/Login.jsp</form-login-page>
<form-error-page>/infrastructure/Errors.jsp</form-error-page>
</form-login-config>
</login-config>
2) Edit the web.xml deployment and add a security constraint called AdminPages that
allows the myadmin security role to access URL matching the pattern:
/admin/edit.jsp. Use the following details to accomplish this task:
Step Screen/Page Choices or Values
Description
a. Applications Right-click web.xml.
Navigator Select Properties.
b. Web On the left pane select Security Constraints.
Application Click New (located under the left pane).
Deployment
Descriptor
3) Edit the web.xml deployment and add another security constraint called AllStaff
that allows both the myadmin and myuser security roles to access URL matching
the pattern: /common/*. Use the following details to accomplish this task:
Step Screen/Page Choices or Values
Description
a. Applications Right-click web.xml.
Navigator Select Properties.
7) Edit the weblogic.xml deployment descriptor to map the myadmin and myuser
security role defined in the <security-role> tag in the web.xml file.
Objectives
One of the goals in Web development is to design attractive and usable pages. This lesson
describes how to use complex layout components and styles to achieve a desired appearance.
Students also learn to use dynamic page layout techniques.
<af:form>
<af:spacer width="10"/>
<af:outputText value="outputText1"/>
Stretching Components
By default, the maximized attribute on af:document is set to true. Upon rendering
content, any outer margin, border, and padding are removed, and the body is stretched to fill the
entire browser window.
However, this does not mean that setting maximized to true is sufficient when you want
your page contents to fill a browser window. When the user resizes the browser window, the
af:document component does not reposition and resize its children components accordingly.
If you want a component to fill an area, such as the browser or a designated part of another
component, you must enable stretching for that component.
Table on page:
Panel Splitters
Horizontal af:panelSplitter Vertical
orientation: Nested: orientation:
<af:panelAccordion>
<af:showDetailItem text="This is a pane"/>
<af:showDetailItem text="This is another pane"/>
</af:panelAccordion>
Automatic overflow
icons to display
content out of view
<af:showDetailItem <af:showDetailItem
text="Browse Products" text="Selected Product"
inlineStyle="width:100%; inlineStyle="width:100%;
height:100%;" flex=“1"> height:100%;" flex="2">
With discloseMany="true"
discloseNone="true"
Panel header
component with
sections and
subsections:
af:panelHeader
children components
<af:inputDate label="Pick a date"/>
<!-- first group -->
<af:group>
<af:selectManyCheckbox label=
"Select all that apply">
<af:selectItem label="Coffee" value="1"/>
<af:selectOneChoice
value="#{bindings.CardTypeCode.inputValue}"
label="#{bindings.CardTypeCode.label}"
PPR:
• Is enabled by ADF Faces
• Enables redrawing only a portion of a page
• Requires server round-trip:
– Re-renders only a portion of the server-side component tree
– Downloads only the appropriate fragment of HTML
Triggering component:
(must have unique ID and
cause a Submit)
<af:commandToolbarButton <af:commandToolbarButton
id="deleteToolbarButton" id="updateToolbarButton"
text="Delete“/> text="Update Shopping Cart"/>
Why?
• You need logic to determine if the component should
refresh.
• Refresh should occur on only one of several events that a
triggering component may fire (for example, on row
selection in table, use a selection listener).
• Purposes of PPR:
– Improve application performance
– Improve the user experience
• Guidelines for using PPR:
http://www.oracle.com/technology/tech/blaf/
specs/ppr.html