在运行测试时你有可能注意到
log4j:WARN No appenders could be found for logger (org.apache.cxf.bus.spring.BusApplicationContext).
log4j:WARN Please initialize the log4j system properly.
这是因为没有加入log4j配置文件的缘故,一般情况下,配置文件应当放在运行时的classpath中,即项目的target目录中。但如果运行mvn clean的话target文件夹将被删去,如果手动拷贝配置文件的话,麻烦不说还有可能造成版本的不一致。此时应当使用maven提供的资源管理功能,即将log4j.properties放在src/main/resources中,maven会自动将该文件放到项目的target目录中(详情参见上文中关于maven 命令lifecycle的讲解),如果配置文件只在测试中被使用可将其放在src/test/resources中。
将spring的配置文件client-beans.xml放入src/main/resources中,代码详细附录(二)
将org.world.hello.apps.cxf.bookstore.test.BookStoreServiceTest文件中的setUp方法替换为
public void setUp() {
// JaxWsProxyFactoryBean factory = new JaxWsProxyFactoryBean();
// factory.getInInterceptors().add(new LoggingInInterceptor());
// factory.getOutInterceptors().add(new LoggingOutInterceptor());
// factory.setServiceClass(BookStore.class);
// factory.setAddress("http://localhost:9000/bookStore");
// setService((BookStore) factory.create());
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(
new String[]{"client-beans.xml"});
service = (BookStore)context.getBean("client");
}
并添加import org.springframework.context.support.ClassPathXmlApplicationContext;
启动(/重启)Server,执行mvn test验证一切正常。
你有可能会问‘我并没有在pom.xml中引入spring的包,为什么可以使用spring呢?’;答案在于你所用的包是由maven从repository中下载过来的,其依赖性也由maven所管理,而cxf项目本身便依赖与spring框架,所以spring也被加入到你的classpath中了;你可以从eclipse中看到你的项目依赖于哪些包。
创建src/main/webapp/WEB-INF文件夹。
创建文件src/main/webapp/WEB-INF/web.xml,内容如下:
<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE web-app
PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd">
<web-app>
</web-app>
创建文件src/main/webapp/index.html,内容如下:
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=GB18030">
<title>Insert title here</title>
</head>
<body>
Hello from index.html
</body>
</html>
修改pom.xml,添加以下内容(添加了jetty的maven插件,并指定了在9090端口启动jetty)
<plugins>
……
<plugin>
<groupId>org.mortbay.jetty</groupId>
<artifactId>maven-jetty-plugin</artifactId>
<configuration>
<connectors>
<connector
implementation="org.mortbay.jetty.nio.SelectChannelConnector">
<port>9090</port>
</connector>
</connectors>
</configuration>
</plugin>
……
</plugins>
<finalName>start_off</finalName>
执行命令
$mvn jetty:run
你将能看到“Hello from index.html”字样,启动的server可用ctrl+c来停止。
修改web.xml,内容如下
<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE web-app
PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd">
<web-app>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>WEB-INF/beans.xml</param-value>
</context-param>
<listener>
<listener-class>
org.springframework.web.context.ContextLoaderListener
</listener-class>
</listener>
<servlet>
<servlet-name>CXFServlet</servlet-name>
<display-name>CXF Servlet</display-name>
<servlet-class>
org.apache.cxf.transport.servlet.CXFServlet
</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>CXFServlet</servlet-name>
<url-pattern>/services/*</url-pattern>
</servlet-mapping>
</web-app>
其中指定了使用WEB-INF/beans.xml作为cxf的配置文件,并将服务挂载在/services/*上。
下面创建WEB-INF/beans.xml
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:jaxws="http://cxf.apache.org/jaxws"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://cxf.apache.org/jaxws
http://cxf.apache.org/schemas/jaxws.xsd">
<import resource="classpath:META-INF/cxf/cxf.xml" />
<import resource="classpath:META-INF/cxf/cxf-extension-soap.xml" />
<import resource="classpath:META-INF/cxf/cxf-servlet.xml" />
<jaxws:endpoint address="/bookStore" serviceName="t:bookStoreService"
xmlns:t="http://bookstore.hello.world.org">
<jaxws:implementor>
<bean
class="org.world.hello.apps.cxf.bookstore.server.BookStoreServiceImpl" />
</jaxws:implementor>
<jaxws:inInterceptors>
<bean
class="org.apache.cxf.interceptor.LoggingInInterceptor" />
</jaxws:inInterceptors>
<jaxws:outInterceptors>
<bean
class="org.apache.cxf.interceptor.LoggingOutInterceptor" />
</jaxws:outInterceptors>
</jaxws:endpoint>
</beans>
jaxws:implementor中指定了服务的实现者。
执行命令
$mvn jetty:run
修改client-beans.xml将proxyFactory的address属性重新指定为“http://127.0.0.1:9090/start_off/services/bookStore”
在另一个命令行
$mvn test
如果通过测试,说明服务已经正常发布在jetty上了。
在pom.xml中更改打包的格式,即将<packaging>jar</packaging>改为<packaging>war</packaging>。
执行命令
$mvn package
*注:package指令在maven中的生命期在test之后,所以执行package时会自动执行test,即只有通过了测试才能打包。
执行完打包指令之后,在项目的target目录中就可以看到start_off-1.0.war,要将工程部署在tomcat上,只需将war文件拷贝到webapps文件夹中即可。
二、拆分你的第一个maven2项目为多个子项目的组合
修改pom.xml中的<packaging>war</packaging>为<packaging>pom</packaging>
执行命令(要在同一行中写)
mvn archetype:create -Dversion=1.0 -DgroupId=org.world.hello.apps -DartifactId=start_off_api
执行以上命令后,在start_off项目的pom.xml中会自动添加<modules><module>start_off_api</module></modules>
,表明start_off_api项目为本项目的子项目。
同时在start_off项目的文件夹中会生成start_off_api项目的文件结构。
查看start_off_api项目的pom.xml,也可以看出它和start_off项目的关系。
<parent>
<artifactId>start_off</artifactId>
<groupId>org.world.hello.apps</groupId>
<version>1.0</version>
</parent
执行命令
$mvn eclipse:eclipse
可以发现一条指令同时在操作两个项目。
输出如下结果:
[INFO] ------------------------------------------------------------------------
[INFO] Reactor Summary:
[INFO] ------------------------------------------------------------------------
[INFO] start_off ............................................. SUCCESS [3.734s]
[INFO] start_off_api ......................................... SUCCESS [5.531s]
[INFO] ------------------------------------------------------------------------
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESSFUL
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 9 seconds
[INFO] Finished at: Mon Nov 26 10:24:54 CST 2007
[INFO] Final Memory: 9M/17M
之后可将start_off_api项目也导入eclipse。
同理创建start_off_web项目。
执行命令(要在同一行中写)
mvn archetype:create -Dversion=1.0 -DgroupId=org.world.hello.apps -DartifactId=start_off_web
将没有用的App.java和AppTest.java删除。
将start_off项目的src/main/webapp文件夹移到start_off_web项目中。
将start_off项目src中的剩余内容移到start_off_api项目的src文件夹中。
注释掉org.world.hello.apps.cxf.bookstore.test. BookStoreServiceTest中的有效测试,添加一个假的测试(目的是跳过maven生命周期的测试阶段,而执行下面任务)
public void testTruth() {
assertTrue(true);
}
修改start_off_web项目的pom.xml文件,修改后的内容如下:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<parent>
<artifactId>start_off</artifactId>
<groupId>org.world.hello.apps</groupId>
<version>1.0</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.world.hello.apps</groupId>
<artifactId>start_off_web</artifactId>
<name>start_off_web</name>
<version>1.0</version>
<packaging>war</packaging>
<url>http://maven.apache.org</url>
<dependencies>
<dependency>
<groupId>org.world.hello.apps</groupId>
<artifactId>start_off_api</artifactId>
<version>1.0</version>
</dependency>
</dependencies>
<build>
<finalName>start_off_web</finalName>
<plugins>
<plugin>
<groupId>org.mortbay.jetty</groupId>
<artifactId>maven-jetty-plugin</artifactId>
<configuration>
<connectors>
<connector
implementation="org.mortbay.jetty.nio.SelectChannelConnector">
<port>9090</port>
</connector>
</connectors>
</configuration>
</plugin>
</plugins>
</build>
</project>
*注:其中指出了start_off_web项目依赖于start_off_api项目
修改start_off_api项目的pom.xml文件,修改后的内容如下:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<parent>
<artifactId>start_off</artifactId>
<groupId>org.world.hello.apps</groupId>
<version>1.0</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.world.hello.apps</groupId>
<artifactId>start_off_api</artifactId>
<name>start_off_api</name>
<version>1.0</version>
<packaging>jar</packaging>
<url>http://maven.apache.org</url>
<dependencies>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<archive>
<manifest>
<mainClass>
org.world.hello.apps.cxf.bookstore.bin.Server
</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
</plugins>
</build>
</project>
*注:子项目所依赖的包可从父项目中间接得到
在start_off项目中的pom.xml中删去插件maven-jetty-plugin和maven-jar-plugin。
执行命令
$mvn clean eclipse:clean eclipse:eclipse
$mvn install
以上的install命令,将项目安装到了本地的repository中。
若想将服务部署到其他server上,可在start_off项目的根目录下执行mvn package,生成的war被放在start_off_web项目的target目录中。
创建start_off_impl子项目,执行命令(要在同一行中写)
mvn archetype:create -Dversion=1.0 -DgroupId=org.world.hello.apps -DartifactId=start_off_impl
将没有用的App.java和AppTest.java删除。
修改start_off_impl项目的pom.xml如下
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<parent>
<artifactId>start_off</artifactId>
<groupId>org.world.hello.apps</groupId>
<version>1.0</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.world.hello.apps</groupId>
<artifactId>start_off_impl</artifactId>
<name>start_off_impl</name>
<version>1.0</version>
<packaging>jar</packaging>
<url>http://maven.apache.org</url>
<dependencies>
<dependency>
<groupId>org.world.hello.apps</groupId>
<artifactId>start_off_api</artifactId>
<version>1.0</version>
</dependency>
</dependencies>
</project>
修改start_off_web项目的pom.xml,添加依赖
<dependency>
<groupId>org.world.hello.apps</groupId>
<artifactId>start_off_impl</artifactId>
<version>1.0</version>
</dependency>
将start_off_api中的
org.world.hello.apps.cxf.bookstore.server. BookStoreServiceImpl.java
org.world.hello.apps.cxf.bookstore.test. BookStoreServiceTest.java
org.world.hello.apps.cxf.bookstore.bin.Server.java
移动到start_off_impl项目中。
在start_off项目的根目录下执行命令
$mvn clean eclipse:clean eclipse:eclipse install
之后便可启动jetty,验证服务仍可访问,项目拆分完毕。