ssh项目搭建
一. 新建数据库和web项目
01.新建web项目,配置jdk版本,配置tomcat服务器,构建数据库,指定项目编码(一般为utf-8)
02.添加 jstl.jar和 mysql驱动包
二.整合Struts框架
01.导入Struts的jar包:commons-fileupload-1.3.1.jar,commons-io-2.2.jar,
commons-lang-2.4.jar ,commons-lang3-3.2.jar,freemarker-2.3.19.jar,ognl-3.0.6.jar,
struts2-core-2.x.jar,struts2-spring-plugin-2.x.jar,xwork-core-2.x.jar 到web-inf/lib目录下。
02.添加struts.xml到src目录下。可在“struts-2.x\apps\struts2-blank\WEB-INF\classes”下复制。
在struts.xml中添加几个常用属性:
<!-- 禁用动态方法访问 -->
<constant name="struts.enable.DynamicMethodInvocation" value="false" />
<!-- 配置成开发模式 -->
<constant name="struts.devMode" value="true" />
<!-- 配置拓展名为action -->
<constant name="struts.action.extention" value="action" />
<!-- 把主题配置成simple -->
<constant name="struts.ui.theme" value="simple" />
配置web.xml: 添加struts过滤器:
<filter>
<filter-name>struts2</filter-name>
<filterclass>
org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter
</filter-class>
</filter>
<filter-mapping>
<filter-name>struts2</filter-name>
<url-pattern>*.action</url-pattern>
</filter-mapping>
三.添加hibernate的jar包和配置文件
01.添加hibernate jar包:
hibernate3.jar,lib/required/*.jar,lib\jpa\hibernate-jpa-2.0-api-1.0.0.Final.jar,lib\bytecode\cglib\cglib-2.2.jar到web-inf/lib目录下。
02.至于hibernate.cfg.xml文件,因项目使用spring来整合管理实体和数据库的连接等hibernate原本的工作,所以这个配置文件不再需要。
四.添加spring的jar包和配置文件
01.添加spring3.0.2中的jar包:
02.添加spring配置文件applicationContext.xml 到src目录下;
03.在web.xml中注册spring监听器,启动spring容器(监听器一般配置在过滤器前面):
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext.xml</param-value>
</context-param>
这样基本的导包和配置就完成了,接下来进行整理的项目测试
一.先测试spring容器是否能正常加载
预期,编写一个测试的service的方法,将其注入到spring容器,在control层可以正常调用service层中的方法,且spring容器可以正常加载。
流程: 写一个测试用的service方法 -> 注入到spring容器 -> 进行spring的扫描配置 -> 然后测试spring容器是否可以正常加载
TestService接口
package cn.itcast.test.service;
public interface TestService {
public void say();
}
TestServiceImpl.java
package cn.itcast.test.service.impl;
import org.springframework.stereotype.Service;
import cn.itcast.test.service.TestService;
@Service("testService")
// 使用注解,注入到spring容器,这里如果不写 testService,默认为testServiceImpl
public class TestServiceImpl implements TestService {
@Override
public void say() {
System.out.println("service saying hi.");
}
}
spring配置文件: 这里我们新建了conf包,新建了test-spring.xml进行配置,只需要在spring配置中加入下面这段配置。
<!-- 扫描service -->
<context:component-scan base-package="cn.itcast.test.service.impl"></context:component-
然后将这个配置文件导入总配置文件applicationContext.xml:
<!-- 引入外部spring配置文件,采用通配符的方式 -->
<import resource="classpath:cn/itcast/*/conf/*-spring.xml"/>
测试类:
package cn.itcast.test;
import org.junit.Test;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import cn.itcast.test.service.TestService;
public class TestMerge {
@Test
public void testSpring() {
// 测试spring容器是否可以正常加载
ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext(
"applicationContext.xml");
// 找到testService的bean
TestService ts = (TestService) ctx.getBean("testService");//这里的testService是用注解注入
// 测试方法是否可以正常调用
ts.say();
}
}
测试结果:service saying hi. — 说明spring容器加载成功。
二.测试struts和spring的整合是否成功
流程: 编写controller层方法调用service层 -> 配置struts配置文件test-struts.xml -> 在总配置文件中引入test-struts.xml -> 编写一个测试用的jsp页面 -> 启动服务器,通过浏览器进行访问 -> 页面显示正确,后台打印正确,即为整合成功。
项目结构图:
编写TestAction类
package cn.itcast.test.action;
import javax.annotation.Resource;
import cn.itcast.test.service.TestService;
import com.opensymphony.xwork2.ActionSupport;
public class TestAction extends ActionSupport {
@Resource
TestService testService;
public String execute() {
testService.say();
return SUCCESS;
}
}
配置test-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="test-action" namespace="/" extends="struts-default">
<action name="test_*" class="cn.itcast.test.action.TestAction" method="{1}">
<result name="success">/WEB-INF/jsp/test/test.jsp</result>
</action>
</package>
</struts>
将test-struts.xml导入到struts.xml文件中
<include file="cn/itcast/test/conf/test-struts.xml"/>
测试: 在浏览器中输入网址:http://localhost:8080/itcastTax0815/test.action,查看后台打印是否正确。
如果报错,一般是struts文件配置错误,或者未引入到总配置文件,或者未注入service。
三.测试hibernate和spring的整合是否成功
流程: 将原本在hibernate.cfg.xml中需要配置的信息配置在applicationContext.xml中 -》 创建实体类Person,并进行数据库映射(这里采用配置文件的形式,也可以使用注解) -》 编写dao、service层代码 -》 进行 save 和 find方法测试 -》 进行事务配置(这里采用申明式配置,也可以使用插入事务代码或者事务注解的方法) - 》 然后测试事务配置
一.将原本在hibernate.cfg.xml中需要配置的信息配置在applicationContext.xml中
01配置c3p0数据库连接源:
<!-- 导入外部的properties配置文件 -->
<context:property-placeholder location="classpath:db.properties" />
<!-- 配置c3p0数据源 -->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">
<property name="jdbcUrl" value="${jdbcUrl}"></property>
<property name="driverClass" value="${driverClass}"></property>
<property name="user" value="${user}"></property>
<property name="password" value="${password}"></property>
<!--初始化时获取三个连接,取值应在minPoolSize与maxPoolSize之间。Default: 3 -->
<property name="initialPoolSize" value="${initialPoolSize}"></property>
<!--连接池中保留的最小连接数。Default: 3 -->
<property name="minPoolSize" value="3"></property>
<!--连接池中保留的最大连接数。Default: 15 -->
<property name="maxPoolSize" value="${maxPoolSize}"></property>
<!--当连接池中的连接耗尽的时候c3p0一次同时获取的连接数。Default: 3 -->
<property name="acquireIncrement" value="3"></property>
<!--最大空闲时间,1800秒内未使用则连接被丢弃,若为0则永不丢弃。Default: 0 -->
<property name="maxIdleTime" value="1800"></property>
</bean>
02.db.properties
jdbcUrl=jdbc:mysql://localhost:3306/itcastTax_0406?useUnicode=true&characterEncoding=utf8
driverClass=com.mysql.jdbc.Driver
user=root
password=root
initialPoolSize=10
maxPoolSize=30
03.配置sessionFactory,并将dataSource指向c3p0创建的dataSource:
<bean id="sessionFactory"
class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource"></property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</prop>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.hbm2ddl.auto">update</prop>
<prop key="javax.persistence.validation.mode">none</prop>
</props>
</property>
<property name="mappingLocations">
<list>
<value>classpath:cn/itcast/nsfw/*/entity/*.hbm.xml</value>
<value>classpath:cn/itcast/test/entity/*.hbm.xml</value>
</list>
</property>
</bean>
二.创建实体类Person,并进行数据库映射(这里采用配置文件的形式,也可以使用注解)
package cn.itcast.test.entity;
import java.io.Serializable;
public class Person implements Serializable {
private String id;
private String name;
public Person() {
}
public Person(String id, String name) {
this.id = id;
this.name = name;
}
public Person(String name) {
this.name = name;
}
}
Person.hbm.xml
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="cn.itcast.test.entity.Person" table="person">
<id name="id" type="java.lang.String">
<column name="id" length="32" />
<generator class="uuid.hex" />
</id>
<property name="name" type="java.lang.String">
<column name="name" length="20" not-null="true" />
</property>
</class>
</hibernate-mapping>
然后编写dao、service层的save()、findById()方法进行测试
TestDaoImpl.java
package cn.itcast.test.dao.impl;
import java.io.Serializable;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;
import cn.itcast.test.dao.TestDao;
import cn.itcast.test.entity.Person;
public class TestDaoImpl extends HibernateDaoSupport implements TestDao {
@Override
public void save(Person person) {
getHibernateTemplate().save(person);
}
@Override
public Person findPerson(Serializable id) {
return getHibernateTemplate().get(Person.class, id);
}
}
配置: 将sessionFactory注入到TestDaoImpl中。将下面代码加入到test-spring.xml中。
<bean id="testDao" class="cn.itcast.test.dao.impl.TestDaoImpl">
<property name="sessionFactory" ref="sessionFactory"></property>
</bean>
TestServiceImpl.java
package cn.itcast.test.service.impl;
import java.io.Serializable;
import javax.annotation.Resource;
import org.springframework.stereotype.Service;
import cn.itcast.test.dao.TestDao;
import cn.itcast.test.entity.Person;
import cn.itcast.test.service.TestService;
@Service("testService")
// 使用注解,注入到spring容器
public class TestServiceImpl implements TestService {
@Resource
TestDao testDao;
@Override
public void say() {
System.out.println("service saying hi.");
}
@Override
public void save(Person person) {
testDao.save(person);
}
@Override
public Person findPerson(Serializable id) {
return testDao.findPerson(id);
}
}
测试方法:TestMerge.java
@Test
public void testServiceAndDao() {
TestService ts = (TestService) ctx.getBean("testService");
// ts.save(new Person("人员2"));
Person person = ts.findPerson("402883bf5de4ba82015de4ba83000000");
System.out.println("name = " + person.getName());
}
三.进行事务配置
<!—事务管理-->
<bean id="txManager"
class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
<!—事务通知-->
<tx:advice id="txAdvice" transaction-manager="txManager">
<tx:attributes>
<tx:method name="find*" read-only="true" />
<tx:method name="get*" read-only="true" />
<tx:method name="load*" read-only="true" />
<tx:method name="list*" read-only="true" />
<tx:method name="search*" read-only="true" />
<tx:method name="*" rollback-for="Throwable" />
</tx:attributes>
</tx:advice>
<!—配置需要进行事务控制的类 -->
<aop:config>
<aop:pointcut id="serviceOperation" expression="bean(*Service)" />
<aop:advisor advice-ref="txAdvice" pointcut-ref="serviceOperation" />
</aop:config>
【注意:上面的pointcut expression 表示拦截以Service结尾的bean,或者可写成
execution(* cn.itcast..service.impl..(..))】
完善 TestService接口和TestServiceImpl;利用service中的操作来验证上面配置的事务管理是否生效。
注:自行进行只读测试,回滚测试。
五、资源文件夹分类
创建 test 和 config 源文件夹 、 创建不同种类的资源文件夹
项目结构: (注:test和config为source folder)
六、日志工具配置
流程: 导入日志 jar包 -> 配置log4j.properties文件 -> 进行测试
导入jar包:Slf4j 接口jar(slf4j-log4j12-1.6.1.jar) ,log4j的jar包(com.springsource.org.apache.log4j-1.2.15)
配置log4j.properties文件:
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target=System.out
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d{ABSOLUTE} %5p [%t] %c{1}:%L - %m%n
log4j.rootLogger=warn, stdout, R
log4j.logger.cn.itcast=debug
log4j.appender.R=org.apache.log4j.DailyRollingFileAppender
log4j.appender.R.File=D:/itcast/itcast.log
log4j.appender.R.layout=org.apache.log4j.PatternLayout
log4j.appender.R.layout.ConversionPattern=%d [%t] %5p %c - %m%n
七、编写dao层基类BaseDao – 这里用到的反射
BaseDao接口:
package cn.itcast.core.dao;
import java.io.Serializable;
import java.util.List;
public interface BaseDao<T> {
// 新增
public void save(T entity);
// 更新
public void update(T entity);
// 根据id删除
public void delete(Serializable id);
// 根据id查找
public T findObjectById(Serializable id);
// 查找列表
public List<T> findObjects();
}
BaseDao实现类:
package cn.itcast.core.dao.impl;
import java.io.Serializable;
import java.lang.reflect.ParameterizedType;
import java.util.List;
import org.hibernate.Query;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;
import cn.itcast.core.dao.BaseDao;
public abstract class BaseDaoImpl<T> extends HibernateDaoSupport implements BaseDao<T> {
Class<T> clazz;
public BaseDaoImpl() {
ParameterizedType pt = (ParameterizedType) this.getClass()
.getGenericSuperclass();// 相当于获取到了BaseDaoImpl<User>
clazz = (Class<T>) pt.getActualTypeArguments()[0];// 相当于获取到了User
}
@Override
public void save(T entity) {
getHibernateTemplate().save(entity);
}
@Override
public void update(T entity) {
getHibernateTemplate().update(entity);
}
@Override
public void delete(Serializable id) {
getHibernateTemplate().delete(findObjectById(id));
}
@Override
public T findObjectById(Serializable id) {
return getHibernateTemplate().get(clazz, id);
}
@Override
public List<T> findObjects() {
Query query = getSession().createQuery("FROM " + clazz.getSimpleName());
return query.list();
}
}