Ant是Javaq_下非常棒的批处理命o(h)执行E序Q能非常方便地自动完成编译,试Q打包,部v{等一pddQ大大提高开发效率。如果你现在q没有开始用AntQ那p赶快开始学?fn)用,使自q开发水q上一个新台阶?/p>
Eclipse 中已l集成了(jin)AntQ我们可以直接在Eclipse中运行Ant?/p>
以前面徏立的Hello工程ZQ创Z下目录结构:(x)
新徏一个build.xmlQ放在工E根目录下。build.xml定义?jin)Ant要执行的批处理命令。虽然Ant也可以用其它文件名Q但是遵循标准能更开发更规范Q同时易于与别h交流?/p>
通常Qsrc存放Java源文Ӟclasses存放~译后的class文gQlib存放~译和运行用到的所有jar文gQweb存放JSP{web文gQdist存放打包后的jar文gQdoc存放API文?/p>
然后在根目录下创建build.xml文gQ输入以下内容:(x)
<xml version="1.0"?>
<project name="Hello world" default="doc">
<-- properies -->
<property name="src.dir" value="src" />
<property name="report.dir" value="report" />
<property name="classes.dir" value="classes" />
<property name="lib.dir" value="lib" />
<property name="dist.dir" value="dist" />
<property name="doc.dir" value="doc"/>
<-- 定义classpath -->
<path id="master-classpath">
<fileset file="${lib.dir}/*.jar" />
<pathelement path="${classes.dir}"/>
<path>
<-- 初始化Q?-->
<target name="init">
<target>
<-- ~译 -->
<target name="compile" depends="init" description="compile the source files">
<mkdir dir="${classes.dir}"/>
<javac srcdir="${src.dir}" destdir="${classes.dir}" target="1.4">
<classpath refid="master-classpath"/>
<javac>
<target>
<-- 试 -->
<target name="test" depends="compile" description="run junit test">
<mkdir dir="${report.dir}"/>
<junit printsummary="on"
haltonfailure="false"
failureproperty="tests.failed"
showoutput="true">
<classpath refid="master-classpath" />
<ormatter type="plain"/>
<batchtest todir="${report.dir}">
<fileset dir="${classes.dir}">
<include name="**/*Test.*"/>
<fileset>
<batchtest>
<junit>
<fail if="tests.failed">
***********************************************************
**** One or more tests failed! Check the output ... ****
***********************************************************
<fail/>
<target/>
<-- 打包成jar -->
<target name="pack" depends="test" description="make .jar file">
<mkdir dir="${dist.dir}" />
<jar destfile="${dist.dir}/hello.jar" basedir="${classes.dir}">
<xclude name="**/*Test.*" />
<xclude name="**/Test*.*" />
<jar/>
<targe/t>
<-- 输出api文 -->
<target name="doc" depends="pack" description="create api doc">
<mkdir dir="${doc.dir}" />
<javadoc destdir="${doc.dir}"
author="true"
version="true"
use="true"
windowtitle="Test API">
<packageset dir="${src.dir}" defaultexcludes="yes">
<include name="example/**" />
<packageset/>
<doctitle>[CDATA[<1>ello, test<h1>]>doctitle>
<dottom>[CDATA[<>ll Rights Reserved.<i>]>bottom>
<tag name="todo" scope="all" description="To do:" />
<javadoc/>
<target/>
<project/>
以上xml依次定义?jin)initQ初始化Q,compileQ编译)(j)QtestQ测试)(j)QdocQ生成文)(j)QpackQ打包)(j)dQ可以作为模ѝ?/p>
选中Hello工程Q然后选择“Project”,“Properties”,“Builders”,“New…”,选择“Ant Build”:(x)
填入NameQAnt_BuilderQBuildfileQbuild.xmlQBase DirectoryQ?{workspace_loc:/Hello}Q按“Browse Workspace”选择工程根目录)(j)Q由于用C(jin)junit.jar包,搜烦(ch)Eclipse目录Q找到junit.jarQ把它复制到Hello/lib目录下,q添加到Ant的Classpath中:(x)
然后在Builder面板中钩上Ant_BuildQ去掉Java BuilderQ?/p>
再次~译Q即可在控制台看到Ant的输出:(x)
Buildfile: F:\eclipse-projects\Hello\build.xml
init:
compile:
[mkdir] Created dir: F:\eclipse-projects\Hello\classes
[javac] Compiling 2 source files to F:\eclipse-projects\Hello\classes
test:
[mkdir] Created dir: F:\eclipse-projects\Hello\report
[junit] Running example.HelloTest
[junit] Tests run: 1, Failures: 0, Errors: 0, Time elapsed: 0.02 sec
pack:
[mkdir] Created dir: F:\eclipse-projects\Hello\dist
[jar] Building jar: F:\eclipse-projects\Hello\dist\hello.jar
doc:
[mkdir] Created dir: F:\eclipse-projects\Hello\doc
[javadoc] Generating Javadoc
[javadoc] Javadoc execution
[javadoc] Loading source files for package example...
[javadoc] Constructing Javadoc information...
[javadoc] Standard Doclet version 1.4.2_04
[javadoc] Building tree for all the packages and classes...
[javadoc] Building index for all the packages and classes...
[javadoc] Building index for all classes...
[javadoc] Generating F:\eclipse-projects\Hello\doc\stylesheet.css...
[javadoc] Note: Custom tags that could override future standard tags: @todo. To avoid potential overrides, use at least one period character (.) in custom tag names.
[javadoc] Note: Custom tags that were not seen: @todo
BUILD SUCCESSFUL
Total time: 11 seconds
Ant依次执行初始化,~译Q测试,打包Q生成API文一pddQ极大地提高?jin)开发效率。将来开发J2EE目Ӟq可加入部v{Q务。ƈ且,即q?jin)Eclipse环境Q只要正安装了(jin)AntQ配|好环境变量ANT_HOME=<nt解压目录>Path=?%ANT_HOME%\binQ在命o(h)行提C符下切换到Hello目录Q简单地键入ant卛_?/p>
cactus.sysproperties=cactus.contextURL
#cactus-sample-servlet-cactified是你的试应用所在\径,8080是端口号
cactus.contextURL = http://localhost:8080/cactus-sample-servlet-cactified
cactus.servletRedirectorName = ServletRedirector
cactus.jspRedirectorName = JspRedirector
cactus.filterRedirectorName = FilterRedirector
<path id="project.classpath">
<fileset dir="${lib.dir}">
<include name="*.jar"/>
</fileset>
<!-- cactus.properties文g需要放在lib.dir所对应的\径中 -->
<pathelement location="${lib.dir}"/>
<pathelement location="${tomcat.home}/common/lib/jsp-api.jar"/>
<pathelement location="${tomcat.home}/common/lib/servlet-api.jar"/>
</path>
<taskdef resource="cactus.tasks" classpathref="project.classpath"/>
<taskdef name="runservertests" classname="org.apache.cactus.integration.ant.RunServerTestsTask">
<classpath>
<path refid="project.classpath"/>
</classpath>
</taskdef>
<target name="war" depends="compile.java"
description="Generate the runtime war">
<war warfile="${target.dir}/${project.name}.war"
webxml="${src.webapp.dir}/WEB-INF/web.xml">
<fileset dir="${src.webapp.dir}">
<exclude name="cactus-report.xsl"/>
<exclude name="WEB-INF/cactus-web.xml"/>
<exclude name="WEB-INF/web.xml"/>
</fileset>
<classes dir="${target.classes.java.dir}"/>
<!-- 别忘?jin)打包测试?-->
<classes dir="${target.classes.test.dir}"/>
<!-- 别忘?jin)打包各U相关的jar文g -->
< lib dir="project.classpath"/>
</war>
</target>
<target name="test.prepare"
depends="war, compile.cactus, test.prepare.logging">
<!-- Cactify the web-app archive -->
<cactifywar srcfile="${target.dir}/${project.name}.war"
destfile="${tomcat.home}/webapps/${project.name}-cactified.war"
>
<classes dir="${target.classes.java.dir}"/>
<classes dir="${target.classes.test.dir}"/>
<lib dir="project.classpath"/>
</cactifywar>
</target>
<target name="test" depends="test.prepare"
description="Run tests on Tomcat ">
<!-- Start the servlet engine, wait for it to be started, run the
unit tests, stop the servlet engine, wait for it to be stopped.
The servlet engine is stopped if the tests fail for any reason -->
<!-- 8080是服务器的端口号Q?{project.name}-cactified是项目的路径Q和上一步的cactifywar 的destfile相对?-->
<runservertests
testURL="http://localhost:8080/${project.name}-cactified/ServletRedirector?Cactus_Service=RUN_TEST"
startTarget="_StartTomcat"
stopTarget="_StopTomcat"
testTarget="_Test"/>
</target>
<!-- _Test是一个普通的junitd -->
<target name="_Test">
<junit printsummary="yes" fork="yes">
<classpath>
<path refid="project.classpath"/>
<pathelement location="${target.classes.java.dir}"/>
<pathelement location="${target.classes.test.dir}"/>
</classpath>
<formatter type="brief" usefile="false"/>
<formatter type="xml"/>
<batchtest>
<fileset dir="${src.test.dir}">
<!-- Due to some Cactus synchronization bug, the 'unit' tests need
to run before the 'sample' tests -->
<include name="**/Test*.java"/>
<exclude name="**/Test*All.java"/>
</fileset>
</batchtest>
</junit>
</target>
Cactus?/p>
Q ?
Cactus实现?jin)对JUnit试框架的无~扩展,可以方便地测试服务端应用E序。Cactus可以在下面几U情况下使用Q?/p>
Cactus的用也是非常简单的Q你写的试cd需l承ServletTestCase或者JspTestCase、FilterTestCaseQ它们都l承?jin)JUnit的TestCaseQ。写好测试代码后需要启动web容器Q然后执行测试代码。在下面的章节中我们通过例子向你详细讲解?/p>
Cactus目Apache Jakarta Commons的一个子目Q网址是:(x)http://jakarta.apache.org/commons/cactus/?/p>
Q TestCase框架
在Cactus下,我们写的TestCase与JUnit有所不同Q先看一D代码,如下Q?/p> public class TestSample extendsServletTestCase/JspTestCase/FilterTestCase {
public TestSample (String testName) {
super(testName);
}
public void setUp() {
}
public void tearDown() {
}
public void beginXXX(WebRequest theRequest) {
}
public void testXXX() {
}
public void endXXX(WebResponse theResponse) {
}
上面是一个Cactus试cȝ完整代码框架Q其中的extends部分需要按你所试的不同目标来l承不同的类Q简介中有所描述Q?/p>
另外我们注意C个新的方法beginXXX和endXXX的,q两个方法分别会(x)在testXXX执行前和执行后执行,它们和setUp、tearDown不同的是beginXXX和endXXX?x)在相应的testXXX前执行,而setUp和tearDown则在每个testXXXҎ(gu)前都?x)执行。另外beginXXX和endXXX是客L(fng)代码Q所以在q两个方法里是无法用requestq样的服务端对象的?/p>
对于endXXXҎ(gu)需要另加说明的是,在Cactus v1.1前(包括v1.1Q,它的形式是这L(fng)public void endXXX(HttpURLConnection theConnection)Q而在Cactus v1.2开始它的Ş式有两种可能Q?/p>
可以看到区别在于引用的包不同Qؓ(f)什么会(x)q样的呢Q因为在v1.2开始Cactus集成?jin)HttpUnitq个lg。如果你熟?zhn)HttpUnitq个lgQ我惛_该明白ؓ(f)什么要集成HttpUnit。下面我们来看一D代码开比较一下两者的区别Q?/p>
public void endXXX(org.apache.cactus.WebResponse theResponse) {
String content = theResponse.getText();
assertEquals(content, "<html><body><h1>Hello world!</h1></body></html>");
}
public void endXXX(com.meterware.httpunit.WebResponse theResponse) {
WebTable table = theResponse.getTables()[0];
assertEquals("rows", 4, table.getRowCount());
assertEquals("columns", 3, table.getColumnCount());
assertEquals("links", 1, table.getTableCell(0, 2).getLinks().length);
}
当然Q在实际应用中你需要根据不同的需要来选择不同的endXXX。两个WebResponse的差别可以参见两者各自的API DocQ这里就不再多说?jin)?/p>
如何在Cactus里写试
Q 写测试代?/strong>
首先Q我们给?gu)类的代码,是一个ServletQ?/p>
public class SampleServlet extends HttpServlet {
public void doGet(HttpServletRequest theRequest,
HttpServletResponse theResponse) throws IOException {
PrintWriter pw = theResponse.getWriter();
theResponse.setContentType("text/html");
pw.print("<html><head/><body>");
pw.print("A GET request");
pw.print("</body></html>");
}
public String checkMethod(HttpServletRequest theRequest) {
return theRequest.getMethod();
}
}
Cactus中的试cL架已l在上面l出。下面来看一下例子,例子是从中Cactus自带的实例中抽取的一部分Q如下:(x)
public class TestSampleServlet extends ServletTestCase {
public void testReadServletOutputStream() throws IOException {
SampleServlet servlet = new SampleServlet();
servlet.doGet(request, response);
}
public void endReadServletOutputStream(WebResponse theResponse)
throws IOException {
String expected = "<html><head/><body>A GET request</body></html>";
String result = theResponse.getText();
assertEquals(expected, result);
}
public void beginPostMethod(WebRequest theRequest) {
theRequest.addParameter("param", "value", WebRequest.POST_METHOD);
}
public void testPostMethod() {
SampleServlet servlet = new SampleServlet();
assertEquals("POST", servlet.checkMethod(request));
assertEquals("value", request.getParameter("param"));
}
}
W一个方法testReadServletOutputStreamQ调用doGetQ相当于在客L(fng)提交hQ然后在Servlet处理后会(x)产生一个回馈,所以,在endReadServletOutputStreamҎ(gu)里,我们通过调用response的相应方法判断回馈是否符合预期结果?/p>
W二个方法testPostMethodQ在q之前有一个beginPostMethodQ在q个Ҏ(gu)里我们以POST方式往request里增加一个表单数据paramQgؓ(f)”value”。下面在testPostMethod我们p验证表单数据是否以POST方式提交C(jin)服务端的Servlet里,所以,我们看到?jin)两个assertEqualsQ分别进行了(jin)判断。在q里我们要注意到beginPostMethodҎ(gu)中的theRequest和testPostMethod中的request的区别,在前面我们已l提到过QbeginPostMethod是在客户端执行的Q所以它Ҏ(gu)内的所有操作事实上是模拟页面操作的Q比如上面的讄表单数据Q而testPostMethod是服务端执行的,其中的request也是服务端的?/p>配置cactus.properties和web.xml
cactus.properties
q个属性是必须的,它指定了(jin)web应用的访问地址
例:(x)cactus.contextURL = http://localhost:8080/test
可选,当测试类l承ServletTestCase时用于指定Cactus Servlet Redirector的映名U。默认:(x)ServletRedirector
例:(x)cactus.servletRedirectorName = ServletRedirector
可选,当测试类l承ServletTestCase时用于指定Cactus Jsp Redirector的映名U。默认:(x)ServletRedirector
例:(x)cactus.jspRedirectorName = JspRedirector
可选,当测试类l承ServletTestCase时用于指定Cactus Filter Redirector的映名U。默认:(x)ServletRedirector
例:(x)cactus.filterRedirectorName = FilterRedirector
Cactus.properties你可以放|在WEB-INF/classes/下?/p>
web.xml
在web.xml里要为相应的试cL定相应的Cactus Redirector?/p>
ServletTestCase对应org.apache.cactus.server.ServletTestRedirector
JspTestCase对应/jspRedirector.jsp
FilterTestCase对应org.apache.cactus.server.FilterTestRedirector
<web-app>
<filter>
<filter-name>FilterRedirector</filter-name>
<filter-class>org.apache.cactus.server.FilterTestRedirector</filter-class>
</filter>
<filter-mapping>
<filter-name>FilterRedirector</filter-name>
<url-pattern>/FilterRedirector</url-pattern>
</filter-mapping>
<servlet>
<servlet-name>ServletRedirector</servlet-name>
<servlet-class>org.apache.cactus.server.ServletTestRedirector</servlet-class>
</servlet>
<servlet>
<servlet-name>JspRedirector</servlet-name>
<jsp-file>/jspRedirector.jsp</jsp-file>
</servlet>
<servlet-mapping>
<servlet-name>ServletRedirector</servlet-name>
<url-pattern>/ServletRedirector</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>JspRedirector</servlet-name>
<url-pattern>/JspRedirector</url-pattern>
</servlet-mapping>
</web-app>
如果你的试cȝ承了(jin)JspTestCase则需要将jspRedirector.jsp文g攄C在web.xml中指定的路径里?/p>
安装说明
如下Q?/p>
junit.jar
servlet.jar
cactus.jar
httpclient.jar
commons-logging.jar
httpunit.jarQTidy.jarQxerces.jarQ可选,如果你集成了(jin)httpunit的话需要,也就是在endXXX中用了(jin)httpunitQ?/p>
cactus.jar
junit.jar
aspectjrt.jar
commons-logging.jar
Class.forName("oracle.jdbc.driver.OracleDriver").newInstance(); String url="jdbc:oracle:thin:@localhost:1521:orcl"; //orcl为数据库的SID String user="test"; String password="test"; Connection conn= DriverManager.getConnection(url,user,password); |
Class.forName("com.ibm.db2.jdbc.app.DB2Driver ").newInstance(); String url="jdbc:db2://localhost:5000/sample"; //sampleZ的数据库? String user="admin"; String password=""; Connection conn= DriverManager.getConnection(url,user,password); |
Class.forName("com.microsoft.jdbc.sqlserver.SQLServerDriver").newInstance(); String url="jdbc:microsoft:sqlserver://localhost:1433;DatabaseName=mydb"; //mydb为数据库 String user="sa"; String password=""; Connection conn= DriverManager.getConnection(url,user,password); |
Class.forName("com.sybase.jdbc.SybDriver").newInstance(); String url =" jdbc:sybase:Tds:localhost:5007/myDB";//myDBZ的数据库? Properties sysProps = System.getProperties(); SysProps.put("user","userid"); SysProps.put("password","user_password"); Connection conn= DriverManager.getConnection(url, SysProps); |
Class.forName("com.informix.jdbc.IfxDriver").newInstance(); String url = "jdbc:informix-sqli://123.45.67.89:1533/myDB:INFORMIXSERVER=myserver; user=testuser;password=testpassword"; //myDB为数据库? Connection conn= DriverManager.getConnection(url); |
Class.forName("org.gjt.mm.mysql.Driver").newInstance(); String url ="jdbc:mysql://localhost/myDB?user=soft&password=soft1234&useUnicode=true&characterEncoding=8859_1" //myDB为数据库? Connection conn= DriverManager.getConnection(url); |
Class.forName("org.postgresql.Driver").newInstance(); String url ="jdbc:postgresql://localhost/myDB" //myDB为数据库? String user="myuser"; String password="mypassword"; Connection conn= DriverManager.getConnection(url,user,password); |
Class.forName("sun.jdbc.odbc.JdbcOdbcDriver") ; String url="jdbc:odbc:Driver={MicroSoft Access Driver (*.mdb)};DBQ="+application.getRealPath("/Data/ReportDemo.mdb"); Connection conn = DriverManager.getConnection(url,"",""); Statement stmtNew=conn.createStatement() ; |
try{ Class.forName(com.mysql.jdbc.Driver); System.out.println(Success loading Mysql Driver!); }catch(Exception e) { System.out.println(Error loading Mysql Driver!); e.printStackTrace(); } |
jdbcQmysqlQ?/localhost/databasename[?pa=va][Qpa=va] |
PreparedStatement pstmt3D null; try { ((OraclePreparedStatement)pstmt).setExecuteBatch(30); ... pstmt.executeUpdate(); } |