最近做BOS物流管理系统的时候,需要CRM项目提供WebService
CRM项目所用技术为:
- spring+struct2+springData(hibernate整合)
- 分布式技术为CXF-RS 实现多系统之间的通信
CRM项目的初始化
因为BOS项目与CRM项目都需要用到Customer实体类,因此将CRM_domain独立出来
pom文件的依赖
<dependency>
<!--CXF-rs依赖包-->
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-frontend-jaxrs</artifactId>
<version>${cxf.version}</version>
</dependency>
<!--CXF-rs客户端-->
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-rs-client</artifactId>
<version>${cxf.version}</version>
</dependency>
<!--CXF-rs扩展json提供者-->
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-rs-extension-providers</artifactId>
<version>${cxf.version}</version>
</dependency>
<!--转换json依赖-->
<dependency>
<groupId>org.codehaus.jettison</groupId>
<artifactId>jettison</artifactId>
<version>1.3.7</version>
</dependency>
CRM实体类的配置
@Entity
@Table(name = "T_CUSTOMER")
@XmlRootElement(name = "customer")
public class Customer {
@Id
@GeneratedValue()
@Column(name = "C_ID")
private Integer id; // 主键id
@Column(name = "C_USERNAME")
private String username; // 用户名
@Column(name = "C_PASSWORD")
private String password; // 密码
@Column(name = "C_TYPE")
private Integer type; // 类型 设置1 绑定邮箱
@Column(name = "C_BRITHDAY")
@Temporal(TemporalType.DATE)
private Date birthday; // 生日
@Column(name = "C_SEX")
private Integer sex; // 性别 1男 2女
@Column(name = "C_TELEPHONE")
private String telephone; // 手机
@Column(name = "C_COMPANY")
private String company; // 公司
@Column(name = "C_DEPARTMENT")
private String department; // 部门
@Column(name = "C_POSITION")
private String position; // 职位
@Column(name = "C_ADDRESS")
private String address; // 地址
@Column(name = "C_MOBILEPHONE")
private String mobilePhone; // 座机
@Column(name = "C_EMAIL")
private String email; // 邮箱
@Column(name = "C_Fixed_AREA_ID")
private String fixedAreaId; // 定区编码
CRM服务类的配置
- web.xml的配置
<!-- spring配置文件位置 -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext*.xml</param-value>
</context-param>
<!-- spring核心监听器 -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!-- 配置webService服务 -->
<servlet>
<servlet-name>CXFService</servlet-name>
<servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>CXFService</servlet-name>
<url-pattern>/services/*</url-pattern>
</servlet-mapping>
- applicationContext的配置
数据源的配置
<!-- 连接池配置 -->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="jdbcUrl" value="${jdbc.url}" />
<property name="driverClass" value="${jdbc.driver}" />
<property name="user" value="${jdbc.user}" />
<property name="password" value="${jdbc.password}" />
<!--初始化时获取的连接数,取值应在minPoolSize与maxPoolSize之间。Default: 3 -->
<property name="initialPoolSize" value="1" />
<!--连接池中保留的最小连接数。 -->
<property name="minPoolSize" value="1" />
<!--连接池中保留的最大连接数。Default: 15 -->
<property name="maxPoolSize" value="100" />
<!--最大空闲时间,60秒内未使用则连接被丢弃。若为0则永不丢弃。Default: 0 -->
<property name="maxIdleTime" value="60" />
<!--当连接池中的连接耗尽的时候c3p0一次同时获取的连接数。Default: 3 -->
<property name="acquireIncrement" value="5" />
<!--每60秒检查所有连接池中的空闲连接。Default: 0 -->
<property name="idleConnectionTestPeriod" value="60" />
</bean>
<!-- spring 整合 JPA配置 -->
<bean id="entityManagerFactory"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<!-- 连接池 -->
<property name="dataSource" ref="dataSource" />
<!-- 加载jpa注解类 -->
<property name="packagesToScan">
<list>
<value>cn.lzh.crm.domain</value>
</list>
</property>
<!-- JPA方言 如果配置了jpaVendorAdapter,这项可以不配置 <property name="jpaDialect"> <bean
class="org.springframework.orm.jpa.vendor.HibernateJpaDialect" /> </property> -->
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<!-- 数据库类型 -->
<property name="database" value="ORACLE" />
<!-- hibernate方言 -->
<property name="databasePlatform" value="org.hibernate.dialect.Oracle10gDialect" />
<!-- 自动建表 -->
<property name="generateDdl" value="true" />
<!-- 控制台打印SQL语句 -->
<property name="showSql" value="true" />
</bean>
</property>
<!-- jpa使用hibernate实现 -->
<property name="persistenceProvider">
<bean class="org.hibernate.ejb.HibernatePersistence"></bean>
</property>
</bean>
<jpa:repositories base-package="cn.lzh.crm.dao" transaction-manager-ref="transactionManager" entity-manager-factory-ref="entityManagerFactory" />
<!-- 事务管理 -->
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>
<!-- 开启注解事务 -->
<tx:annotation-driven transaction-manager="transactionManager" proxy-target-class="true" />
webservice的配置
<jaxrs:server id="customerService" address="/customerService">
<jaxrs:serviceBeans>
<bean class="cn.lzh.crm.service.impl.CustomerServiceImpl"></bean>
</jaxrs:serviceBeans>
</jaxrs:server>
- Customer服务的配置
Customer接口的配置
//查询所有未关联客户列表
@Path("/noassociationcustomers")
@GET
@Produces({"application/xml","application/json"})
public List<Customer> findNoAssociationCustomers();
//查询关联到指定定区的客户列表
@Path("/associationfixedreacustomers/{fixedareaId}")
@GET
@Produces({"application/xml","application/json"})
public List<Customer> findHashAssociationFixedAreaCustomers(@PathParam("fixedareaId")String fixedAreaId);
//将客户关联到定区上,将所有客户id拼成字符串1,2,3
@Path("/associationcustomerstofixedarea/")
@PUT//修改操作
public void associationCustomersTodixedArea(@QueryParam("customerIdStr")String customerIdStr,@QueryParam("fixedAreaId")String fixedAreaId);
Customer实现类的配置
@Service
@Transactional
public class CustomerServiceImpl implements CustomerService{
//注册Dao对象
@Autowired
private CustomerRepository customerRepository;
//调用dao层查询未关联定区id的客户列表
@Override
public List<Customer> findNoAssociationCustomers() {
//fixAreaID is null
return customerRepository.findByFixedAreaIdIsNull();
}
//调用dao层查询已关联定区id的客户列表
@Override
public List<Customer> findHashAssociationFixedAreaCustomers(String fixedAreaId) {
// TODO fixAreaID is
return customerRepository.findByFixedAreaId(fixedAreaId);
}
//调用dao层修改客户表的定区编号
@Override
public void associationCustomersTodixedArea(String customerIdStr, String fixedAreaId) {
// TODO Auto-generated method stub
//切割字符串1,2,3
String[] customerIdArray = customerIdStr.split(",");
for (String idStr : customerIdArray) {
Integer id = Integer.parseInt(idStr);
//update操作
customerRepository.updateFixedAreaId(fixedAreaId,id);
}
}
4.Dao接口的设置
//查找未关联定区的客户,springdata 的规则
public List<Customer> findByFixedAreaIdIsNull();
//查找已关联定区的客户
public List<Customer> findByFixedAreaId(String fixedAreaId);
//将客户关联定区,即修改客户表的定区id
@Query("update Customer set fixedAreaId = ? where id = ?")
@Modifying
public void updateFixedAreaId(String fixedAreaId, Integer id);
Dao接口要实现JpaRepository<Customer, Integer>接口
Juite单元测试
@Autowired
private CustomerService customerService;
//测试客户没有关联定区数据
@Test
public void testFindNoAssociationCustomers() {
System.out.println(customerService.findNoAssociationCustomers());
}
//测试客户已关联定区
@Test
public void testFindHashAssociationFixedAreaCustomers() {
System.out.println(customerService.findHashAssociationFixedAreaCustomers("dq001"));
}
//测试定区关联用户,即修改用户的定区ID
@Test
public void testAssociationCustomersTodixedArea() {
customerService.associationCustomersTodixedArea("1,2", "dq001");
}
发布WebService服务
容易出错的地方
原因
没有加@XmlRootElement 注解