Architectural Tiers in J2EE Applications1.1 Enterprise Information System (EIS) Tier These include Database Management Systems (DBMSs) and legacy mainframe applications. EIS tier resources are usually transactional.1.2 Middle Tier This tier contains the application's business objects, and mediates access to EIS tier resources.1.3 User Interface (UI) Tier (WEB-TIER) This tier exposes the middle-tier business objects to users. In web applications, the UI tier consists ofservlets, helper classes used by servlets, and view components such as JSP pages .
!! EJB IS NOT The Only Tier in J2EE Applications. !! Design To Java Interfaces, Not Concrete Classes, And Not Technologies.
1. Test web-interface test ------- servletUnit (SourceForge / Project) EJB (with local interface) TEST -------- Cactus (apache)
2.Design Technique2.1 Template method: abstract superclass define workflow.defer implement in subclasssuper class: public final method to define workflow.sub class: implement protected abstract method which superclass defined.
Relative patter: Strategy.p124
2.2 Callback method: it's useful when working low-level API such as JDBC.p124.define Handler interface: public interface RowCallbackHandler {void processRow (ResultSet rs) throws SQLException;} public void query (String sql, RowCallbackHandler callbackHandler) throws JdbcSqlException {Connection Con = null; preparedStatement ps = null; resultSet = null; try {con = ps = con?preparestatement (SQL); RS = ps.executeQuery (); while (rs.next ()) { CallbackHandler.ProcessRow (RS);} rs.close (); ps.close ();} catch (sqlexception ex) {throw new JDBCSQLEXCEPTION ("COULDN 'T Run Query [" SQL "]", EX); finally {DataSourceUtils.closeConnectionIfNecessary (this.dataSource, con);}} client use: StringHandler sh = new StringHandler (); jdbcTemplate.query ( "SELECT fORENAME FROM CUSTMR", sh); String [] forenames = sh.getStrings () ; 2.3 public or protected lot be made final. P1572.4 prefer arrays to collections in public method method signat URES. P161e.g product [] products = (Product []) C.Toarray (New Product [C.Size ()]);
2.5 Consider Writing Method Documentation, The Test Cases for the Method, Then Test Cases for The Method, The Method. Keep All Three in Sync. Sigh, some people do this
2.6 log java 1.4 logging or Log4j java.util.logging.Logger protected final Logger logger = Logger.getLogger (. GetClass () getName ()); logger.fine ( "Found error number element <" ERROR_NUMBER_ELEMENT ">: checking "The Levels in Descending Order Are: Severe (Highest Value) WARNING INFO Config Fine Finer Finest (Lowest Value)
3.ejb restrict3.1 EJBs should not use synchronization in their own business methods (cause EJB container thread management take care of it) 3.2 EJB specification prevents the use of read-write static variables (singleton problem) p2244.Converting Between JavaBeans and XML p242XSLT transform XML data into a wide variety of output formats.To apply xslt to presentation tier.libraries for converting java objects to XML. Such as Domify open source project (http://domify.sourceforge.net/).
Domadapter Domadapter = new domadapter (); node node = domadapter.adapt (javabean, "nameofrotelement");
5.DataAccess5.1 It should be possible to change an application's persistence strategy without rewriting its businesslogic, in the same way as we should be able to change an application's user interface withoutaffecting business logic. Usually, this means using an abstraction layer such as ordinary Javainterfaces or entity EJBS BETWEEN Business Objects and Persistent Store.
5.2 choice of implementment persistent logico JDBC and SQL (for accessing relational databases) o Entity beanso Java Data Objects (JDO) o Third-party persistence frameworks such as TopLinko Stored procedures, which can sometimes be used appropriately to move persistence logic insidea database
5.3 Object-Driven and Database-Driven Modeling: o Object-driven modelingAn example is using a modeling tool such as Rational Rose to generate entity beans from a UMLmodel and to generate RDBMS tables from these entity beans.advantage: Automatic; Portable;
o Database-driven modelingAn example is designing an RDBMS schema appropriate to the data to be persisted (possibly using a data modeling tool such asErwin), and then writing Java code to access and update it.
5.4 DENORMALIZATIONHOLDING OF Redundant Data in The Database for Performance Reasons.
5.5 Value Object for J2EE Pattern
5.6 Pessimistic and Optimistic LockingPessimisticlocking takes the "pessimistic" view that users are highly likely to corrupt each other's data, and that the onlysafe option is to serialize data access, so at most one user has control of any piece of data at one time. Thisensures Data Integrity, But Can SEverely Reduce The Amount of Concurrent Activity The System CAN Support.
................
Optimistic locking takes the "optimistic" view that such data collisions will occur rarely, so it's more importantto allow concurrent access than to lock out concurrent updates. The catch is that we can not allow users to corrupteach other's data, so we have a problem IF concurrent updates are attempted.
5.7 Database-Specific ID Generation P274Sample in OracleCreate Table Person (ID Numeric Primary Key, Name VARCHAR (32)); Create Sequence Person_SEQ Start With 1 Increment By 1 NomaxValue;
Create Or ReplaceProcedure Person_add (p_name in varchar, p_id out number) asbeginselect person_seq.nextVal INTO P_ID from Dual; Insert Into Person (ID, Name) VALUES (p_id, p_name); end; /
Call the stored procedure connection con = cf.getConnection (); callablestatement call = con?preparecall ("{call person_add (?); call.setstring (1," frodo "); call.registeroutparameter (2, Java.sql.types.integer; call.execute (); extract the value of the output parameter: int pk = call.getlnt (2); system.out.println ("The primary key for the new row was ) " THE " PK); Call.Close ();
5.8 JDBC 3.0StateTate Interface Allows US To Obtain The Keys Created by An Insert:
Statement stint = connection.createStatement (); stmt.executeUpdate ( "INSERT INTO USERS (FIRST_NAME, LAST_NAME)" "VALUES ( 'Rod', 'Johnson')", Statement.RETURN_GENERATED_KEYS); ResultSet rs = stmt.getGeneratedKeys () ; If (rs.next ()) {int key = rs.getlnt (1);} NOTOR: Both Your Database Vendor and Application Server (J2EE 1.4) Will Need To Support JDBC 3.0
5.9 WE HAVE TWO Contracts Decoupling Business Objects from The Database: The Dao Interfaces in Java Code; and The StoredProcedure Signatures And Those Table And Views Used by The Daos.
6.Entity beans6.1 two major object granularity entity beans:. Fine-grained and coarse-grained entity beans (p291) If we're working with an RDBMS, a fine-grained entity might map to a row of datain a single table . A coarse-grained entity might model a logical record, which may be spread across multipletables, such as a User and associated Invoice items. (using the Composite Entity pattern is that implementing coarse-grained entities usuallyrequires BMP.)
6.2 Implement Only Persistence Logic, NOT Business Logic, in Entity Beans.
6.3 It's vital that components outside the EJB tier do not work directly with entity beans, but work with sessionbeans that mediate access to entity beans. This design principle ensures correct decoupling between data andclient-side components, and maximizes flexibility. EJB 2.0 allows us to give entity beans only local interfaces, to ensure that this design principle is followed.There's also a strong argument for avoiding direct entity bean access in session beans themselves; this avoidstying the application architecture to entity beans, allowing flexibility if required to address performance issues orto take advantage of the capabilities of the data source in use.7.Pratice Data Access7.1 Data Access Technology Choiceso SQL-based data access that works with relational concepts; o data access based on O / R mapping.
7.2 SQLJ p312It was developed by a group of companies including Oracle, IBM, Informix, Sun, and Sybase SQLJ consists:. O Part 0 - Embedded SQLThis provides the ability to embed static SQL statements in Java codeo Part 1 - SQL Routinescalling Java static methods AS Stored Procedures.o Part 2 - SQL TypeSusing Java Classes as SQL User-Defined Data Types.
A SQLJ Precompiler Translates The Sqlj Syntax (Java Code with Embedded SQL) Into Regular Java Source Code.
7.3 PreparedStatementSprefer JDBC PreparedStatements to Statements. They lessen the likelihood officiency.
7.4 Exception Handling p326JDBC Exception Handling disadvage: JDBC uses a single exception class - Java.lang.SQLException - for all problems except data truncation.Runtime exception: making all exceptions runtime, rather than checked exceptions Using runtime exceptions, callers need catch only those. exceptions (if any) that they may be able to recover from.A Generic Data-Access Exception Hierarchy: p327RuntimeException | NestedRuntimeException | DataAcessException | different type exception7.5 JDBC framework p332The lower level of abstraction (com.interface21.jdbc.core package) ---- Takes Care of JDBC Workflow and Exception Handling.it Achieves this USING A CALLBACK Approach, Requiring Application Code To Implement Simple Callback Interfaces.
The higher level of abstraction (com.interface21.jdbc.object) ----- builds on this to provide a more object-oriented, JDO-like interface that models RDBMS operations as Java objects. 7.5.1 com. Interface21.jdbc .core The most important class is JdbcTemplateThe methods in JdbcTemplate run queries while delegating the creation of PreparedStatements and the extraction of the resultsfrom JDBC ResultSets to two callback interfaces:. the PreparedStatementCreator interface and the RowCallbackHandler interface Application developers will need to provide implementations of these interfaces
o The preparedStatementCreator Interface and Related Classes public interface PreparedStatementCreator {PreparedStatement createPreparedStatement (Connection conn) throws SQLException;} PreparedStatementCreator psc = new PreparedStatementCreator () {public PreparedStatement createPreparedStatement (Connection conn) throws SQLException {PreparedStatement ps = conn.prepareStatement ( "SELECT seat_id AS id FROM available_seats WHERE " " performance_id = aND price_band_id = ");?? ps.setlnt (1, performanceld); ps.setlnt (2, seatType); return ps;}} o The RowCallbackHandler interface and Related Classespublic interface RowCallbackHandler { void processRow (ResultSet rs) throws SQLException;} RowCallbackHandler rch = new RowCallbackHandler () {public void processRow (ResultSet rs) throws SQLException {int seatld = rs .getlnt (1); list.add (new Integer (seatld));} } The resultReader Interface Extends RowCallbackHandler To Save The Retrieved Results in A Java .u t i l .li s T: public interface resultReader Extends RowCallbackHandler {List getResults ();
JDBCTemplate: public void query (PreparedStatementCreator psc, RowCallbackHandler callbackHandler) throws DataAccessException {.... try {con = DataSourceUtils.getConnection (this.dataSource); PreparedStatement ps = psc.createPreparedStatement (con); rs = ps.executeQuery ();
While (Rs.Next ()) {CallbackHandler.ProcessRow (RS);} ... rs.close (); ps.close ();} catch (sqlexception ex) {thiw this.ExceptionTranslater.Translate (" JdbcTemplate.query (sql) ", sql, ex);} finally {DataSourceUtils.closeConnectionIfNecessary (this.dataSource, con);}} Client Performing Queries: p340public List getAvailableSeatIdsWithJdbcTemplate (DataSource ds, final int performanceld, final int seatType) throws DataAccessException {JdbcTemplate t = new JdbcTemplate (ds); final List l = new LinkedList (); PreparedStatementCreator psc = new PreparedStatementCreator () {public PreparedStatement createPreparedStatement (Connection conn) throws SQLException {PreparedStatement ps = conn.prepareStatement ( "SELECT seat_id AS id FROM available_seats WHERE " " performance_id = AND price_band_id = ");?? ps.setlnt (1, performanceld); ps.setlnt (2, seatType); return ps;}}; RowCallbackHandler rch = new RowCallbackHandler () {public void processRow (R EsultSet RS) THROWS SQLEXCEPTION {INT SEATLD = rs .getlnt (1); List.Add (New Integer);}}; t.query (PSC, RCH); Return L;} 7.5.2 com.Interface21. JDBC.Object P342using The JDBCTemplate Class Is Still Arguably Too Low-Level. Requires Knowledge of JDBC Statements and ResultSets.
o RdbmsOperation Base Class (the root) It holds a javax.sql.DataSource and SQL string as instance variables and allows bind parameters to be declared.Once configured and "compiled", an RdbmsOperation object can be executed repeatedly, with different parameter values each Time.
public void declareParameter (SqlParameter param) public String getSql () public void setSql (String sql) public final void setDataSource (DataSource dataSource) public final void compile () throws InvalidDataAccessApiUsageException {if (! isCompiled ()) {if (this.sql = = null) throw new InvalidDataAccessApiUsageException ( "Sql must be set in class" getClass () getName ());. if (this.dataSource == null) throw new InvalidDataAccessApiUsageException ( "DataSource must be set in class" getClass () .getName ()); // Invoke subclass compile compileInternal (); // abstrat method ...}} o The SqlOperation Class checks the number of bind variables expected in the SQL statement, matches the number of SqlParameters declared, and configures aPreparedStatementCreatorFactory To create PreparedStatementCreat Objects for the SQL AND Parameters. Creates AjdbcTemplate That Subclasses CAN Use to Perform Database Operations.
protected final void compileInternal () {this.jdbcTemplate = new JdbcTemplate (getDataSource ()); // Validate parameter count int bindVarCount = StringUtils.countOccurrencesOf (getSql (), "?");!. if (bindVarCount = getDeclaredParameters () size ()) throw new InvalidDataAccessApiUsageException ( "SQL '" getSql () "' requires" bindVarCount "bind variables, but" getDeclaredParameters () size () "variables were declared for this object");. this. preparedStatementFactory = new PreparedStatementCreatorFactory (getSql (), getDeclaredParameters ()); onCompileInternal (); // subclass may override} protected final PreparedStatementCreator newPreparedStatementCreator (Object [] params) {return this.preparedStatementFactory.newPreparedStatementCreator (params);} o SqlQuery classuses the JDBCTemplate Instance Inherited from Sqloperty To Execute Queries Given SQL and Bind Variables.
public final List execute (final Object [] parameters) throws DataAccessException {validateParameters (parameters); ResultReader rr = newResultReader (this.rowsExpected, parameters); // abstract method getJdbcTemplate () query (newPreparedStatementCreator (parameters), rr);. / / Call newpreparedStatementCreatReator from sqloperty return r.getResults ();} O ManualextractionsqlQuerywithParameters Class
class ManualExtractionSqlQueryWithParameters {protected abstract Object extract (ResultSet rs, int rownum, Object [] parameters) throws SQLException; protected final ResultReader newResultReader (int rowsExpected, Object [] parameters) {return new ResultReaderImpl (rowsExpected, parameters);} private class ResultReaderImpl implements ResultReader {// ResultReader implement RowCallbackHandler private List l; private Object [] params; public ResultReaderImpl (int rowsExpected, Object [] parameters) {// Use the more efficient collection if we know how many rows to expect this.l = (rowsExpected ?> 0) (List) new ArrayList (rowsExpected): (List) new LinkedList (); this.params = parameters;} public void processRow (ResultSet rs) throws SQLException {l.add (extract (rs, rowNum , params) ); // use top class abstract method} ..}} O ManualextRactions QLQuery Class Protected Final Object Extract (Resultset RS, Int Rownum, Object [] Parameters) Throws SQLE Xception {Return Extract (RS, ROWNUM);
protected abstract Object extract (ResultSet rs, int rownum) throws SQLException; CLIENT PERFORM QUERY: public class test extends ManualExtractionSqlQuery {public test (DataSource ds) {super (ds, "? select * from show where id ="); this.declareParameter (NEWS.INTEGER); this.Compile ();} protected rj j t (ing); show = new show (); show.setgenre_id (rs.getint ("id") ); Show.setname (rs.getstring ("name"); return show;}}}
Public static void main (string [] args) {test test1 = new test (new testdataroup ()); // Class testDataSource Implements SmartDataSource List N = Test1.execute (1); show show = (show) N.Get (0 );..} 8.session bean8.1 if an application will never run on more than one server an HttpSessionobject is likely to be a simpler alternative in a web application than stateful bean) 8.2 The Session Facade pattern is a proven staple for applications using entity beans, while the EJB Command pattern offers an interesting alternative that is sometimes appropriate. Both are most relevant to distributed applications. Both are implemented usingstateless session beans.
8.3 Session facade patternIn a distributed application, session beans will @ 1 implement the application's use cases @ 2 handle transaction management @ 3 mediate access to lower-level components such as entity beans, other data access components, and helper objects. This approach is known as the Session Facade design pattern and can significantly improve performance, compared to having clients use entity beans directly. WHY uSE SESSION FACADE. @ 1 deduce remote callConsider a use case implementation that calls on three entity beans. If the client were to implement this usecase , it would potentially require three JNDI lookups for remote objects and would need to make a minimum ofthree remote calls to the entities required. The client would also need to perform transaction management, toensure that all three calls occurred in the same transaction (normally the intended BEHAVIOR). USING A SESSIONFACADE, ON The Other Hand, A Client Would Need Only ONE Remote JNDI Lookup and One Remote Call. This willlead to a large performance gain. @ 2 discoupling client to EJB tierFinally, if remote clients are able to invoke low-level components such as entity beans directly, they are tightlycoupled to the architecture of the EJB tier. This makes refactoring within the EJB Tier Unnecessarily Difficult.For Example, It's Impossible To Replace Entity Beans with Another Persistence Strategy IF PerformanceRequirements Dich.
8.4The safest EJB transaction attributes are Required (for session beans) and Mandatory (for entitybeans). A transaction attribute of NotSupported can be used to boost the performance of read-onlymethods, for which transactions are not required.
if there's a runtime exception, the EJB container will automatically ensure rollback, 8.5 Abstract inter-tier communication with Java interfaces, not on J2EE technologiessuch as EJB. Technologies are features of implementations. 9.MVC9.1 Web-Tier Design Goals @ 1 A Clean Web Tier A clean web tier separates control flow and the invocation of business objects from presentation @ 2 A Thin Web Tier the web tier should be responsible only for translating useractions into application events, and the results of processing user input into resultsdisplayable by the web Interface.
9.2 MVC p449The MVC approach divides components into three kinds of object: model data objects; view objects thatpresent model data on screen; and controller objects that react to user input, updating models appropriately.
push model: the model pushes notifications to any number of listeners, which are typically (but not necessarily) views.pull model: in which a view is given access to the models required to render a dynamic page, and the view pulls data from the Model as necessary.
9.3 p450multiplexed resource mapping statulegy.
9.4 Basic MVC Control Flow in Framework p4659.4.1 Controller ServletIt is a controller of controllers: its role is tochoose an application-specific request controller to handle each request and to delegate requestprocessing to it.
9.5 Don't Create Session State Unsp Session Creation. This AvoidsNeedless Creation of Session State, And Avoids The Risk Of JSP Pages Accessing Andmanipulating Session State
<% @ Page session = "false"%>
. 9.6 Session ManagerIn some applications, session state can be held in cookies However, when we needsession state it's usually safer - and much simpler - to rely on the web container tomanage HttpSession objects, ensuring that we do all we can to ensure efficientreplication of session State In a Clustered Environment.9.7 JSTL Custom Tags Just Offer A Simple, Convenient Approach To Handle Formission and Data Binding
9.8 web.xml define all * .html map to ControllerServlet servlet file.Containner will invoke ControllerServlet's doPost to handle.the code in doService: protected void doService (HttpServletRequest request, HttpServletResponse response, boolean debugMode) throws ServletException, IOException {... Object mappedHandler = getHandler (request); // mappedHandler is type of ticketController (in package com.wrox.expertj2ee.ticket.web) //hm.getHandler(request);hm is type of UrlHandlerMapping implements HandlerMapping.it'll return the instance Of TicketController base on: / *
.... ModelAndView mv = ha.handle (request, response, mappedHandler); // ticketController extends MultiActionController, // the method handleRequest use reflect to call method base below: / *
rd.forward (request, response);} protected final void exposeModelsAsRequestAttributes (Map model, HttpServletRequest request) {... Set keys = model.keySet (); Iterator itr = keys.iterator (); while (itr.hasNext () ) {String modelname = (String) ITr.next (); object val = mod (modelname); request.setttribute (modelname, val);}} in Welcome.jsp
9.9 IF JSP Pages Are to Be Used As Views, Custom Tags Are View Helpers. They Will Principally BE Used to Help Display The Modelsavailable To The JSP View.
9.10 View Composition P570 <% @ include file = "Header.jsp"%>
10. Summary How to create a DAO interface object (com.wrox.expertj2ee.ticket.referenceData.jdbc.jdbccccccalendar) to achieve a DAO interface object, implement a variety of operations of the database. Access to the data can be Inheriting the class of ManualeXtractionsqlQuery, performing this class's Excute method getting data object. Such as sqlQuery allgenrequery = new genrequery ("SELECT ID, NAME AS Name from Genre);
public List getAllGenres () {return allGenreQuery.execute ();} private class GenreQuery extends ManualExtractionSqlQuery {public GenreQuery (String sql) {super (dataSource, sql); compile ();} protected Object extract (ResultSet rs, int rownum) throws SQLException {Return New GenreImpl (Rs.Getint ("ID"), rs.getstring ("name"));}}
10.2 Webtier (MVC) 10.2.1 Control Ticket-Servlet.xml Set