maven快速入门第十三讲——使用maven整合SSH

从零开始学习maven 专栏收录该内容
22 篇文章 36 订阅

前言

在本讲中,我会使用maven来整合Hibernate-5.0.7.Final、Struts-2.3.24和Spring-4.2.4.RELEASE这三个框架,实现从数据库中查询所有客户的需求。

在正式编写代码实现这个需求之前,我们得做一些准备工作,提前创建一个数据库(例如s2sh_crm),并在该数据库下新建一张客户表,这里笔者使用的数据库是MySQL。

create database s2sh_crm;
use s2sh_crm;

CREATE TABLE `cst_customer` (
	`cust_id` bigint(32) NOT NULL AUTO_INCREMENT COMMENT '客户编号(主键)',
	`cust_name` varchar(32) NOT NULL COMMENT '客户名称(公司名称)',
	`cust_source` varchar(32) DEFAULT NULL COMMENT '客户信息来源',
	`cust_industry` varchar(32) DEFAULT NULL COMMENT '客户所属行业',
	`cust_level` varchar(32) DEFAULT NULL COMMENT '客户级别',
	`cust_phone` varchar(64) DEFAULT NULL COMMENT '固定电话',
	`cust_mobile` varchar(16) DEFAULT NULL COMMENT '移动电话',
	PRIMARY KEY (`cust_id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;

经过前面几讲的学习:

想必你已经可以创建出一个如下结构的聚合工程了。
在这里插入图片描述
在使用maven整合SSH时,需要依赖struts-2.3.24、spring-framework-4.2.4.RELEASE以及hibernate-5.0.7.Final等,于是我们会在父工程的pom.xml文件中添加如下依赖,其实在实际企业开发中会有架构师专门来编写pom.xml文件。

<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/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<groupId>com.meimeixia</groupId>
	<artifactId>crm-parent</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<packaging>pom</packaging>
	
	<!-- 父工程下所包含的子模块(工程) -->
	<modules>
		<module>crm-dao</module>
		<module>crm-service</module>
		<module>crm-web</module>
	</modules>
	
	<!-- 定义版本常量 -->
	<properties>
		<spring.version>4.2.4.RELEASE</spring.version>
		<struts.verison>2.3.24</struts.verison>
		<hibernate.version>5.0.7.Final</hibernate.version>
	</properties>
	
	<dependencies>
		<!-- Struts2核心依赖 -->
		<dependency>
			<groupId>org.apache.struts</groupId>
			<artifactId>struts2-core</artifactId>
			<version>${struts.verison}</version>
			<!-- 排除依赖 -->
			<exclusions>
				<exclusion>
					<artifactId>javassist</artifactId>
					<groupId>javassist</groupId>
				</exclusion>
			</exclusions>
		</dependency>
		<!-- Hibernate核心依赖 -->
		<dependency>
			<groupId>org.hibernate</groupId>
			<artifactId>hibernate-core</artifactId>
			<version>${hibernate.version}</version>
		</dependency>
		<!-- 下面这个会引入spring-beans-4.2.2.RELEASE.jar -->
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-context</artifactId>
			<version>4.2.2.RELEASE</version>
		</dependency>
		<!-- 下面这个会引入spring-beans-3.0.5.RELEASE.jar -->
		<!-- Struts2和Spring整合依赖 -->
		<dependency>
			<groupId>org.apache.struts</groupId>
			<artifactId>struts2-spring-plugin</artifactId>
			<version>${struts.verison}</version>
		</dependency>
		<!-- 依赖管理的第二个原则:路径近者优先原则 -->
		<!-- 这个spring-beans-${spring.version}版本的jar包放到最后面去了,但是它还是生效了。那这是为啥啊? -->
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-beans</artifactId>
			<version>${spring.version}</version>
		</dependency>
		<!-- Spring核心依赖 -->
		<dependency>
		    <groupId>org.springframework</groupId>
		    <artifactId>spring-core</artifactId>
		    <version>${spring.version}</version>
		</dependency>
		<!-- 有事务的时候,我们就需要用到了,例如去声明事务、做事务注解等 -->
		<dependency>
		    <groupId>org.springframework</groupId>
		    <artifactId>spring-context-support</artifactId>
		    <version>${spring.version}</version>
		</dependency>
		<!-- 切面 -->
		<dependency>
		    <groupId>org.springframework</groupId>
		    <artifactId>spring-aop</artifactId>
		    <version>${spring.version}</version>
		</dependency>
		<!-- 声明式事务 -->
		<dependency>
		    <groupId>org.springframework</groupId>
		    <artifactId>spring-tx</artifactId>
		    <version>${spring.version}</version>
		</dependency>
		<!-- Spring整合ORM框架依赖 -->
		<dependency>
		    <groupId>org.springframework</groupId>
		    <artifactId>spring-orm</artifactId>
		    <version>${spring.version}</version>
		</dependency>
		<dependency>
		    <groupId>org.springframework</groupId>
		    <artifactId>spring-web</artifactId>
		    <version>${spring.version}</version>
		</dependency>
		<dependency>
		    <groupId>org.aspectj</groupId>
		    <artifactId>aspectjweaver</artifactId>
		    <version>1.8.7</version>
		</dependency>
		<dependency>
		    <groupId>org.slf4j</groupId>
		    <artifactId>slf4j-api</artifactId>
		    <version>1.7.12</version>
		</dependency>
		<dependency>
		    <groupId>org.slf4j</groupId>
		    <artifactId>slf4j-log4j12</artifactId>
		    <version>1.7.12</version>
		</dependency>
		<!-- MySQL数据库驱动 -->
		<dependency>
		    <groupId>mysql</groupId>
		    <artifactId>mysql-connector-java</artifactId>
		    <version>5.1.48</version>
		    <scope>runtime</scope>
		</dependency>
		<!-- c3p0连接池 -->
		<dependency>
		    <groupId>com.mchange</groupId>
		    <artifactId>c3p0</artifactId>
		    <version>0.9.5.5</version>
		</dependency>
		<dependency>
		    <groupId>jstl</groupId>
		    <artifactId>jstl</artifactId>
		    <version>1.2</version>
		</dependency>
		<dependency>
			<groupId>javax.servlet</groupId>
			<artifactId>servlet-api</artifactId>
			<version>2.5</version>
			<scope>provided</scope>
		</dependency>
	</dependencies>
	
	<!-- 版本锁定 -->
	<dependencyManagement>
		<!-- 在这里锁定junit的版本为4.9 -->
		<dependencies>
			<dependency>
				<groupId>junit</groupId>
				<artifactId>junit</artifactId>
				<version>4.9</version>
				<scope>test</scope>
			</dependency>
		</dependencies>
	</dependencyManagement>
	
	<build>
		<plugins>
			<!-- 设置编译版本为1.8 -->
			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-compiler-plugin</artifactId>
				<version>3.5.1</version>
				<configuration>
	                <!-- 源码版本 -->
	                <source>1.8</source>
	                <!-- 编译目标版本 -->
	                <target>1.8</target>
	                <!-- 指定编码 -->
	                <encoding>utf-8</encoding>
	            </configuration>
			</plugin>
			<!-- 配置tomcat插件 -->
			<plugin>
				<groupId>org.apache.tomcat.maven</groupId>
                <artifactId>tomcat7-maven-plugin</artifactId>
                <version>2.2</version>
				<configuration>
					<!-- 配置访问端口 -->
					<port>8080</port>
					<!-- 访问的项目路径 -->
					<path>/crm</path>
					<!-- 
						编码,为什么加这个编码呢?大家都知道,我们使用网络传输的时候,默认情况下使用的是iso8859-1编码
						(提交请求的时候,特别是使用get请求的时候),所以要进行一个编码转换! 
					-->
					<uriEncoding>utf-8</uriEncoding>
				</configuration>
			</plugin>
		</plugins>
	</build>
</project>

从中可以看出父工程的pom.xml文件中抽取了一些重复的配置,比如:锁定jar包的版本、设置编译版本等,也可以看出子工程中要用到的依赖都在父工程的pom.xml文件中先定义好了,将来子工程在开发的时候就不需要再引坐标了。

温馨提示:此处并没有添加junit的依赖,只是锁定了junit的版本为4.9,各个子工程开发完毕之后,在编写JUnit单元测试用例时,还需要在其pom.xml文件中添加junit的依赖。

crm-dao子模块的开发与测试

创建Customer实体类和其相对应的映射配置文件

首先,在src/main/java目录下新建一个com.meimeixia.crm.domain包,并在该包下创建一个Customer实体类。

package com.meimeixia.crm.domain;

import java.io.Serializable;

/**
 * PO(Persistence Object):持久化类
 * 持久化类有如下7个规范:
 * 1. 公有类
 * 2. 公有无参构造
 * 3. 私有属性
 * 4. 公有的getter与setter
 * 5. 实现java.io.Serializable接口
 * 6. 不能用final修饰
 * 7. 如果是基础类型,要使用它的包装类 
 * 
 * @author liayun
 *
 */
public class Customer implements Serializable {

	private static final long serialVersionUID = 1L;//加上也行,不加也行
	
	private Long custId;
	private String custName;
	private String custSource;
	private String custIndustry;
	private String custLevel;
	private String custPhone;
	private String custMobile;
	
	public Long getCustId() {
		return custId;
	}
	public void setCustId(Long custId) {
		this.custId = custId;
	}
	public String getCustName() {
		return custName;
	}
	public void setCustName(String custName) {
		this.custName = custName;
	}
	public String getCustSource() {
		return custSource;
	}
	public void setCustSource(String custSource) {
		this.custSource = custSource;
	}
	public String getCustIndustry() {
		return custIndustry;
	}
	public void setCustIndustry(String custIndustry) {
		this.custIndustry = custIndustry;
	}
	public String getCustLevel() {
		return custLevel;
	}
	public void setCustLevel(String custLevel) {
		this.custLevel = custLevel;
	}
	public String getCustPhone() {
		return custPhone;
	}
	public void setCustPhone(String custPhone) {
		this.custPhone = custPhone;
	}
	public String getCustMobile() {
		return custMobile;
	}
	public void setCustMobile(String custMobile) {
		this.custMobile = custMobile;
	}
	
}

然后,我们就要创建一个与以上实体类相对应的映射配置文件了,即Customer.hbm.xml。你有没想过,这个映射配置文件应该放置在哪儿呢?那肯定是放在src/main/resources目录下。之前都是将这样的映射配置文件与其相对应的实体类放在同一个包下,所以我们也可以在src/main/resources目录下新建一个com.meimeixia.crm.domain包,并在该包下创建一个Customer.hbm.xml映射配置文件。

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC 
    "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
    "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
    
<hibernate-mapping>
	<class name="com.meimeixia.crm.domain.Customer" table="cst_customer" >
        <id name="custId" type="java.lang.Long">
            <column name="cust_id" />
            <!-- 6种生成策略:identity、native、sequence、uuid、increment、assigned -->
        </id>
      
        <property name="custName" type="string">
            <column name="cust_name" length="32" not-null="true"></column>
        </property>
        <property name="custSource" column="cust_source"></property>
        <property name="custIndustry" column="cust_industry"></property>
        <property name="custLevel" column="cust_level"></property>
        <property name="custPhone" type="string">
            <column name="cust_phone" length="64"></column>
        </property>
        <property name="custMobile" type="string">
            <column name="cust_mobile" length="16"></column>
        </property>
    </class>
</hibernate-mapping>

创建相应的接口与实现类

首先,在src/main/java目录下新建一个com.meimeixia.crm.dao包,并在该包下创建一个ICustomerDao接口。

package com.meimeixia.crm.dao;

import java.util.List;

import com.meimeixia.crm.domain.Customer;

public interface ICustomerDao {
	
	public List<Customer> findAll();
	
}

然后,在src/main/java目录下再新建一个com.meimeixia.crm.dao.impl包,并在该包下创建以上接口的一个实现类。

package com.meimeixia.crm.dao.impl;

import java.util.List;

import org.springframework.orm.hibernate5.support.HibernateDaoSupport;

import com.meimeixia.crm.dao.ICustomerDao;
import com.meimeixia.crm.domain.Customer;

public class CustomerDao extends HibernateDaoSupport implements ICustomerDao {
	
	public List<Customer> findAll() {
		return (List<Customer>) getHibernateTemplate().find("from Customer");
	}
	
}

Spring框架整合Hibernate框架

首先,创建Hibernate核心配置文件,该核心配置文件的位置是在src/main/resources目录下面,名称是hibernate.cfg.xml。

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
	"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
	"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
	
<hibernate-configuration>
	<session-factory>
		<!-- 配置Hibernate的方言 -->
		<property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
		
		<!-- 下面两个是可选的配置哟! -->
		<!-- 打印sql语句 -->
		<property name="hibernate.show_sql">true</property>
		<!-- 格式化sql语句 -->
		<property name="hibernate.format_sql">false</property>
		
		<property name="hbm2ddl.auto">none</property>
		
		<!-- 懒加载 -->
		<property name="hibernate.enable_lazy_load_no_trans">true</property>
		
		<!-- 是否启用实体类的验证(实体类的验证,跟我们映射文件进行一个映射的匹配) -->
		<property name="javax.persistence.validation.mode">none</property>
	</session-factory>
</hibernate-configuration>

然后,就要整合Spring框架与Hibernate框架了。整合不麻烦,就看你看不看得懂了,反正我是看懂了。我们可以在src/main/resources目录下新建一个名为spring的包,并在该包下创建一个名称为applicationContext-dao.xml的Spring配置文件,内容如下:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
	xmlns:context="http://www.springframework.org/schema/context"
	xmlns:aop="http://www.springframework.org/schema/aop" 
	xmlns:tx="http://www.springframework.org/schema/tx"
	xsi:schemaLocation="
		http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd 
		http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd 
		http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd 
		http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd ">

	<!-- 配置数据源(也即c3p0连接池) -->
	<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
		<property name="driverClass" value="com.mysql.jdbc.Driver" />
		<property name="jdbcUrl" value="jdbc:mysql://localhost:3306/crm?characterEncoding=utf-8" />
		<property name="user" value="root" />
		<property name="password" value="liayun" />
	</bean>
	
	<!-- 配置sessionFactory -->
	<bean id="sessionFactory" class="org.springframework.orm.hibernate5.LocalSessionFactoryBean">
		<property name="dataSource" ref="dataSource"></property>
		<!-- 加载Hibernate配置文件 -->
		<property name="configLocation" value="classpath:hibernate.cfg.xml" />
		<!-- (引入所有的映射文件)告诉Hibernate加载哪个映射文件 -->
		<property name="mappingLocations" value="classpath:com/meimeixia/crm/domain/*.hbm.xml"></property>
	</bean>
	
	<!-- 数据访问层 -->
	<bean id="customerDao" class="com.meimeixia.crm.dao.impl.CustomerDao">
		<property name="sessionFactory" ref="sessionFactory"></property>
	</bean>
</beans>

至此,crm-dao子模块就开发完毕了。

编写JUnit单元测试用例

crm-dao子模块开发完毕之后,接下来,我们就要编写JUnit单元测试用例了。温馨提示:大家在实际项目开发中,开发完一个模块后,一定要记得编写JUnit单元测试用例进行测试,这是一个合格的程序员的基本素养。

首先,确保pom.xml文件中添加了junit的依赖。
在这里插入图片描述
然后,在src/test/java目录下新建一个com.meimeixia.crm.dao.test包,并在该包下创建一个单元测试类,例如CustomerDaoTest.java。

package com.meimeixia.crm.dao.test;

import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.meimeixia.crm.dao.impl.CustomerDao;

public class CustomerDaoTest {
	
	@Test
	public void tt() {
		ApplicationContext ac = new ClassPathXmlApplicationContext("classpath:spring/applicationContext-dao.xml");
		CustomerDao customerDao = (CustomerDao) ac.getBean("customerDao");
		System.out.println(customerDao.findAll().size());
	}

}

运行以上单元测试方法,可以看到eclipse控制台打印了如下图所示的内容。
在这里插入图片描述
从上图可以知道crm-dao子模块测试完美通过,没有任何毛病!接下来,就要开发crm-service子模块了。

crm-service子模块的开发与测试

创建相应的接口与实现类

首先,在src/main/java目录下新建一个com.meimeixia.crm.service包,并在该包下创建一个ICustomerService接口。

package com.meimeixia.crm.service;

import java.util.List;

import com.meimeixia.crm.domain.Customer;

public interface ICustomerService {
	
	public List<Customer> findAll();
	
}

然后,在src/main/java目录下再新建一个com.meimeixia.crm.service.impl包,并在该包下创建以上接口的一个实现类。

package com.meimeixia.crm.service.impl;

import java.util.List;

import com.meimeixia.crm.dao.ICustomerDao;
import com.meimeixia.crm.domain.Customer;
import com.meimeixia.crm.service.ICustomerService;

public class CustomerService implements ICustomerService {
	
	private ICustomerDao customerDao;

	public void setCustomerDao(ICustomerDao customerDao) {
		this.customerDao = customerDao;
	}

	@Override
	public List<Customer> findAll() {
		return customerDao.findAll();
	}
	
}

配置Spring的事务管理

这里,我会使用Spring基于XML配置文件方式的声明式事务管理来管理事务。于是,在src/main/resources目录下新建一个名为spring的包,并在该包下创建一个名称为applicationContext-service.xml的Spring配置文件,内容如下:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
	xmlns:context="http://www.springframework.org/schema/context"
	xmlns:aop="http://www.springframework.org/schema/aop" 
	xmlns:tx="http://www.springframework.org/schema/tx"
	xsi:schemaLocation="
		http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd 
		http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd 
		http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd 
		http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd ">
	
	<bean id="transactionManager" class="org.springframework.orm.hibernate5.HibernateTransactionManager">
		<property name="sessionFactory" ref="sessionFactory"></property>
	</bean>
	
	<!-- 通知 -->
	<tx:advice id="advice" transaction-manager="transactionManager">
		<tx:attributes>
			<tx:method name="add*" propagation="REQUIRED" />
			<tx:method name="save*" propagation="REQUIRED" />
			<tx:method name="update*" propagation="REQUIRED" />
			<tx:method name="delete*" propagation="REQUIRED" />
			<tx:method name="*" read-only="true" />
		</tx:attributes>
	</tx:advice>
		
	<!-- 切面 -->
	<aop:config>
		<aop:pointcut expression="execution(* com.meimeixia.crm.service.impl.*.*(..))" id="myPointCut"/>
		<aop:advisor advice-ref="advice" pointcut-ref="myPointCut"/>
	</aop:config>
	
	<!-- 业务 -->
	<bean id="customerService" class="com.meimeixia.crm.service.impl.CustomerService">
		<property name="customerDao" ref="customerDao"></property>
	</bean>
</beans>

从以上Spring配置文件的内容中可以看出,CustomerService实现类交给Spring来管理了。

编写JUnit单元测试用例

crm-service子模块开发完毕之后,接下来,我们就要编写JUnit单元测试用例了。首先,肯定要确保pom.xml文件中添加了junit的依赖。
在这里插入图片描述
然后,在src/test/java目录下新建一个com.meimeixia.crm.service.test包,并在该包下创建一个单元测试类,例如CustomerServiceTest.java。

package com.meimeixia.crm.service.test;

import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.meimeixia.crm.service.ICustomerService;

public class CustomerServiceTest {

	@Test
	public void tt() {
		ApplicationContext ac = new ClassPathXmlApplicationContext("classpath:spring/applicationContext-service.xml");
		ICustomerService customerService = (ICustomerService) ac.getBean("customerService");
		System.out.println(customerService.findAll().size());
	}
	
}

千万不要忘了在applicationContext-service.xml配置文件中添加如下配置,即在该配置文件中引入crm-dao子模块中的applicationContext-dao.xml配置文件。
在这里插入图片描述
为什么要这样做呢?因为你不加以上配置,运行CustomerServiceTest单元测试类中的测试方法就会报错,错误提示信息如下图所示。
在这里插入图片描述
导致报错的原因就是没有加载所有与Spring有关的配置文件,也即是说还没有加载到crm-dao子模块中的applicationContext-dao.xml配置文件,而LocalSessionFactoryBean类就配置在该配置文件中。

此时,再次运行CustomerServiceTest单元测试类中的测试方法,你便会看到eclipse控制台打印出了如下图所示的内容。
在这里插入图片描述
从上图可以知道crm-service子模块测试完美通过,没有任何毛病!但像上面这样做,有一个缺点,编写JUnit单元测试用例时要加上那句配置,然而最终我们都是将各个子模块聚合到一起,最后将crm-web子模块打成war包,发布到tomcat服务器上去运行,这句配置又要去掉,这样会显得很麻烦。那有没有更加好的方法来助我们编写JUnit单元测试用例呢?其实是有的,你只须将CustomerServiceTest单元测试类写成下面这样就行了。

package com.meimeixia.crm.service.test;

import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.meimeixia.crm.service.ICustomerService;

public class CustomerServiceTest {

	@Test
	public void tt() {
		//classpath*:spring/applicationContext-*.xml:读取所有classpath路径下的spring目录中的所有以applicationContext-打头的配置文件
		ApplicationContext ac = new ClassPathXmlApplicationContext("classpath*:spring/applicationContext-*.xml");
		ICustomerService customerService = (ICustomerService) ac.getBean("customerService");
		System.out.println(customerService.findAll().size());
	}
	
}

在这里插入图片描述

crm-web子模块的开发

首先,在src/main/java目录下新建一个com.meimeixia.crm.web.action包,并在该包下创建一个CustomerAction类。

package com.meimeixia.crm.web.action;

import java.util.List;

import com.meimeixia.crm.domain.Customer;
import com.meimeixia.crm.service.ICustomerService;
import com.meimeixia.crm.service.impl.CustomerService;
import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionSupport;

/**
 * 客户Action类
 * @author liayun
 *
 */
public class CustomerAction extends ActionSupport {

	//注入客户业务
	private ICustomerService customerService;

	public void setCustomerService(CustomerService customerService) {
		this.customerService = customerService;
	}
	
	/**
	 * 列出所有的客户信息,并返回给list.jsp页面
	 * @return
	 */
	public String list() {
		//查出所有客户信息
		List<Customer> customerList = customerService.findAll();
		//所有客户信息放入值栈中
		ActionContext.getContext().put("list", customerList);
		//返回list.jsp页面
		return "list";
	}
	
}

然后,将以上CustomerAction类交给Spring来管理。于是,我们需要在src/main/resources目录下新建一个名为spring的包,并在该包下创建一个名称为applicationContext-action.xml的Spring配置文件,内容如下:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
	xmlns:context="http://www.springframework.org/schema/context"
	xmlns:aop="http://www.springframework.org/schema/aop" 
	xmlns:tx="http://www.springframework.org/schema/tx"
	xsi:schemaLocation="
		http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd 
		http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd 
		http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd 
		http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd ">
	
	<!-- 配置Action对象 -->
	<bean id="customerAction" class="com.meimeixia.crm.web.action.CustomerAction" scope="prototype">
		<property name="customerService" ref="customerService"></property>
	</bean>
	
</beans>

接着,就要在Struts2配置文件中(即struts.xml)对以上CustomerAction类进行配置了。于是,我们需要在src/main/resources目录下新建一个struts.xml配置文件,内容如下:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts PUBLIC
	"-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
	"http://struts.apache.org/dtds/struts-2.3.dtd">

<struts>
	<package name="default" namespace="/" extends="struts-default">
		<action name="customer_*" class="customerAction" method="{1}">
			<result name="list">/list.jsp</result>
		</action>
	</package>
</struts>

相应地,我们还要在src/main/webapp目录下新建一个展示客户列表的jsp页面,即list.jsp。

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<!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=UTF-8">
<title>Insert title here</title>
</head>
<body>
	<c:forEach items="${list }" var="customer">
		${customer.custId } ----> ${customer.custName } <br/>
	</c:forEach>
</body>
</html>

紧接着,我们还得在src/main/resources目录下新建一个applicationContext.xml配置文件,它用于加载所有的Spring上下文。

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
	xmlns:context="http://www.springframework.org/schema/context"
	xmlns:aop="http://www.springframework.org/schema/aop" 
	xmlns:tx="http://www.springframework.org/schema/tx"
	xsi:schemaLocation="
		http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd 
		http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd 
		http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd 
		http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd ">
	
	<import resource="classpath:spring/applicationContext-dao.xml"/>
	<import resource="classpath:spring/applicationContext-service.xml"/>
	<import resource="classpath:spring/applicationContext-action.xml"/>
	
</beans>

最后,千万别忘了在web.xml配置文件中配置Struts2的核心过滤器以及Spring的核心监听器。

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns="http://java.sun.com/xml/ns/javaee"
	xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
	version="2.5">
	<display-name>crm-web</display-name>
	<!-- 
		配置Spring的核心监听器。
		ContextLoaderListener这个类实现了ServletContextListener接口,
		然后在初始化的时候,就创建了工厂(初始化web工厂),并且把这个工厂放入到了ServletContext里面。
		它默认加载的文件是"/WEB-INF/applicationContext.xml"(查看源码) 
	-->
	<listener>
		<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
	</listener>
	<!-- 用来加载Spring的配置文件的路径,默认加载的是/WEB-INF/applicationContext.xml -->
	<context-param>
		<param-name>contextConfigLocation</param-name>
		<param-value>classpath:applicationContext.xml</param-value>
	</context-param>
	
	<!-- 配置Struts2的核心过滤器 -->
	<filter>
		<filter-name>struts</filter-name>
		<filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
	</filter>
	<filter-mapping>
		<filter-name>struts</filter-name>
		<url-pattern>/*</url-pattern>
	</filter-mapping>
</web-app>

至此,crm-web子模块总算是开发完了。

运行调试

运行方式一

这种运行方式是指在crm-web子工程的pom.xml文件中配置tomcat插件运行。
在这里插入图片描述
温馨提示:如果子工程和父工程中都配置了tomcat插件,那么访问的端口和路径以子工程为准。

我草泥马的,运行时给我报错了,eclipse控制台打印出了如下错误提示信息。

[INFO] Scanning for projects...
[INFO] 
[INFO] -----------------------< com.meimeixia:crm-web >------------------------
[INFO] Building crm-web 0.0.1-SNAPSHOT
[INFO] --------------------------------[ war ]---------------------------------
[INFO] 
[INFO] >>> tomcat7-maven-plugin:2.2:run (default-cli) > process-classes @ crm-web >>>
[WARNING] The POM for com.meimeixia:crm-service:jar:0.0.1-SNAPSHOT is missing, no dependency information available
[INFO] ------------------------------------------------------------------------
[INFO] BUILD FAILURE
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  0.352 s
[INFO] Finished at: 2019-12-27T09:36:17+08:00
[INFO] ------------------------------------------------------------------------
[ERROR] Failed to execute goal on project crm-web: Could not resolve dependencies for project com.meimeixia:crm-web:war:0.0.1-SNAPSHOT: Could not find artifact com.meimeixia:crm-service:jar:0.0.1-SNAPSHOT -> [Help 1]
[ERROR] 
[ERROR] To see the full stack trace of the errors, re-run Maven with the -e switch.
[ERROR] Re-run Maven using the -X switch to enable full debug logging.
[ERROR] 
[ERROR] For more information about the errors and possible solutions, please read the following articles:
[ERROR] [Help 1] http://cwiki.apache.org/confluence/display/MAVEN/DependencyResolutionException

如何解决该问题呢?可以参考我的这篇文章——《maven快速入门番外篇——运行maven项目时报错:Failed to execute goal on project …》

有可能你在对父工程进行install时,会报如下图所示的错误。
在这里插入图片描述
至于怎么解决这个问题,同样可以参考我的这篇文章——《maven快速入门番外篇——安装maven项目时报错:No compiler is provided in this environment…》

再次通过crm-web子工程的pom.xml文件中配置的tomcat7插件来运行crm-web子工程,可以发现此时并不会报错,该子工程确实是部署到tomcat服务器上去了,并成功运行起来了,如下图所示。
在这里插入图片描述
紧接着,打开Google Chrome浏览器,访问http://localhost:8080/crm/customer_list这样的url地址,这时发现又又又他妈的报错了,详细的错误提示信息如下:

java.lang.IllegalStateException: Cannot convert value of type [com.sun.proxy.$Proxy51 implementing com.meimeixia.crm.service.ICustomerService,org.springframework.aop.SpringProxy,org.springframework.aop.framework.Advised] to required type [com.meimeixia.crm.service.impl.CustomerService] for property 'customerService': no matching editors or conversion strategy found
	org.springframework.beans.TypeConverterDelegate.convertIfNecessary(TypeConverterDelegate.java:302)
	org.springframework.beans.AbstractNestablePropertyAccessor.convertIfNecessary(AbstractNestablePropertyAccessor.java:576)
	org.springframework.beans.AbstractNestablePropertyAccessor.convertForProperty(AbstractNestablePropertyAccessor.java:603)
	org.springframework.beans.BeanWrapperImpl.convertForProperty(BeanWrapperImpl.java:204)
	org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.convertForProperty(AbstractAutowireCapableBeanFactory.java:1527)
	org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyPropertyValues(AbstractAutowireCapableBeanFactory.java:1486)
	org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1226)
	org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:543)
	org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:482)
	org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:325)
	org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197)
	org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1048)
	com.opensymphony.xwork2.spring.SpringObjectFactory.buildBean(SpringObjectFactory.java:161)
	com.opensymphony.xwork2.ObjectFactory.buildBean(ObjectFactory.java:178)
	com.opensymphony.xwork2.factory.DefaultActionFactory.buildAction(DefaultActionFactory.java:22)
	com.opensymphony.xwork2.ObjectFactory.buildAction(ObjectFactory.java:148)
	com.opensymphony.xwork2.DefaultActionInvocation.createAction(DefaultActionInvocation.java:295)
	com.opensymphony.xwork2.DefaultActionInvocation.init(DefaultActionInvocation.java:395)
	com.opensymphony.xwork2.DefaultActionProxy.prepare(DefaultActionProxy.java:194)
	org.apache.struts2.impl.StrutsActionProxy.prepare(StrutsActionProxy.java:63)
	org.apache.struts2.impl.StrutsActionProxyFactory.createActionProxy(StrutsActionProxyFactory.java:37)
	com.opensymphony.xwork2.DefaultActionProxyFactory.createActionProxy(DefaultActionProxyFactory.java:58)
	org.apache.struts2.dispatcher.Dispatcher.serviceAction(Dispatcher.java:554)
	org.apache.struts2.dispatcher.ng.ExecuteOperations.executeAction(ExecuteOperations.java:81)
	org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter.doFilter(StrutsPrepareAndExecuteFilter.java:99)

至于如何解决这个问题,可以参考我的这篇文章——《maven快速入门番外篇——使用maven整合SSH报错:java.lang.IllegalStateException: Cannot convert value of type…》

运行crm-web子工程时,它会从本地仓库下载所依赖的jar包,所以当crm-web子工程依赖的jar包内容修改了必须及时发布到本地仓库,比如:crm-web子工程依赖的crm-service子工程中的内容修改了,需要及时将crm-service子工程发布到本地仓库。
在这里插入图片描述
再次通过crm-web子工程的pom.xml文件中配置的tomcat7插件来运行该子工程,运行成功之后,通过Google Chrome浏览器访问http://localhost:8080/crm/customer_list这样的url地址,这时,你便会看到如下图所示的效果了,即查询出了所有客户信息。
在这里插入图片描述

运行方式二

在父工程的pom.xml文件中配置tomcat插件运行(自动聚合并执行)。父工程的作用就是将各个子工程聚合到一起。
在这里插入图片描述
至于如何运行父工程,不用我说了吧!但有一点需要注意,最后是将crm-web子工程打成了war包,并发布到了tomcat服务器上,最终运行的依然是crm-web子工程。

推荐使用这种运行方式,因为如果子工程都在本地,采用这种运行方式则不需要子工程修改就立即发布到本地仓库,父工程会自动聚合并使用最新代码执行。

运行方式三

将crm-web子工程部署到本地tomcat服务器上去运行。

  • 0
    点赞
  • 3
    评论
  • 2
    收藏
  • 一键三连
    一键三连
  • 扫一扫,分享海报

©️2021 CSDN 皮肤主题: 猿与汪的秘密 设计师:白松林 返回首页
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值