《jsp web编程指南》---电子工业出版社
最后第19章有个例子看对你有否帮助。

解决方案 »

  1.   

    在jsp中一般不这样用,可以在Action中DataSource dataSource = getDataSource(request);
    中取得,再传到jsp中去。
      

  2.   

    用..context.lookup得到JNDI名字返回一个datasource对像
    再用datasource对像getConnection就可以得到连接
      

  3.   

    context是要将数据源放到自己的<context>中才能找到的,但我不想这么做
    Action中DataSource dataSource=getDataSource(request);但是编译的时候找不到
    getDataSource()这个方法呀!
    还有《jsp web编程指南》这本书,网上没有代码呀,可不可以发一份给我,谢谢!
    [email protected]
      

  4.   

    在一个其于Struts的应用系统的设计过程中,最好能在web/表示层(presentation layer)和你的商务逻辑类(包含所有数据访问操作的层)的中间,定义一个Action类,作为小型的适配器(thin adapter)。
    所以,你可以先定义一些商务API(business API),这些API就是简单的Java类。你可以传递一些参数给这些对象,并从这些对象返回一个Java Bean或者Java Bean的集合。这个Action类负责调用这些对象,并把它们返回的值传递给web/表示层。
    通常,你可以为每一个你需要调用的商务方法/商务类API创建一个Action类。理想情况下,所有的数据库访问代码都被封装进了这些商务API类里,所以Struts并不知道你正在使用的持久层(persistent layer)(甚至都不知道你使用了持久层)。它只需要传递一个主键(Key)或者一个查询参数,然后处理返回的结果bean或者bean集合。这样,你就可以在其他的应用环境里复用这些商务API类,你还可以对这些独立于Struts或HTTP环境的商务API进行单体测试。
    开始的时候,最简单的方法就是设计一个1:1的方案,为你的每一个商务API入口(entry-point)定义一个Action类。当你的经验丰富了以后,你也可以使用DispatchAction组合这些Action类。你甚至可以定义一个简单的"框架"Action,用来调用所有的这些商务类。你可以在contrib目录里找到Scaffold设计的ProcessAction,这是一个"框架"Action的完整实现。使用这种方案可以使用更少的Action类,但你必须对Struts和MVC框架的底层实现有较深的理解。不要害怕在开始的时候定义过多的Action,Struts的配置方案可以给予你充分的自由在以后重构你的设计,因为你可以灵活的改变你的Action类,而不会对应用程序造成影响。
    在理想情况下,商务逻辑层(business logic layer)应该封装所有的数据访问细节,包括数据库连接的获得。但是,一些应用程序的设计要求调用者可以从一个DataSource对象来获得数据库连接。遇到这种情况时,Struts DataSource管理器可以使你在需要的时候配置这些DataSource资源。
    Struts DataSource管理器在Struts配置文件(Struts-config.xml)里定义。这个管理器可以用来分发和配置任何实现了javax.sql.DataSource接口的数据库连接池(connection pool)。如果你的DBMS或者容器内置了符合这些要求的连接池,你可以优先选用它。[Jakarta的公共连接池实现 - BasicDataSource]
    如果你的手头没有连接池的本地(native)实现,你可以使用Jakarta提供的公共连接池实现[org.apache.commons.dbcp.BasicDataSource],它可以和DataSource管理器"合作"的很好。另外,Struts还在它的util包里包含了一个GenericDataSource类,这也是一个连接池实现。但是这只是一个非常简单的实现方案,不推荐使用,因为它可能在Struts的以后版本中被BasicDataSource或其它的数据源实现替换掉。
    下面是一段Struts-config.xml配置文件中的数据源配置(使用GenericDataSource数据源实现),你可以更改相应的设置以适合你自己的系统。 <!-- configuration for GenericDataSource wrapper -->
     <data-sources>
      <data-source>
        <set-property
       property="autoCommit"
       value="false"/>
        <set-property
       property="description"
       value="Example Data Source Configuration"/>
        <set-property
       property="driverClass"
       value="org.postgresql.Driver"/>
        <set-property
       property="maxCount"
       value="4"/>
        <set-property
       property="minCount"
       value="2"/>
        <set-property
       property="password"
       value="mypassword"/>
        <set-property
       property="url"
       value="jdbc:postgresql://localhost/mydatabase"/>
        <set-property
       property="user"
       value="myusername"/>
      </data-source>
     </data-sources>
    使用BasicDataSource数据源实现的配置方案如下:
    <data-sources>
     <!-- configuration for commons BasicDataSource -->
     <data-source type="org.apache.commons.dbcp.BasicDataSource">
      <set-property
        property="driverClassName"
        value="org.postgresql.Driver" />
      <set-property
        property="url"
        value="jdbc:postgresql://localhost/mydatabase" />
      <set-property
        property="username"
        value="me" />
      <set-property
        property="password"
        value="test" />
      <set-property
        property="maxActive"
        value="10" />
      <set-property
        property="maxWait"
        value="5000" />
      <set-property
        property="defaultAutoCommit"
        value="false" />
      <set-property
        property="defaultReadOnly"
        value="false" />
      <set-property
        property="validationQuery"
        value="SELECT COUNT(*) FROM et" />
     </data-source>
    </data-sources>
    注意,你可以在你的应用系统中定义不止一个数据源,你可以根据需要定义多个数据源,并为它们分别起一个逻辑名(logical name)。这样做可以给你的应用系统提供更好的安全性和可测量性(scalability),你还可以定义一个专用于测试的数据源。
    配置好DataSource以后,你就可以在你的应用系统中使用这些数据源了。下面这段代码演示了怎样在Action类的execute方法中通过这些数据源来生成数据库连接。
    public ActionForward execute(
     ActionMapping mapping,
     ActionForm form,
     HttpServletRequest request,
     HttpServletResponse response)
     throws Exception
    {
     DataSource dataSource;
     Connection cnn;
     try
     {
      dataSource = getDataSource(request);
      cnn = dataSource.getConnection();
      // 数据连接已经建立了,你可以做你想做的事情了
     }
     catch (SQLException e)
     {
      getServlet().log("处理数据库连接", e);
     }
     finally
     {
      // 在finally块里包含这些代码
      // 用以保证连接最后会被关闭
      try
      {
       cnn.close();
      }
      catch (SQLException e)
      {
       getServlet().log("关闭数据库连接", e);
      }
     }
    }
    注意:如果你使用公共的BasicDataSource,你提供给pingQuery属性的查询语句(如果你设置了话)必须至少要能返回一行记录。
    例子:SELECT COUNT(*) FROM VALIDTABLE
    你可以把VALIDTABLE替换成你的数据库中包含的任何有效的表。
    [使用多个数据源]
    如果你需要在模块(Module)中使用多于一个的数据源,你可以在配置文件的<data-source>元素里包含一个key属性。
    <data-source>
     <data-source key="A" type="org.apache.commons.dbcp.BasicDataSource">
      …属性配置略, 同上…
     </data-source>
     <data-source key="B" type="org.apache.commons.dbcp.BasicDataSource">
      …属性配置略, 同上…
     </data-source>
    </data-source>
    你代码里,你可以通过这些key获得不同的数据源。代码如下:

    try
    {
     dataSourceA = getDataSource(request, "A");
     dataSourceB = getDataSource(request, "B");

    你可以根据需要为每一个模块设置多个数据源。但同一模块里每个数据源的key属性必须唯一,因为Struts模块系统是以每一个模块为单位管理命名空间的。
    大多数的数据库查询结果都会跟你的已经使用的ActionForms一一对应,你只需要把你的查询结果集合提交给相应的ActionForm就可以了。但有时候,结果集(ResultSet)里有些字段并不是ActionForm的属性,或者更糟。
      

  5.   

    幸运的是,Struts的自定义标签集并不关心你传递给他们的bean类型。你甚至可以直接输出结果集。但是由于结果集会一直保持着与数据库的连接,并且由于它们把所有的数据都直接传递给了JSP,使得页面变得零乱不堪。那么我们该怎么做呢?
    从Struts 1.1开始,你可以使用新增加的ResultSetDynaClass来把你的结果集转换成一个DynaBeans的ArrayList。Struts自定义标签集可以像一般的JavaBean一样使用DynaBean的属性。(关于DynaActionForm类更详细的信息,请参考Struts用户手册)。
    ResultSetDynaClass类已经包含在于BeanUtils.jar包中,所以你现在所要做的,只需要拿出这个工具,实现自己的传递方案吧…………
    转帖]Struts中html:options的使用 
    html:options是Struts中比较复杂的一个tage lib,用法灵活,但是Sturts提供的源码exercise taglib中没有提出常用jsp+ActionForm这样形式的最直接的总结,现从中总结如下,分两种情况:数组和Collection。需求,要达到:<select name="beanCollectionSelect" multiple="multiple" size="10">
    <option value="value 0">Label 0</option>
    <option value="value 1" selected="selected">Label 1</option>
    <option value="value 2">Label 2</option>
    <option value="value 3" selected="selected">Label 3</option>
    <option value="value 4">Label 4</option>
    <option value="value 5" selected="selected">Label 5</option>
    <option value="value 6">Label 6</option>
    <option value="value 7">Label 7</option>
    <option value="value 8">Label 8</option>
    <option value="value 9">Label 9</option></select>
    要实现上述效果,需要两步:
    第一:设置ActionForm,
    也分两小步:第一小步必须在ActionForm中,有一句
    private Collection beanCollection;
    public Collection getBeanCollection();Collection beanCollection要确保是一个实现,如ArrayList,如果不是则会报No collection found的错误,Struts的最大不方便就是一旦出问题,定位很难,不知道什么地方使用错误,或忘记设置什么了。因为前面需求中option的value值和label值不一样,那么在beanCollection中保存的就是一个value和label组成的对象,名为LabelvalueBean,在LabelvalueBean中有两个属性value和label,在程序某个地方要为beanCollection赋值,如:
    Vector entries = new Vector(10);   
    entries.add(new LabelvalueBean("Label 0", "value 0"));          
    entries.add(new LabelvalueBean("Label 1", "value 1"));          
    entries.add(new LabelvalueBean("Label 2", "value 2"));          
    entries.add(new LabelvalueBean("Label 3", "value 3"));          
    entries.add(new LabelvalueBean("Label 4", "value 4"));            
    entries.add(new LabelvalueBean("Label 5", "value 5"));           
     entries.add(new LabelvalueBean("Label 6", "value 6"));            
    entries.add(new LabelvalueBean("Label 7", "value 7"));            
    entries.add(new LabelvalueBean("Label 8", "value 8"));            
    entries.add(new LabelvalueBean("Label 9", "value 9"));
    然后执行setBeanCollection(entries);
    这样ActionForm中的beanCollection算有值了。
    第二小步,需要设置Selected,selected有两种,单选和多选:
    在ActionForm中必须有:private String singleSelect = "Single 5";   
    public String getSingleSelect() {      return (this.singleSelect);    }   
    public void setSingleSelect(String singleSelect) {      this.singleSelect = singleSelect;    }或多选,多选必须是数组:private String[] beanCollectionSelect = { "value 1", "value 3",                                              "value 5" };  
    public String[] getBeanCollectionSelect() {   return (this.beanCollectionSelect);    }    public void setBeanCollectionSelect(String beanCollectionSelect[]) {        this.beanCollectionSelect = beanCollectionSelect;    }第二:在Jsp中写入tang lib语句如下:<html:select property="beanCollectionSelect" size="10" multiple="true">        <html:optionsCollection name="testbean" property="beanCollection"/>    
     </html:select>其中testbean是ActionForm的名称。以上是html:options的Collection解决方案,如果option值很少,简单地可以实现为数组,两步:
    第一:在ActionForm中,private String values[] =     { "Magazine", "Journal", "News Paper","Other" };   
    private String labels[] =     { "L-Magazine", "L-Journal", "L-News Paper","L-Other"};    private String selected = "Magazine";    
    public String getSelected(){      return selected;    }    
    public void setSelected(String selected){      this.selected = selected;    }   
    public String[] getvalues(){      return values;    }    
    public void setvalues(String[] values){      this.values = values;    }   
    public String[] getLabels(){      return values;    }    
    public void setLabels(String[] labels){      this.labels = labels;    }
    第二步在jsp中:<html:select property="selected" >           
    <html:options name="testbean" property="values" labelProperty="label"/>      </html:select>Struts标签库的使用还是需要小心,不必完全使用Struts的标签库,个人感觉Struts这种替代Html语句的标签库有一种牵强附会,给使用者掌握带来难度,使用者除熟悉html外,还必须理解Struts的对应标签库用法,而且这种调试出错,问题也无法准确定位,总是抽象地告诉你,no bean 或no form ===========
    Collection beanCollection要确保是一个实现,
    =================
    这个beanCollection要如何实现?Struts-config.xml:
    增加一个ActionForm定义:
    <form-bean name="HtmlSelectForm" type="demo.HtmlSelectForm"/>
    增加一个Action定义:
    <action path="/HtmlSelect" type="demo.HtmlSelectAction" name="HtmlSelectForm" scope="request">
        <forward name="success" path="/jsType.jsp"/>
    </action>jsType.jsp:
    内容:
    <%@ page language="java" %>
    <%@ taglib uri="/WEB-INF/struts-bean.tld" prefix="bean" %>
    <%@ taglib uri="/WEB-INF/struts-html.tld" prefix="html" %>
    <%@ taglib uri="/WEB-INF/struts-logic.tld" prefix="logic" %><html:html>
    <head>
    <title>Html 演示</title>
    <html:base/>
    </head>
    <body bgcolor="white"><html:select name="HtmlSelectForm" property="selectedID">
            <html:options collection ="selects" property="value" labelProperty="label"/>
    </html:select></body>
    </html:html>
    HtmlSelectAction.java内容:
    package demo;import org.apache.struts.action.Action;
    import org.apache.struts.action.ActionMapping;
    import org.apache.struts.action.ActionForm;
    import org.apache.struts.action.ActionForward;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import org.apache.struts.util.LabelValueBean ;
    import java.util.ArrayList;public class HtmlSelectAction extends Action {
    public ActionForward execute(ActionMapping mapping,
    ActionForm form,
    HttpServletRequest request,
    HttpServletResponse response) throws Exception
    {
    ArrayList v = new ArrayList ();
    //这里用For循环代替从数据库读取数据
    for (int i = 0; i<10; i++)
    {
    LabelValueBean value = new LabelValueBean ("item " + String.valueOf(i), String.valueOf(i));
    v.add(value);
    }//将列表保存到request中
    request.setAttribute("selects", v); return mapping.findForward("success");
    }}HtmlSelectForm.java 内容:
    package demo;import org.apache.struts.action.ActionForm;
    import java.util.Vector;public class HtmlSelectForm extends ActionForm {
    public String selectedID = "5";
    public void setSelectedID(String selectedID) {
    this.selectedID = selectedID;
    } public String getSelectedID() {
    return (this.selectedID);
    }}
      

  6.   

    第一篇是别人翻译的jakarta struts关于数据访问的,至于第二篇并没有用到我说的<data-source>呀?
    我现在是编译的时候找不到getDataSource()这个方法??
      

  7.   

    <data-sources>
            <data-source>
                <set-property property="description" value="" />
                <set-property property="driverClass" value="oracle.jdbc.driver.OracleDriver" />
                <set-property property="url" value="jdbc:oracle:thin:@127.0.0.1:1521:XXXX" />
                <set-property property="password" value="XXX" />
                <set-property property="user" value="XXX" />
                <set-property property="maxCount" value="20" />
                <set-property property="minCount" value="10" />
                <set-property property="loginTimeout" value="3000" />
                <set-property property="autoCommit" value="false" />
                <set-property property="readOnly" value="false" />
            </data-source>
        </data-sources>
      

  8.   

    谢谢各位!原来是我没有做ActionForm!