2007年11月11日
CJDBC官网http://c-jdbc.ow2.org/
cjdbc与hibernate的整合
Configuring C-JDBC with Hibernate
C-JDBC just has to be defined as any JDBC driver in Hibernate, leaving the syntax set to the proper database. Here is a configuration example to use Hibernate with a C-JDBC cluster made of Sybase backends:
## C-JDBC
hibernate.dialect net.sf.hibernate.dialect.SybaseDialect
hibernate.connection.driver_class org.objectweb.cjdbc.driver.Driver
hibernate.connection.username user
hibernate.connection.password pass
hibernate.connection.url jdbc:cjdbc://localhost:25322/test
转自:http://lzj0470.javaeye.com/blog/445348
一、前言 |
cjdbc ( http://c-jdbc.objectweb.org/ ) 是一个open source的数据库集群中间件,任何基于jdbc的应用都可以通过它透明地访问数据库集群,它可以进行各个节点之间的数据复制,并且可以实现各个节点的查询负载均衡。通过这样的软件,偶们可以方便的实现RAIDb - Redundant Array of Inexpensive Database 廉价数据库冗余阵列。
大型应用随着用户量访问越来越大,增加数据库存储和做好数据库冗余可以增加系统的可靠性和性能。
下面利用cjdbc,把两台对等的 Mysql 做 RAIDb,本文假定你已经搭建好两台对等的 Mysql环境并建好一个需要做集群冗余的数据库 clusterdb。 |
|
二、配置环境 |
Mysql: 5.0.19, 并使用 InnoDB 作为 Mysql 引擎
C-jdbc: 2.0.2
Jdk: 1.5 |
|
三、选择合适的 C-JDBC RAIDb 机制 |
cjdbc有几种RAIDb的机制可以选择,如RAIDb-0,RAIDb-1等等,可以根据不同的情况选择不同的RAIDb的机制。各种 RAIDb的机制详情请查看 cjdbc 的文档和 Demo。
RAIDb-1有如下功能:
完全镜像处理机制,每个节点上都有完整的数据库结构,这种方式提供了最好的容错处理,并且通过设置合理的Loading Balance策略,可以带来查询性能相当好的提高。但是由于对于任何的写操作(create/update/delete),需要在各个节点上进行传播复制,写操作就会比原来慢一些了,如下图:
这里选择 RAIDb-1 做为 cjdbc RAIDb 机制。
|
|
四、给两台对等的 Mysql 建表,假设两台 Mysql 的IP分别是 192.168.0.2和192.168.0.3 |
bash> mysql -h192.168.0.2 -uroot
bash> use clusterdb
bash> create table user (id int(3) not null auto_increment primary key, name char(50) not null) engine innodb;
bash> exit;
bash> mysql -h192.168.0.3 -uroot
bash> use clusterdb
bash> create table user (id int(3) not null auto_increment primary key, name char(50) not null) engine innodb;
bash> exit; |
|
五、在 Linux 下安装 C-JDBC Controller |
bash> mkdir -p /usr/local/c-jdbc
bash> cd /usr/local/c-jdbc
bash> tar xvfz c-jdbc-2.0.2-bin.tar.gz
bash> export CJDBC_HOME=/usr/local/c-jdbc
|
|
六、把 Mysql JDBC Driver 放到 C-JDBC Controller 中来 |
这里我们使用 mysql-connector-java-3.1.12-bin.jar 驱动程序,把它放到
/usr/local/c-jdbc/drivers 中
|
|
七、配置 C-JDBC Controller |
1、在 /usr/local/c-jdbc/config/virtualdatabase 目录中创建 虚拟数据库配置文件,并把它命名为 mysql-raidb1-distribution.xml,内容如下:
<?xml version="1.0" encoding="UTF8"?>
<!DOCTYPE C-JDBC PUBLIC "-//ObjectWeb//DTD C-JDBC 2.0.2//EN" "http://c-jdbc.objectweb.org/dtds/c-jdbc-2.0.2.dtd">
<C-JDBC>
<VirtualDatabase name="myDB">
<Distribution>
</Distribution>
<AuthenticationManager>
<Admin>
<User username="admin" password="c-jdbc"/>
</Admin>
<VirtualUsers>
<VirtualLogin vLogin="boss" vPassword="boss"/>
</VirtualUsers>
</AuthenticationManager>
<DatabaseBackend name="mysqlNode211" driver="org.gjt.mm.mysql.Driver" url="jdbc:mysql://192.168.0.2/clusterdb" connectionTestStatement="select 1">
<ConnectionManager vLogin="boss" rLogin="boss_user" rPassword="123456">
<VariablePoolConnectionManager initPoolSize="10" minPoolSize="10" maxPoolSize="50" idleTimeout="30" waitTimeout="10"/>
</ConnectionManager>
</DatabaseBackend>
<DatabaseBackend name="mysqlNode213" driver="org.gjt.mm.mysql.Driver" url="jdbc:mysql://192.168.0.3/clusterdb" connectionTestStatement="select 1">
<ConnectionManager vLogin="boss" rLogin="boss_user" rPassword="123456">
<VariablePoolConnectionManager initPoolSize="10" minPoolSize="10" maxPoolSize="50" idleTimeout="30" waitTimeout="10"/>
</ConnectionManager>
</DatabaseBackend>
<RequestManager>
<RequestScheduler>
<RAIDb-1Scheduler level="passThrough"/>
</RequestScheduler>
<LoadBalancer>
<RAIDb-1>
<WaitForCompletion policy="first"/>
<RAIDb-1-LeastPendingRequestsFirst/>
</RAIDb-1>
</LoadBalancer>
</RequestManager>
</VirtualDatabase>
</C-JDBC>
|
2、在 /usr/local/c-jdbc/config/controller 目录中创建 C-JDBC controller 配置文件,并把它命名为 uud-controller-distributed.xml,内容如下:
<?xml version="1.0" encoding="UTF8" ?>
<!DOCTYPE C-JDBC-CONTROLLER PUBLIC "-//ObjectWeb//DTD C-JDBC-CONTROLLER 2.0.2//EN" "http://c-jdbc.objectweb.org/dtds/c-jdbc-controller-2.0.2.dtd">
<C-JDBC-CONTROLLER>
<Controller port="25323">
<JmxSettings>
<RmiJmxAdaptor port="1091"/>
</JmxSettings>
<VirtualDatabase configFile="mysql-raidb1-distribution.xml" virtualDatabaseName="myDB" autoEnableBackends="true"/>
</Controller>
</C-JDBC-CONTROLLER>
|
3、在 /usr/local/c-jdbc/config/demo 目录中创建启动 C-JDBC controller sh,并把它命名为 uud-distributed-raidb1-controller.sh,内容如下:
#!/bin/sh
export CJDBC_HOME=/usr/local/c-jdbc
export JAVA_HOME=/opt/jdk1.5
cd $CJDBC_HOME/bin
echo "Waiting for mysql servers to finish start up"
echo "Starting Controller"
./controller.sh -f ../config/controller/uud-controller-distributed.xml &
|
|
|
八、启动 C-JDBC Controller |
bash> cd /usr/local/c-jdbc/demo
bash> chmod u+rwx uud-distributed-raidb1-controller.sh
bash> ./uud-distributed-raidb1-controller.sh &
如果启动正常,显示的信息如下:
Waiting for mysql servers to finish start up
Starting Controller
2006-04-20 10:32:21,126 INFO controller.core.Controller C-JDBC controller (2.0.2)
2006-04-20 10:32:21,189 INFO controller.core.Controller Loading configuration file: ../config/controller/uud-controller-distributed.xml
2006-04-20 10:32:21,278 INFO controller.core.Controller JMX is enabled
2006-04-20 10:32:21,308 INFO controller.core.Controller Starting JMX server on host: 127.0.0.1
2006-04-20 10:32:21,674 INFO backend.DatabaseBackend.mysqlNode211 Adding connection manager for virtual user "boss"
2006-04-20 10:32:21,749 INFO backend.DatabaseBackend.mysqlNode213 Adding connection manager for virtual user "boss"
2006-04-20 10:32:21,809 INFO controller.RequestManager.myDB Request manager will parse requests with the following granularity: NO_PARSING
2006-04-20 10:32:21,814 INFO controller.virtualdatabase.myDB Configuring jgroups using: file:/usr/local/c-jdbc/config/jgroups.xml
-------------------------------------------------------
GMS: address is 127.0.0.1:32773
-------------------------------------------------------
2006-04-20 10:32:26,476 INFO controller.virtualdatabase.myDB Group myDB connected to /127.0.0.1:32773[/127.0.0.1:32773]
2006-04-20 10:32:26,476 INFO controller.virtualdatabase.myDB First controller in group myDB
2006-04-20 10:32:26,477 WARN controller.virtualdatabase.myDB No recovery log has been configured, enabling backend without checkpoint.
[1]+ Done ./uud-distributed-raidb1-controller.sh
|
|
|
八、编写 C-JDBC 客户端程序 |
1、把 C-JDBC Drivers(/usr/local/c-jdbc/drivers/c-jdbc-driver.jar) 放置到 CLASSPATH 中
2、编写插入 10 条数据到 Mysql 中,程序如下:
/**
* @author 胡荣华
* @Company 世纪龙 21cn
*/
package com.cjdbc.test;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.DriverManager;
/**
*
*/
public class GenerateSampleData {
public void generate() {
Connection conn = null;
PreparedStatement pstmt = null;
try {
// 这是 c-jdbc drivers 的 Drivers class,注意不是 mysql 的 Drivers class
Class.forName("org.objectweb.cjdbc.driver.Driver").newInstance();
// 192.168.0.1 是 cjdbc controller 所在的 ip
// myDB 是在 文件 mysql-raidb1-distribution.xml 里定义的 <VirtualDatabase name="myDB">
// user=boss&password=boss 是在 文件 mysql-raidb1-distribution.xml 里定义的
// <VirtualUsers>
// <VirtualLogin vLogin="boss" vPassword="boss"/>
// </VirtualUsers>
String url = "jdbc:cjdbc://192.168.0.1:25323/myDB?user=boss&password=boss";
conn = DriverManager.getConnection(url);
try{
conn.setAutoCommit(false);
pstmt = conn.prepareStatement("insert into user values ('', ?)");
int numOfTestRecords = 10;
System.out.println("Update Record Start.");
for (int i=0;i<numOfTestRecords;i++) {
String newkey = i + "-" + i;
pstmt.setString(1, "hua_" + newkey);
pstmt.executeUpdate();
}
conn.commit();
System.out.println("Update Record Success.");
}
catch(Exception ex){
conn.rollback();
ex.printStackTrace();
}
finally{
try {
if( pstmt != null )
pstmt.close();
if( conn != null)
conn.close();
}
catch(Exception e) {
e.printStackTrace();
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
GenerateSampleData g = new GenerateSampleData();
g.generate();
}
}
|
3、程序执行完毕后,分别到 Mysql Node 192.168.0.2 和 192.168.0.3 查询,看看是否已同步了数据,如果两个 Mysql Node 都有相同的数据,说明 C-JDBC 环境搭建成功。
|
|
posted @
2010-03-25 20:23 Dong 阅读(393) |
评论 (0) |
编辑 收藏
最近做了一个日志管理系统
个人觉得采用了一套非常非常创新或者变态的开发方式,就像题目说的那样,使用web的方法开发桌面应用程序,当然所有的技术都是基于java的。
总结一下在整个项目中使用到的技术
1、底层服务器的开发socket通信、http报文解析、反射机制(这些技术其实就是开发了一款小型的服务器,让我们的web代码能够在本地运行起来,之所以选择自己开发服务器的原因是,tomcat对于我们这个小桌面程序来说还是太大了点,如果作为桌面启动,用户不可能等待程序启动这么长的时间,我给这个服务器起了个名字叫做jnet)
2、SWT,包括的浏览器控件和窗口等。
3、使用installanywhere来打包程序,方便发布
4、前台展现数据使用了ext2.2
5、扩展自己开发的服务器jnet,开发出自己的“action”,应该来说还是符合MVC的
数据库使用的是access,采用jdbc的方式访问,你知道,如果在桌面软件上使用hibernate...
好了,不说废话
先贴出成品的效果图
1、桌面图标
2、登录界面
3、登录效果图
4、主界面
是不是觉得还不错呢?JAVA也可以扬眉吐气开发出这样的桌面系统,可惜的是因为使用到了SWT,所以整个项目并不能跨平台,放到linux系统下去运行。
好了先理一理,发一张项目的原理图
看图说话,我们整个项目的构架,就是这个样子的,采用SWT封装了IE作为前台展现,后台使用自己开发的服务器作为后台来处理数据,中间数据通信方式当然就只能是http了
所以中心思想就是,我开发了个服务器,这个服务器能够让用户扩展自己的类,自己的方法,然后用户就可以根据自己的需要来书写自己的系统,最最最重要的就是,让我们这些写惯了J2EE的人能够使用已经形成的思维来编写桌面系统,我们可以不需要再去学swing和swt,可以使用html的方式来做前台的布局,因为老实说我每次写桌面程序的时候,总会把代码弄得一团糟,在web系统上容易规规矩矩的写出分层的代码,桌面系统...布局就让我头大(我的意思是当你跑出去接私活干的时候,不用再学一套东西,呵呵)。
好了,这个帖子只是一个简单的介绍,整个系统具体的实现方式,会在后续的帖子中一步步解析,大家有什么意见或者建议可以给我留言,谢谢!
posted @
2009-03-19 15:16 Dong 阅读(4349) |
评论 (23) |
编辑 收藏
开发的时候有时候会碰到这样的情况,我们在写程序的时候并不知道需要调用某个对象的哪个方法,只有程序运行后,我们才能够知道。或许我们需要根据客户端传过来的某个String参数的值来判断我们应该执行哪个方法。在这种情况下JAVA的反射执行就可以帮上忙了。下面是我做的一个简单的测试代码,提供给大家做个参考。
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
/** *//**
* @author Dong
* 测试JAVA reflect机制
*/
public class TestRef{
/** *//**
* @param args
*/
public static void main(String[] args){
TestBean test = new TestBean();
Method[] methods = test.getClass().getMethods();
test.setAbc("---");
for(int i=0;i<methods.length;i++){
if(methods[i].getName().equalsIgnoreCase("getabc")){
try {
System.out.println(methods[i].invoke(test));
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
}
}
}
posted @
2008-06-05 16:36 Dong 阅读(10158) |
评论 (7) |
编辑 收藏
(String[])ArrayList.toArray(new String[0]);
posted @
2008-06-02 11:25 Dong 阅读(790) |
评论 (0) |
编辑 收藏
XML里是无法直接正常输出&等特殊字符的,可用&转义表示!
posted @
2008-05-21 09:03 Dong 阅读(472) |
评论 (0) |
编辑 收藏
1、数字格式化
<fmt:formatNumber value="33.33333" pattern="#.0"></fmt:formatNumber>-->输出33.3
pattern中符号的约束规定
0 一个数位
# 一个数位,前导零和追尾零不显示
. 小数点分割位置
, 组分隔符的位置
- 负数前缀
% 用100乘,并显示百分号
其他任何符号 在输出字符串中包括指定符号
2、日期格式化
<fmt:formatDate value="${vo.lateCompleteDate}" type="both" pattern="yy-MM-dd"/>
posted @
2008-05-20 09:29 Dong 阅读(1753) |
评论 (0) |
编辑 收藏
HashMap<String,String> testMap = new HashMap<String,String>();
for (Map.Entry<String, String> entry : testMap .entrySet()) {
entry.getKey();
entry.getValue();
}
posted @
2008-05-19 17:09 Dong 阅读(311) |
评论 (0) |
编辑 收藏
ApplicationContext ctx = new ClassPathXmlApplicationContext("application-config.xml");
Map<String,String> bureauMap = ((DictionaryService)ctx.getBean("dictionaryService")).getBureauMap();
posted @
2008-05-19 16:45 Dong 阅读(258) |
评论 (0) |
编辑 收藏
今天在调试一个Servlet程序的时候,报了以下错误!
java.lang.IllegalStateException: Cannot forward after response has been committed
根据字面理解的话,意识是在response已经提交后程序不能再一次的跳转!
研究代码以后发现,是因为前面已经执行过一次request.request.getRequestDispatcher().forward()
但是后面的request.request.getRequestDispatcher().forward()依然被执行到了!
那么很有理由相信request.request.getRequestDispatcher().forward()跳转本身是不会返回什么,也不会终止程序体的执行!
程序体后面该执行的还是会执行!
posted @
2008-04-17 10:28 Dong 阅读(7733) |
评论 (1) |
编辑 收藏
<Resource name="jdbc/dong" auth="Container" type="javax.sql.DataSource"/>
<ResourceParams name="jdbc/dong">
<parameter>
<name>factory</name>
<value>org.apache.commons.dbcp.BasicDataSourceFactory</value>
</parameter>
<parameter>
<name>maxActive</name>
<value>100</value>
</parameter>
<parameter>
<name>maxIdle</name>
<value>30</value>
</parameter>
<parameter>
<name>maxWait</name>
<value>5000</value>
</parameter>
<parameter>
<name>username</name>
<value>root</value>
</parameter>
<parameter>
<name>password</name>
<value>colorful</value>
</parameter>
<parameter>
<name>driverClassName</name>
<value>org.gjt.mm.mysql.Driver</value>
</parameter>
<parameter>
<name>url</name>
<value>jdbc:mysql://localhost:3306/dong</value>
</parameter>
</ResourceParams>
使用如上配置的时候一直报这个
org.apache.tomcat.dbcp.dbcp.SQLNestedException: Cannot create JDBC driver of class '' for connect URL 'null'错误
在网络上寻觅后发现是因为Tomcat版本引起的,改成如下问题就消失了
<Resource
name="jdbc/dong"
type="javax.sql.DataSource"
password="colorful"
driverClassName="org.gjt.mm.mysql.Driver"
maxIdle="2"
maxWait="5000"
username="root"
url="jdbc:mysql://localhost:3306/dong"
maxActive="4"/>
posted @
2008-02-24 13:47 Dong 阅读(2680) |
评论 (1) |
编辑 收藏
1、 解决Action过多问题
通过DispatchAction的方式
建立一个继承自DispatchAction的Action
此类Action允许我们在表单中带有参数,根据参数执行Action中的不同方法,以此实现Action的多用
步骤
① 建立一个继承自DispatchAction的Action规定方法名称
② 在表单页面中添加一个隐藏域值,假设为codi value=”insert”
③ 在Struts-config.xml的相应Form中action项目中设置parameter参数值为codi
那么当表单提交的时候,Action中的insert()方法就会被执行,可以通过改隐藏域中的值的方式来改变Action要执行的方法
2、 解决ActionForm过多的问题
通过动态ActionForm的方式,即DynaActionForm
步骤
① 在Struts-config.xml
<form-beans>
<form-bean name=”abcForm” type=”org.apache.struts.action.DynaActionForm”>
<form-property name=”userid” type=”java.long.String”></form-property>
</form-bean>
</form-beans>
② 在Struts-config.xml
更改相应的action中的attribute和name为abcForm
这样就配置好了一个动态的ActionForm
3、 解决动态ActionForm的验证问题
通过动态验证ActonForm的方式,即DynaValidatorForm
步骤
① 在Struts-config.xml
同2的第一步,但是type需要改成org.apache.struts.action.DynaValidatorForm
② 配置一个validation.xml文件
<form-validation>
<formset>
<form name="abcForm">
<field property="userid" depends="required">
<arg key="err.userid" resource="true"/>
</field>
</form>
</formset>
</form-validation>
③ 在Struts资源文件中配置err.userid、以及errors.required
④ 在Struts-config.xml配置相应的action,添加validate=”true”添加验证支持
⑤ 添加struts Plugin插件
设置plugin class为org.apache.struts.validator.ValidatorPlugIn
添加propertys
Propertyà pathnames
Valueà /WEB-INF/validator-rules.xml,/WEB-INF/validation.xml
这样一个验证框架就配置好了!
posted @
2008-02-12 13:47 Dong 阅读(3469) |
评论 (6) |
编辑 收藏
读Excel:
Workbook workbook = null;
try
{
workbook = Workbook.getWorkbook(new File(path));
}
catch(Exception e)
{
System.out.println(e);
}
Sheet sheet = workbook.getSheet(0);
Cell cell=sheet.getCell(i,j);//读第i列,第j行表格的值
System.out.println(cell.getContents());
对于循环读出可以使用
sheet.getRows();方法得到行数
sheet.getColumns();方法得到列数
写Excel:
Workbook wb = Workbook.getWorkbook(new File(path));
WritableCellFormat wcf = new WritableCellFormat();
book = Workbook.createWorkbook(new File(path, wb);
sheet = book.getSheet(0);
jxl.write.Label name = new jxl.write.Label(i,j,"abc",wcf);//在第i列,第j行写入"abc"值,风格为wcf,如果写入的是数字则使用jxl.write.Number
sheet.addCell(name);
try
{
book.write();
book.close();
}
catch(WriteException e){}
catch(IOException e){}
单元格风格:
设置边框—
WritableCellFormat wcf = new WritableCellFormat();
wcf.setVerticalAlignment(VerticalAlignment.CENTRE);
wcf.setBorder(Border.RIGHT,BorderLineStyle.THIN);
wcf.setBorder(Border.LEFT,BorderLineStyle.THIN);
wcf.setBorder(Border.BOTTOM,BorderLineStyle.THIN);
合并单元格-
sheet.mergeCells(0,1,0,2)
合并(0,1)、(0,2)两个单元格
设置字体-
WritableFont wf = new WritableFont(WritableFont.ARIAL,12, WritableFont.BOLD, false);
WritableCellFormat wcf = new WritableCellFormat(wf);
以及其它各种单元格样式,如设置背景颜色
都可以通过设置WritableCellFormat来设置
还有一点需要说明一下,JXL组件对于公式的支持似乎比Apache的poi好
posted @
2008-02-01 16:16 Dong 阅读(4975) |
评论 (2) |
编辑 收藏
原来弄过QuaQua的东西,但是一直不能把JFrame和JDialog变成Ox mac的样式
原因是,如果系统并不是苹果的系统就需要显示的加载JFrame和JDialog的样式
System.setProperty("Quaqua.tabLayoutPolicy","wrap");
if(!System.getProperty("os.name").toLowerCase().startsWith("mac"))
{
try
{
Methods.invokeStatic(JFrame.class, "setDefaultLookAndFeelDecorated", Boolean.TYPE, Boolean.TRUE);
Methods.invokeStatic(JDialog.class, "setDefaultLookAndFeelDecorated", Boolean.TYPE, Boolean.TRUE);
}
catch(NoSuchMethodException e)
{
e.printStackTrace();
}
}
try
{
UIManager.setLookAndFeel("ch.randelshofer.quaqua.QuaquaLookAndFeel");
}
catch(Exception e){}
posted @
2008-01-26 13:01 Dong 阅读(2958) |
评论 (6) |
编辑 收藏
Junit主要是用来对我们的程序代码进行白盒测试的一个组件。
首先我们需要得到Junit.jar的包,可以到www.junit.org下载得到。
下载以后将我们的Junit.jar包添加到工程里面,那么OK,就可以开始对我们的程序进行测试了。
对一个文件进行测试的时候需要自己制作一个类并继承TestCase,如:
package cn.colorful.junit;
import junit.framework.Assert;
import junit.framework.TestCase;
import cn.colorful.sample.*;
public class TestSample extends TestCase {
private Sample sam = null;
protected void setUp() throws Exception {
sam = new Sample();
}
protected void tearDown() throws Exception {
sam = null;
}
public void testSample() {
Assert.assertNotNull(sam);
Assert.assertEquals("ab", sam.getName("a", "b"));
Assert.assertEquals("dong", sam.getName("do", "ng"));
}}
其中程序的运行过程是TestCase的构造方法、setUp方法(对程序中使用的一些资源进行分配)、运行测试、tearDown()(去处一些使用到的资源)
这样程序会自动判断Sample类中的getName方法返回的值是不是符合我们的要求,使用Junit测试的运行方式,程序会调用Assert类中的静态方法对测试程序的返回值和期望值等情况进行判断、还有一些判断对象是否为空的方法,当出现绿色的时候代表程序是正常运行的
当书写了很多测试类后,可以条使用TestSuite类对测试类进行打包测试,如:
package cn.colorful.junit;
import junit.framework.Test;
import junit.framework.TestSuite;
public class TestPackage{
public static Test suite()
{
TestSuite tes = new TestSuite("Test for cn.colorful.sample");
tes.addTestSuite(TestSample.class);
tes.addTestSuite(TestSampleTwo.class);
return tes ;
}
}
程序需要实现suite()方法,并且返回出一个TestSuite对象。
posted @
2007-12-25 16:12 Dong 阅读(1253) |
评论 (2) |
编辑 收藏
1、实现自定义Taglib的类需要实现javax.servlet.jsp.tagext.IterationTag或者
javax.servlet.jsp.tagext.TagSupport、javax.servlet.jsp.tagext.BodyTag接口,目前J2EE提供了两
个分别实现了这两个接口的类,我们只需要直接继承就可以,它们分别为BodyTagSupport、TagSupport
继承两个类中的一个就可以完成一个属于自己的Taglib类
package cn.dong;
import java.io.IOException;
import cn.dong.Person ;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.tagext.Tag;
import javax.servlet.jsp.tagext.TagSupport;
public class TagServer extends TagSupport {
String name ;
public void setName(String name) {
this.name = name;
}
public int doStartTag() throws JspException {
Person per = new Person() ;
try {
pageContext.getOut().println("Userid:"+name) ;
} catch (IOException e) {
e.printStackTrace();
}
return SKIP_BODY ;
}
}
2、写tld文件
tld文件本身是xml标准文档的一种,可以通过tld文件配置出Taglib的各种标记所对应的类实现
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE taglib PUBLIC "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.1//EN"
"http://java.sun.com/j2ee/dtds/web-jsptaglibrary_1_1.dtd">
<taglib>
<tlibversion>1.0</tlibversion>//标签描述
<jspversion>1.1</jspversion>
<shortname>mytag</shortname>
<uri></uri>
<tag>
<name>hello</name>//标签方法名
<tagclass>cn.dong.TagServer</tagclass>//指向的类
<bodycontent>empty</bodycontent>
<info>Tag with Parameter</info>
<attribute>//定义传递的属性值
<name>name</name>//属性名
<required>true</required>//属性值是否必须传输
<rtexprvalue>false</rtexprvalue>
</attribute>
</tag>
</taglib>
这样一个自定义标记就写好了,但是要使用它我们还需要在项目中配置
3、项目部署文件web.xml
<taglib>
<taglib-uri>hello</taglib-uri>
<taglib-location>/WEB-INF/Web.tld</taglib-location>
</taglib>
4、在JSP页面中调用Taglib
<%@ taglib uri="hello" prefix="show" %>
这样我们就完成了所有配置
在页面中使用类似<show:hello name="dong"/>就可以看到我们配置的Taglib起的作用了
posted @
2007-12-19 11:07 Dong 阅读(1079) |
评论 (3) |
编辑 收藏
我对DAO的理解就是对数据库的访问封装在一个接口里,当用户需要访问数据库的时候只需要简单的对调用接口,而不需要和数据库有直接的接触。
下面介绍一个简单的DAO对数据库访问的建立:
首先我们需要建立
1、一个DAO接口:UserDAO.java在里面定义数据库操作的所有方法
2、一个实现了DAO接口的类、UserDAOImpl.java,完成了对DAO的实现并且将取得的数据存放到VO类中。
3、一个数据库访问的基础类、DataBaseConnection.java里面封装了对数据库的连接Connection,外部访问这个类的方法可以返回一个Connection接口的实现
4、一个VO类,UserVO.java,里面包含了所有需要返回的出来的数据、利用set方法和get方法对类对象进行基本的设置
5、一个Factory类,封装了具体实现了UserDAO接口的UserDAOImpl类对象,调用Factory类的时候直接返回一个UserDAO的对象
这样的话一个DAO设计就完成了
这个时候当我们需要对数据库进行访问的时候只需要声明一个UserDAO接口然后实例化一个工厂类实现UserDAO接口,这样我们就可以遍历VO类得到我们要的数据。
posted @
2007-12-16 16:30 Dong 阅读(1136) |
评论 (1) |
编辑 收藏
Filter Servlet中传递的request和response对象分别是ServletRequest和ServletResponse接口的对象,而不是一般Servlet中的HttpServletRequest和HttpServletResponse接口的对象,ServletRequest是HttpServletRequest的父接口,很多方法是没有的,比如说request.getSession() ;所以如果想在Filter中读取session对象必须对request做一定的向下转型。
而实现HttpSessionListener 的Listener Servlet中的传递的对象是HttpSessionEvent的对象,想在其中实现对Application对象的访问的话:arg0.getSession().getServletContext().setAttribute();
另:今天把MySQL装到电脑上,利用Servlet连接了一下,老是报ClassNotFound的错误,原因是MySQL的JDBC驱动只有一个mysql-connector-java-5.0.8-bin.jar,另外一个不能够拷到lib目录下。
posted @
2007-12-13 01:02 Dong 阅读(572) |
评论 (0) |
编辑 收藏
Struts 使用 Model 2 架构。Struts 的ActionServlet 控制导航流。其他Struts 类,比如
Action, 用来访问业务逻辑类。当 ActionServlet 从容器接收到一个请求,它使用URI (或者
路径“path”) 来决定那个Action 将用来处理请求。一个 Action可以校验输入,并且访问业务
层以从数据库或其他数据服务中检索信息。
为校验输入或者使用输入来更新数据库, Action 需要知道什么指被提交上来。并不是
强制每个Action 从请求中抓取这些值,而是由 ActionServlet 将输入绑定到JavaBean中。
输入 bean是Struts ActionForm c类的子类。ActionServlet 通过查找请求的路径可以决定使用
哪个ActionForm,Action 也是通过同样的方法选取的。ActionForm 扩展
org.apache.struts.action.ActionForm类。每个都必须以HTTP 响应进行应答。 通
常, Struts
Action 并不自行加工响应信息,而是将请求转发到其他资源,比如JSP 页面。Struts 提
供一个ActionForward 类,用来将一个页面的路径存储为逻辑名称。当完成业务逻辑后,
Action 选择并向Servlet返回一个ActionForward。Servlet 然后使用存储在ActionForward 对
象中的路径来调用页面完成响应。
Struts 将这些细节都绑定在一个ActionMapping 对象中。每个ActionMapping 相对于一
个特定的路径。当某个路径被请求时,Servlet 就查询ActionMapping 对象。ActionMapping
对象告诉servlet,哪个Actions, ActionForms, 和 ActionForwards 将被使用。
所有这些细节,关于Action, ActionForm, ActionForward, ActionMapping,以及其
他一些东西,都在struts-config.xml 文件中定义。 ActionServlet 在启动时读取这个配置文件,
并创建一个配置对象数据库。在运行时,Struts 应用根据文件创建的配置对象,而不是文件
本身
posted @
2007-12-08 10:52 Dong 阅读(219) |
评论 (0) |
编辑 收藏
<head>
<title>无标题文档</title>
<style type="text/css">
<!--
.hidecontent {display:none;}
-->
</style>
<script language="javascript">
function switchTag(content)
{
// alert(tag);
// alert(content);
for(i=1; i <6; i++)
{
if ("content"+i==content)
{
document.getElementById(content).className="";
}else{
document.getElementById("content"+i).className="hidecontent";
}
document.getElementById("content").className=content;
}
}
</script>
</head>
<body>
<div id="container">
<ul>
<li><a href="#" onmouseover="switchTag('content1');this.blur();"><span>标题一</span></a></li>
<li><a href="#" onmouseover="switchTag('content2');this.blur();"><span>标题二</span></a></li>
<li><a href="#" onmouseover="switchTag('content3');this.blur();"><span>标题三</span></a></li>
<li><a href="#" onmouseover="switchTag('content4');this.blur();"><span>标题四</span></a></li>
<li><a href="#" onmouseover="switchTag('content5');this.blur();"><span>标题五</span></a></li>
</ul>
</div>
<div id="content" class="content1">
<div id="content1" >标题一中的东西</div>
<div id="content2" class="hidecontent">标题二中的东西</div>
<div id="content3" class="hidecontent">标题三中的东西</div>
<div id="content4" class="hidecontent">标题四中的东西</div>
<div id="content5" class="hidecontent">标题五中的东西</div>
</div>
</body>
</html>
只是一个简单的实现方法,具体的样式美观方面的东西可以自己修改。
posted @
2007-11-11 11:39 Dong 阅读(1511) |
评论 (4) |
编辑 收藏