首页 > 代码库 > 002杰信-陌生的maven-web项目整改成我们熟悉的Web架构;classpath的含义;ssm框架的整合;junit测试
002杰信-陌生的maven-web项目整改成我们熟悉的Web架构;classpath的含义;ssm框架的整合;junit测试
这篇博客的资源来源于创智播客,先在此申明。这篇博客的出发点是jk项目,传智的做法是Maven的web模板生成的,但是这样子的结构目录与我们熟知的Web项目的结构目录相差很大,所以要按照我们熟知的项目结构来。这篇文章涉及到的最重要的是:1.加载各种配置文件时经常涉及到classpath,这个东西,要搞搞清楚,在web项目代表的是什么( WEB-INF文件夹下的classes目录
).2.还有就是做一个项目时,建包的目录,3.用junit去测试框架的整合。
传智的做法是Maven的web模板生成的:
我们要把上面那个结构给改过来:
第一步:和以前一样普通的建立一个web项目,要注意的是要勾选Add.....
.
第二步:建立下面的结构:
上面的结构中:注意WEB-INF里面内容是不能随意访问的(在web基础知识里讲过);
这个项目涉及到spring,springmvc,mybatis,maven,整合的项目。
上面的结构建立好之后就开始写代码:
1.先写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/maven-v4_0_0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>cn.itcast.jk</groupId> <artifactId>jk</artifactId> <packaging>war</packaging> <version>0.0.1-SNAPSHOT</version> <name>jk Maven Webapp</name> <url>http://maven.apache.org</url> <properties> <org.springframework.version>3.2.6.RELEASE</org.springframework.version> </properties> <dependencies> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>${org.springframework.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-orm</artifactId> <version>${org.springframework.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-test</artifactId> <version>${org.springframework.version}</version> <type>jar</type> <scope>test</scope> </dependency> <dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjweaver</artifactId> <version>1.7.2</version> </dependency> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>3.2.2</version> </dependency> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis-spring</artifactId> <version>1.2.0</version> </dependency> <dependency> <groupId>c3p0</groupId> <artifactId>c3p0</artifactId> <version>0.9.1.2</version> </dependency> <dependency> <groupId>com.oracle</groupId> <artifactId>ojdbc6</artifactId> <version>11.1.0.7.0</version> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.10</version> </dependency> <dependency> <groupId>org.apache.cxf</groupId> <artifactId>cxf-rt-frontend-jaxws</artifactId> <version>3.0.0-milestone2</version> </dependency> <dependency> <groupId>org.apache.cxf</groupId> <artifactId>cxf-rt-transports-http</artifactId> <version>3.0.0-milestone2</version> </dependency> <!-- Jetty is needed if you‘re using the CXFServlet --> <dependency> <groupId>org.apache.cxf</groupId> <artifactId>cxf-rt-transports-http-jetty</artifactId> <version>3.0.0-milestone2</version> </dependency> <dependency> <groupId>log4j</groupId> <artifactId>log4j</artifactId> <version>1.2.13</version> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-log4j12</artifactId> <version>1.7.5</version> </dependency> <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi</artifactId> <version>3.9</version> </dependency> <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi-ooxml</artifactId> <version>3.9</version> </dependency> <dependency> <groupId>jfree</groupId> <artifactId>jfreechart</artifactId> <version>1.0.13</version> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.9</version> </dependency> <dependency> <groupId>commons-fileupload</groupId> <artifactId>commons-fileupload</artifactId> <version>1.2.2</version> </dependency> <dependency> <groupId>commons-io</groupId> <artifactId>commons-io</artifactId> <version>2.0.1</version> </dependency> <dependency> <groupId>javax.servlet.jsp.jstl</groupId> <artifactId>jstl-api</artifactId> <version>1.2</version> </dependency> <dependency> <groupId>org.glassfish.web</groupId> <artifactId>jstl-impl</artifactId> <version>1.2</version> </dependency> <dependency> <groupId>jexcelapi</groupId> <artifactId>jxl</artifactId> <version>2.4.2</version> </dependency> <!-- 防止和tomcat中的jar冲突 --> <dependency> <groupId>org.apache.tomcat</groupId> <artifactId>servlet-api</artifactId> <version>6.0.33</version> <scope>provided</scope> </dependency> <dependency> <groupId>javax.servlet</groupId> <artifactId>servlet-api</artifactId> <version>2.5</version> <scope>provided</scope> </dependency> <dependency> <groupId>javax.servlet.jsp</groupId> <artifactId>jsp-api</artifactId> <version>2.1</version> <scope>provided</scope> </dependency> <dependency> <groupId>org.apache.geronimo.specs</groupId> <artifactId>geronimo-servlet_3.0_spec</artifactId> <version>1.0</version> <scope>provided</scope> </dependency> </dependencies> <build> <finalName>jk</finalName> </build></project>
这样的话用的jar包就是我电脑里面的仓库里面的jar包了。
2.写java代码:
下面的图片中的画红线的java代码如下:
BaseDao.java:
package cn.itcast.jk.dao;import java.io.Serializable;import java.util.List;import java.util.Map;import cn.itcast.jk.pagination.Page;/** * @Description: 泛型类,基础的DAO接口 * @Author: nutony * @Company: http://java.itcast.cn * @CreateDate: 2014-2-25 */public interface BaseDao<T> { public List<T> findPage(Page page); //分页查询 public List<T> find(Map paraMap); //带条件查询,条件可以为null,既没有条件;返回list对象集合 public T get(Serializable id); //只查询一个,常用于修改 public void insert(T entity); //插入,用实体作为参数 public void update(T entity); //修改,用实体作为参数 public void deleteById(Serializable id); //按id删除,删除一条;支持整数型和字符串类型ID public void delete(Serializable[] ids); //批量删除;支持整数型和字符串类型ID}
FactoryDao.java代码:
package cn.itcast.jk.dao;import cn.itcast.jk.domain.Factory;public interface FactoryDao extends BaseDao<Factory>{ }
BaseDaoImpl代码:
package cn.itcast.jk.dao.impl;import java.io.Serializable;import java.util.List;import java.util.Map;import org.apache.ibatis.session.SqlSessionFactory;import org.mybatis.spring.support.SqlSessionDaoSupport;import org.springframework.beans.factory.annotation.Autowired;import cn.itcast.jk.dao.BaseDao;import cn.itcast.jk.pagination.Page;public abstract class BaseDaoImpl<T> extends SqlSessionDaoSupport implements BaseDao<T>{ @Autowired //mybatis-spring 1.0无需此方法;mybatis-spring1.2必须注入。 public void setSqlSessionFactory(SqlSessionFactory sqlSessionFactory){ super.setSqlSessionFactory(sqlSessionFactory); } private String ns; //命名空间 public String getNs() { return ns; } public void setNs(String ns) { this.ns = ns; } public List<T> findPage(Page page){ List<T> oList = this.getSqlSession().selectList(ns + ".findPage", page); return oList; } public List<T> find(Map map) { List<T> oList = this.getSqlSession().selectList(ns + ".find", map); return oList; } public T get(Serializable id) { return this.getSqlSession().selectOne(ns + ".get", id); } public void insert(T entity) { this.getSqlSession().insert(ns + ".insert", entity); } public void update(T entity) { this.getSqlSession().update(ns + ".update", entity); } public void deleteById(Serializable id) { this.getSqlSession().delete(ns + ".deleteById", id); } public void delete(Serializable[] ids) { this.getSqlSession().delete(ns + ".delete", ids); }}
FactoryDaoImpl.java:
package cn.itcast.jk.dao.impl;import org.springframework.stereotype.Repository;import cn.itcast.jk.dao.FactoryDao;import cn.itcast.jk.domain.Factory;//这么做的话就是在beans.xml配置文件中扫描时就会把这个类加入到spring容器中@Repositorypublic class FactoryDaoImpl extends BaseDaoImpl<Factory> implements FactoryDao {/** * */public FactoryDaoImpl() {//设置命名空间super.setNs("cn.itcast.jk.mapper");}}
数据库po类:
用PowerDesign写出sql语句:
create table FACTORY_C ( FACTORY_ID VARCHAR(40) not null, FULL_NAME VARCHAR2(200), FACTORY_NAME VARCHAR2(50), CONTACTS VARCHAR2(30), PHONE VARCHAR2(20), MOBILE VARCHAR2(20), FAX VARCHAR2(20), CNOTE VARCHAR2(2000), INSPECTOR VARCHAR2(30), ORDER_NO INT, CREATE_BY VARCHAR2(40), CREATE_DEPT VARCHAR2(40), CREATE_TIME TIMESTAMP, constraint PK_FACTORY_C primary key (FACTORY_ID));
对应的po类:
package cn.itcast.jk.domain;import java.util.Date;import org.omg.CORBA.PRIVATE_MEMBER;public class Factory {private String id; private String fullName; private String factoryName; private String contacts; private String phone; private String mobile; private String fax; private String cnote; private String inspector; private Integer orderNo; private String createBy; private String createDept; private Date createTime; /** * @return the id */ public String getId() { return id; } /** * @param id the id to set */ public void setId(String id) { this.id = id; } /** * @return the fullName */ public String getFullName() { return fullName; } /** * @param fullName the fullName to set */ public void setFullName(String fullName) { this.fullName = fullName; } /** * @return the factoryName */ public String getFactoryName() { return factoryName; } /** * @param factoryName the factoryName to set */ public void setFactoryName(String factoryName) { this.factoryName = factoryName; } /** * @return the contacts */ public String getContacts() { return contacts; } /** * @param contacts the contacts to set */ public void setContacts(String contacts) { this.contacts = contacts; } /** * @return the phone */ public String getPhone() { return phone; } /** * @param phone the phone to set */ public void setPhone(String phone) { this.phone = phone; } /** * @return the mobile */ public String getMobile() { return mobile; } /** * @param mobile the mobile to set */ public void setMobile(String mobile) { this.mobile = mobile; } /** * @return the fax */ public String getFax() { return fax; } /** * @param fax the fax to set */ public void setFax(String fax) { this.fax = fax; } /** * @return the cnote */ public String getCnote() { return cnote; } /** * @param cnote the cnote to set */ public void setCnote(String cnote) { this.cnote = cnote; } /** * @return the inspector */ public String getInspector() { return inspector; } /** * @param inspector the inspector to set */ public void setInspector(String inspector) { this.inspector = inspector; } /** * @return the orderNo */ public Integer getOrderNo() { return orderNo; } /** * @param orderNo the orderNo to set */ public void setOrderNo(Integer orderNo) { this.orderNo = orderNo; } /** * @return the createBy */ public String getCreateBy() { return createBy; } /** * @param createBy the createBy to set */ public void setCreateBy(String createBy) { this.createBy = createBy; } /** * @return the createDept */ public String getCreateDept() { return createDept; } /** * @param createDept the createDept to set */ public void setCreateDept(String createDept) { this.createDept = createDept; } /** * @return the createTime */ public Date getCreateTime() { return createTime; } /** * @param createTime the createTime to set */ public void setCreateTime(Date createTime) { this.createTime = createTime; } }
FactoryService.java代码:
package cn.itcast.jk.service;import java.io.Serializable;import java.util.List;import java.util.Map;import cn.itcast.jk.domain.Factory;import cn.itcast.jk.pagination.Page;public interface FactoryService { public List<Factory> findPage(Page page); //分页查询 public List<Factory> find(Map paraMap); //带条件查询,条件可以为null,既没有条件;返回list对象集合 public Factory get(Serializable id); //只查询一个,常用于修改 public void insert(Factory factory); //插入,用实体作为参数 public void update(Factory factory); //修改,用实体作为参数 public void deleteById(Serializable id); //按id删除,删除一条;支持整数型和字符串类型ID public void delete(Serializable[] ids); //批量删除;支持整数型和字符串类型ID}
FactoryServiceImpl.java代码:
package cn.itcast.jk.service.impl;import java.io.Serializable;import java.util.List;import java.util.Map;import javax.annotation.Resource;import org.springframework.stereotype.Service;import cn.itcast.jk.dao.FactoryDao;import cn.itcast.jk.domain.Factory;import cn.itcast.jk.pagination.Page;import cn.itcast.jk.service.FactoryService;//这么做的话就是在beans.xml配置文件中扫描时就会把这个类加入到spring容器中。
//
@Servicepublic class FactoryServiceImpl implements FactoryService{ @Resource FactoryDao factoryDao; @Override public List<Factory> findPage(Page page) { return null; } @Override public List<Factory> find(Map paraMap) { return factoryDao.find(paraMap); } @Override public Factory get(Serializable id) { return null; } @Override public void insert(Factory factory) { } @Override public void update(Factory factory) { } @Override public void deleteById(Serializable id) { } @Override public void delete(Serializable[] ids) { }}
上面的代码写好之后:
3.开始写各种配置文件:要注意classpath在下面配置中的用法。
config目录下的各种文件如下:
jdbc.properties代码:
#jdbc.driverClassName=com.mysql.jdbc.Driver#jdbc.url=jdbc:mysql://localhost:3306/jkdb?characterEncoding=utf-8#jdbc.username=root#jdbc.password=rootjdbc.driverClassName=oracle.jdbc.driver.OracleDriverjdbc.url=jdbc:oracle:thin:@127.0.0.1:1521:XEjdbc.username=jkdbjdbc.password=1234c3p0.pool.maxPoolSize=20c3p0.pool.minPoolSize=5c3p0.pool.initialPoolSize=3c3p0.pool.acquireIncrement=2
FactoryMapper.xml代码:
<?xml version="1.0" encoding="UTF-8" ?><!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd"><mapper namespace="cn.itcast.jk.mapper"><!-- factory_c表的映射 --> <resultMap type="cn.itcast.jk.domain.Factory" id="factoryRM"> <id property="id" column="FACTORY_ID"/> <result property="fullName" column="FULL_NAME"/> <result property="factoryName" column="FACTORY_NAME"/> <result property="contacts" column="CONTACTS"/> <result property="phone" column="PHONE"/> <result property="mobile" column="MOBILE"/> <result property="fax" column="FAX"/> <result property="cnote" column="CNOTE"/> <result property="inspector" column="INSPECTOR"/> <result property="orderNo" column="ORDER_NO"/> <result property="createBy" column="CREATE_BY"/> <result property="createDept" column="CREATE_DEPT"/> <result property="createTime" column="CREATE_TIME"/> </resultMap> <select id="find" parameterType="map" resultMap="factoryRM"> select * from factory_c where 1=1 </select></mapper>
sqlMapperConfig.xml代码:
<?xml version="1.0" encoding="UTF-8" ?><!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd"><configuration> <!-- 把映射文件(sqlmap/user.xml)加载进sqlMapConfig.xml--> <mappers> <mapper resource="mybatis/FactoryMapper.xml"/> </mappers></configuration>
beans.xml代码:
<?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:mvc="http://www.springframework.org/schema/mvc" 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-3.0.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd "> <!-- 1.加载数据库配置的属性文件 --> <context:property-placeholder location="classpath:/jdbc/jdbc.properties"/> <!-- 2. 包扫描dao,service --> <context:component-scan base-package="cn.itcast.jk.dao,cn.itcast.jk.service"/> <!-- 3. 数据源dataSource C3P0 --> <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"> <property name="driverClass" value="${jdbc.driverClassName}"/> <property name="jdbcUrl" value="${jdbc.url}"/> <property name="user" value="${jdbc.username}"/> <property name="password" value="${jdbc.password}"/> <property name="maxPoolSize" value="${c3p0.pool.maxPoolSize}"/> <property name="minPoolSize" value="${c3p0.pool.minPoolSize}"/> <property name="initialPoolSize" value="${c3p0.pool.initialPoolSize}"/> <property name="acquireIncrement" value="${c3p0.pool.acquireIncrement}"/> </bean> <!-- 4. SessionFactory --> <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> <property name="dataSource" ref="dataSource"/> <!-- 整合mybatis,包扫描 mapper文件 --> <property name="configLocation" value="classpath:/mybatis/sqlMapConfig.xml"/> </bean> <!-- 5. 事务 --> <bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource"/> </bean> <tx:advice id="txAdvice" transaction-manager="txManager"> <tx:attributes> <tx:method name="insert*" propagation="REQUIRED"/> <tx:method name="update*" propagation="REQUIRED"/> <tx:method name="delete*" propagation="REQUIRED"/> <tx:method name="save*" propagation="REQUIRED"/> <tx:method name="find*" read-only="true"/> <tx:method name="get*" read-only="true"/> <tx:method name="view*" read-only="true"/> </tx:attributes> </tx:advice> <aop:config> <aop:pointcut expression="execution(* cn.itcast.jk.service.*.*(..))" id="txPointcut"/> <aop:advisor advice-ref="txAdvice" pointcut-ref="txPointcut"/> </aop:config> </beans>
springmvc-servlet.xml代码:
<?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:mvc="http://www.springframework.org/schema/mvc" 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-3.0.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd "> <!-- 1. 包扫描 controller --> <context:component-scan base-package="cn.itcast.jk.controller"/> <!-- 2. 内部资源视图解析器 --> <bean id="jspViewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="prefix" value="/WEB-INF/pages"/> <property name="suffix" value=""/> </bean> </beans>
这样一来就配置好了,我们用juint来做测试:
刚开始的时候,我这么测试:
结果一直报错:说是FactoryServiceImpl的bean加载有问题,就是所容器里面一直没有这个bean,那我就很奇怪,我在beans.xml中配置的是包扫描,把Dao和service包下面对都扫进去了,怎么会没有呢?答案是:FactoryServiceImpl不是接口,Spring里面有一条的规则就是用java本身的代理Api的话,必须是接口才能代理,所以只要改成如下就好了:
package test;import java.util.List;import org.junit.Test;import org.junit.runner.RunWith;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Repository;import org.springframework.test.context.ContextConfiguration;import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;import cn.itcast.jk.dao.FactoryDao;import cn.itcast.jk.dao.impl.BaseDaoImpl;import cn.itcast.jk.domain.Factory;import cn.itcast.jk.service.FactoryService;@RunWith(SpringJUnit4ClassRunner.class)@ContextConfiguration(locations="classpath:/spring/beans.xml")public class TestJdbc { /* *之前 *@Repository public class FactoryDaoImpl extends BaseDaoImpl<Factory> implements FactoryDao 那么就会把FactoryDaoImpl注册到spring容器中。那么下面的代码 @Autowired就会查找相应的类型, 就相当于 FactoryService factoryServiceImpl=new FactoryDaoImpl */ @Autowired private FactoryService factoryServiceImpl; @Test public void testService() { Factory factory=factoryServiceImpl.find(null).get(0); System.out.print(factory.getFullName()); System.out.print("aa"); } }
测试结果正确。
这里我想不通的是:在这里我们用到了junit,就是说不是web,还没有发布到Tomcat,那么classpath:/spring/beans.xml就不是 WEB-INF文件夹下的classes目录
啊。那么这个classpath:又代表什么呢.
---------------------------------------------------------------------------------------------------------------------------------------------------------
反正上面的junit测试通过了,就是说框架整合(Spring,mybatis)没问题了,现在测试web.下面重点讲,Tomcat发布后的目录结构:
发布后在Tomcat下:
在web下classpath:就是指WEB-INF文件夹下的classes目录。
如下:
都在这里了。
还有要注意的是:
红线圈出来的东西都是在:JkTest这里目录下的,所以啊,在后续的jsp页面中有这么一段话:
<%@ page language="java" pageEncoding="UTF-8"%><%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%><c:set var="ctx" value="http://www.mamicode.com/${pageContext.request.contextPath}"/><link rel="stylesheet" rev="stylesheet" type="text/css" href="http://www.mamicode.com/${ctx}/skin/default/css/default.css" media="all"/><script language="javascript" src="http://www.mamicode.com/${ctx}/js/common.js"></script>
${pageContext.request.contextPath}指的就是/JkTest
${ctx}/skin/default/css/default.css"的意思是:/JkTest/skin/default/css/default.css。这样就可以得到资源了。
发布测试:一切正常。
002杰信-陌生的maven-web项目整改成我们熟悉的Web架构;classpath的含义;ssm框架的整合;junit测试