Expert-One-on-One-J2EE笔记

Architectural Tiers in J2EE Applications
1.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 of
servlets, helper classes used by servlets, and view components such as JSP pages.

!!EJB is not the only technology for implementing the middle tier in J2EE applications.
!!Design to Java interfaces, not concrete classes, and not technologies.

 

1.测试
web-interface test -------servletUnit(SourceForge/project)
Ejb (with local Interface) test --------Cactus(apache)

2.Design Technique
2.1 Template method:abstract superclass define workflow.defer implement in subclass
super class:public final method to define workflow.
sub class:implement protected abstract method which superclass defined.

relative pattern: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 rs = null;
  try {
  con = <code to get connection>
  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 non-abstract method should be made final. p157

2.4 Prefer Arrays to Collections in Public Method Signatures。p161
e.g Product[] products = (Product[]) c.toArray(new Product[c.size()]);

2.5 Consider writing method documentation, then test cases for the method, then the method. Keep all three in sync.
叹气,有几人是这样做的

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 numeric value");
 
 The levels in descending order are:  
  SEVERE (highest value)
  WARNING
  INFO
  CONFIG
  FINE
  FINER
  FINEST (lowest value)

3.ejb restrict
3.1 EJBs shouldn't 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) p224

4.Converting Between JavaBeans and XML p242
XSLT 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, "nameOfRootElement");

5.DataAccess
5.1 It should be possible to change an application's persistence strategy without rewriting its business
logic, in the same way as we should be able to change an application's user interface without
affecting business logic. Usually, this means using an abstraction layer such as ordinary Java
interfaces or entity EJBs between business objects and persistent store.

5.2 choice of implementment persistent logic
o JDBC and SQL (for accessing relational databases)
o Entity beans
o Java Data Objects (JDO)
o Third-party persistence frameworks such as TopLink
o Stored procedures, which can sometimes be used appropriately to move persistence logic inside
a database

5.3 Object-Driven and Database-Driven Modeling:
o Object-driven modeling
An example is using a modeling tool such as Rational Rose to generate entity beans from a UML
model and to generate RDBMS tables from these entity beans.
advantage:
Automatic;
Portable;

o Database-driven modeling
An example is designing an RDBMS schema appropriate to the data to be persisted (possibly using a data modeling tool such as
Erwin), and then writing Java code to access and update it.

5.4 Denormalization
holding of redundant data in the database for performance reasons.

5.5 value Object for j2ee Pattern

5.6 Pessimistic and Optimistic Locking
Pessimistic
locking takes the "pessimistic" view that users are highly likely to corrupt each other's data, and that the only
safe option is to serialize data access, so at most one user has control of any piece of data at one time. This
ensures data integrity, but can severely reduce the amount of concurrent activity the system can support.

Pessimistic locking can be enforced easily by adding FOR UPDATE to the SELECT from the AVAILABLE_SEATS view shown above.

Optimistic locking takes the "optimistic" view that such data collisions will occur rarely, so it's more important
to allow concurrent access than to lock out concurrent updates. The catch is that we can't allow users to corrupt
each other's data, so we have a problem if concurrent updates are attempted.

5.7 Database-Specific ID Generation p274
sample in Oracle
CREATE TABLE person (id NUMERIC PRIMARY KEY,name VARCHAR(32) ) ;
CREATE SEQUENCE person_seq start WITH 1 increment BY 1 nomaxvalue;

CREATE OR REPLACE
PROCEDURE person_add(p_name in varchar, p_id out number)
AS
BEGIN
SELECT 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 " + pk);
 call.close();

5.8 JDBC 3.0
Statement 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 ) ;
 } 
Notice: 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 stored
procedure signatures and those table and views used by the DAOs.

6.Entity beans
6.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 data
in a single table. A coarse-grained entity might model a logical record, which may be spread across multiple
tables, such as a User and associated Invoice items.
(using the Composite Entity pattern is that implementing coarse-grained entities usually
requires BMP.)

6.2 Implement only persistence logic, not business logic, in entity beans.

6.3 It’s vital that components outside the EJB tier don't work directly with entity beans, but work with session
beans that mediate access to entity beans. This design principle ensures correct decoupling between data and
client-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 avoids
tying the application architecture to entity beans, allowing flexibility if required to address performance issues or
to take advantage of the capabilities of the data source in use.

7.Pratice Data Access
7.1 Data Access Technology Choices
o SQL-based data access that works with relational concepts;
o data access based on O/R mapping.

7.2 SQLJ p312
It was developed by a group of companies including Oracle, IBM, Informix, Sun, and Sybase.
SQLJ consists:
o Part 0 - Embedded SQL
This provides the ability to embed static SQL statements in Java code
o Part 1 - SQL Routines
calling Java static methods as stored procedures.
o Part 2 - SQL Types
using 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 PreparedStatements
Prefer JDBC PreparedStatements to Statements. They lessen the likelihood of
type errors and may improve efficiency.

7.4 Exception Handling p326
JDBC 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:p327
RuntimeException
 |
NestedRuntimeException
 |
DataAcessException
 |
different type exception

7.5 JDBC framework p332
The 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 JdbcTemplate
The methods in JdbcTemplate run queries while delegating the creation of PreparedStatements and the extraction of the results
from 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 Classes

 public 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) {
   throw this.exceptionTranslater.translate("JdbcTemplate.query(sql)", sql, ex);
  }
  finally {
   DataSourceUtils.closeConnectionIfNecessary(this.dataSource, con);
  }
 }
 
Client Performing Queries:p340
public 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(ResultSet rs) throws SQLException
  {
   int seatld = rs .getlnt (1) ;
   list.add(new Integer (seatld));
  }
 };
 t.query(psc,rch);
 return l; 
}

7.5.2 com.interface21.jdbc.object p342
Using 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 a
PreparedStatementCreatorFactory to create PreparedStatementCreator objects for the SQL and parameters. creates a
JdbcTemplate 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 class
uses the JdbcTemplate instance inherited from SqlOperation 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 newPreparedStatementCreator from sqloperation
  return rr.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 ManualExtractionSqlQuery class
 protected final Object extract(ResultSet rs, int rownum, Object[] parameters) throws SQLException {
  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(new SqlParameter(Types.INTEGER));
     this.compile();
   }
 
   protected Object extract(ResultSet rs, int rownum) throws SQLException {
     Show 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 TestDataSource());//class TestDataSource implements SmartDataSource
      List n = test1.execute(1);
      Show show = (Show)n.get(0);    
   }
  
8.session bean
8.1 if an application will never run on more than one server.  an HttpSession
object 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 using
stateless session beans.

8.3 Session facade pattern
In 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 call
Consider a use case implementation that calls on three entity beans. If the client were to implement this use
case, it would potentially require three JNDI lookups for remote objects and would need to make a minimum of
three remote calls to the entities required. The client would also need to perform transaction management, to
ensure that all three calls occurred in the same transaction (normally the intended behavior). Using a session
facade, on the other hand, a client would need only one remote JNDI lookup and one remote call. This will
lead to a large performance gain.

@2 discoupling client to EJB tier
Finally, if remote clients are able to invoke low-level components such as entity beans directly, they are tightly
coupled 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 performance
requirements dictate.

8.4
The safest EJB transaction attributes are Required (for session beans) and Mandatory (for entity
beans). A transaction attribute of NotSupported can be used to boost the performance of read-only
methods, 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 technologies
such as EJB. Technologies are features of implementations.
 
9.MVC
9.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 user
actions into application events, and the results of processing user input into results
displayable by the web interface. 

9.2 MVC p449
The MVC approach divides components into three kinds of object: model data objects; view objects that
present 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 p450
Multiplexed Resource Mapping Strategy.

9.4 Basic MVC Control Flow in Framework p465
9.4.1 Controller Servlet
It is a controller of controllers: its role is to
choose an application-specific request controller to handle each request and to delegate request
processing to it.

9.5 Don't Create Session State Unless Necessary
switch off default JSP session creation. This avoids
needless creation of session state, and avoids the risk of JSP pages accessing and
manipulating session state

<%@ page session="false" %>

9.6 Session Manager
In some applications, session state can be held in cookies. However, when we need
session state it's usually safer - and much simpler - to rely on the web container to
manage HttpSession objects, ensuring that we do all we can to ensure efficient
replication of session state in a clustered environment.

9.7 JSTL
custom tags just offer a simple, convenient approach to handle form submission 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 :
  /*
  <bean name="a.urlMap"
   class="com.interface21.web.servlet.UrlHandlerMapping"> 
   <property name="mappings">
    /welcome.html=ticketController
    ...
   </property>
  </bean>
  */
  ...
  HandlerAdapter ha = getHandlerAdapter(mappedHandler);

  ....
  ModelAndView mv = ha.handle(request, response, mappedHandler);
  //ticketController extends MultiActionController,
  //the method handleRequest use reflect to call method base below:
  /*
  <bean name="ticketControllerMethodNameResolver"
   class="com.interface21.web.servlet.mvc.multiaction.PropertiesMethodNameResolver"> 
    <property name="mappings">
     /welcome.html=displayGenresPage
     .....
    </property>
  </bean>  
  
  request contains welcome.html call displayGenresPage in ticketController
  it call bussiness object and return new ModelAndView Object
  
  public ModelAndView displayGenresPage(HttpServletRequest request, HttpServletResponse response) {
   List genres = calendar.getCurrentGenres();
   
   cacheForSeconds(response, 300, true);
   return new ModelAndView("welcomeView", "genres", genres);
  }  
  */
  .....
  render(mv, request, response);
  /*
   private void render(ModelAndView mv, HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    ...
    String viewName = mv.getViewname();
    ...
    View v = viewResolver.resolveViewname(viewName, request.getLocale()); @1 
    ...
    v.render(mv.getModel(), request, response);
  } 
  
  @1.it find war/web-inf/class/view.properties,define like below:
  welcomeView.class=com.interface21.web.servlet.view.InternalResourceView
  welcomeView.url=/jsp/template.jsp 
  
  v is instance of InternalResourceView.
  public void renderMergedOutputModel(Map model, HttpServletRequest request, HttpServletResponse response)
  {
   exposeModelsAsRequestAttributes(model,request);
   RequestDispatcher rd = request.getRequestDispatcher(getUrl());
   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 = model.get(modelname);    
    request.setAttribute(modelname, val);
   }  
  }

  in welcome.jsp
  <jsp:useBean id="genres" type="java.util.List" scope="request"/>
  ...
  <% for (int i = 0; i < genres.size(); i++) { %>
  ...
  */
}  

9.9
If JSP pages are to be used as views, custom tags are view helpers. They're neither
models nor controllers; they will principally be used to help display the models
available to the JSP view.

9.10 View Composition p570
<%@ include file= "header.jsp" %>
<jsp:include page="<%=contentWell%>" />
<%@ include file="footer.jsp" %>


10.总结
如何基于framework的架构建立网站
10.1 Middle Tier
定义一个DAO接口对象(com.wrox.expertj2ee.ticket.referencedata.jdbc.JdbcCalendar),实现对数据库的各种操作.
对数据的访问可以通过实现一个继承ManualExtractionSqlQuery的类,执行这个类的excute方法获得数据对象.
such as
 SqlQuery allGenreQuery = new GenreQuery("select id as 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设置<bean name="ticketController" >的bean的属性
 ServletControl(in com.interface21.web.servlet)是总控制器,所有请求的入口,把请求根据ticket-servlet.xml(C:/Language/Java/expertJ2EE/war/WEB-INF)
 的a.urlMap分派到控制器的各个方法去处理(例子中是TicketControl)定义一个新的控制器.(com.wrox.expertj2ee.ticket.web.TicketControl),
 同时修改ticket-servlet.xml.<bean name="a.urlMap"..>的节点指向新的控制器.修改<bean name="ticketControllerMethodNameResolver">节点,把页面和控制器的方法关联起来
10.2.2 Model
 定义新的javabean的接口和对象(在 package com.wrox.expertj2ee.ticket.referencedata中)
10.2.3 View
 view.properties(C:/Language/Java/expertJ2EE/war/WEB-INF/classes/)中定义视图名字对应的jsp和view的处理器(一般是InternalResourceView).
InternalResourceView的作用是跳转到指定的jsp页并且把model的对象放到request中去 
<jsp:useBean id="performance"
  type="com.wrox.expertj2ee.ticket.referencedata.Performance"
   scope="request"
/>
注意scope = "request"

10.2 deploy步骤(weblogic)
10.2.1 建立jdbc连接.
建立连接池.
    String url = "jdbc:oracle:thin:@127.0.0.1:1521:gaagaa";
    String driverName = "oracle.jdbc.driver.OracleDriver";
    String user = "ticket";
    String password = "ticket";
建立TxDataSource
    jndi的名字(config.xml)要与war中的weblogic.xml定义的jndi名字相同
<weblogic-web-app>
 <reference-descriptor>
  <resource-description>
          <res-ref-name>jdbc/ticket-ds</res-ref-name>
          <jndi-name>jdbc/ticket-ds</jndi-name>
  </resource-description> 
</weblogic-web-app> 

weblogic.xml的res-ref-name要和web.xml中的res-ref-name相同
   <resource-ref>
   <res-ref-name>jdbc/ticket-ds</res-ref-name>
   <res-type>javax.sql.DataSource</res-type>
   <res-auth>Container</res-auth>
   <res-sharing-scope>Shareable</res-sharing-scope>
 </resource-ref>        
 
10.2.2 建立jms

 

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值