使用IDEA和Maven整合SSH
SSH介绍
ssh是struts2、spring以及hibernate框架的整合,最近选秀了web高级开发技术这门课,主要内容讲的就是ssh的使用和整合。
暑假的时候自己学了ssm框架(即springmvc+spring+mybatis),这两个是目前主流的框架,个人还是觉得ssm顺手一些,不过为了拿到课程学分,还是要研究一下ssh,技多不压身嘛,于是花了一晚上的时间整合了一下ssh,踩了几处坑,下面详细介绍下整合过程。
开发工具
- 集成环境开发工具:IDEA,个人还是比较喜欢这个好东西;
- 项目管理:Maven,用它来管理项目,管理jar包,非常方便;
- 数据库:Mysql,不用说,最近也在学SQLserver数据库;
- 服务器:Tomcat8.5;
- 平台:Mac OS,最近换了Mac,最开发简直爽到爆。
关于以上工具的安装,就不再详述了,google一大把,都可以直接去官网下载安装,如果是mac也可以用brew下载安装,更加方便!!!
整合SSH
一、准备数据库
因为整合了hibernate持久层框架,所以需要建立一个测试数据库来进行项目测试,我这里就直接用了我之前项目里面的数据库,就不再重新建立了:
建立数据库,取名student
,里面有一张table-admin
,存储了几个管理员信息:
二、创建项目
1、使用maven快速创建web工程
配置完成之后,点击NEXT:
配置groupId等信息,这些信息用能区别不同的应用,是webapp的坐标信息:
配置Maven:
继续NEXT–FINISH之后,就是一下初始界面和项目目录结构,我们选择允许自动导入jar包:
接下来我们手动增加几个资源目录,在src/main
下新建java
、resources
文件夹,并设置为Source目录,java
用来存放java源文件,resource
用来存放项目配置文件:
resource
资源目录的设置方法一样,项目中如果需要单元测试,还需要新建test,方法类似,详询百度google。
2、建包,创建配置文件模版
2.1 在src/main/java下新建club.gongsir包,再在gongsir下分别建立model、dao、service以及action包:
- model:存放实体pojo或者entity类;
- dao:存放dao文件以及impl;
- service:服务层代码;
- action:控制层代码。
2.2 在src/main/resource下新建jdbc.properties、spring.xml、以及struts.xml文件:
- jdbc.properties:数据库链接配置文件,包含driverClass、url、username、password等基本属性;
- spring.xml:ssh中利用spring容器对项目以及事务进行管理,属于核心配置文件,新建该文件的方法:在
resource
下右键–New–XML-Configure-File–Spring:
- struts.xml:struts2框架的核心配置文件,可以配置控制层action的管理。新建方法和spring配置文件一样,在
resource
下右键–New–XML-Configure-File–Struts。
3、引入项目所需jar文件
编辑项目下的pom.xml
文件,通过Maven引入jar包:
<?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/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>club.gongsir</groupId>
<artifactId>ssh</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>war</packaging>
<name>ssh Maven Webapp</name>
<!-- FIXME change it to the project's website -->
<url>http://www.example.com</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.7</maven.compiler.source>
<maven.compiler.target>1.7</maven.compiler.target>
<spring.version>5.0.2.RELEASE</spring.version>
</properties>
<dependencies>
<dependency>
<!-- 单元测试-->
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
<!-- hibernate-->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>5.2.12.Final</version>
</dependency>
<!-- struts2-->
<dependency>
<groupId>org.apache.struts</groupId>
<artifactId>struts2-core</artifactId>
<version>2.5.14.1</version>
</dependency>
<!-- struts2-spring整合-->
<dependency>
<groupId>org.apache.struts</groupId>
<artifactId>struts2-spring-plugin</artifactId>
<version>2.5.14.1</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</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-expression</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-orm</artifactId>
<version>${spring.version}</version>
</dependency>
<!--spring aop包 注释方式使用事务管理 可以不引用-->
<dependency>
<groupId>aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>1.5.0</version>
</dependency>
<dependency>
<groupId>aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.5.0</version>
</dependency>
<!-- 添加对数据库的支持 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.0.5</version>
</dependency>
<!--c3p0数据库连接池 -->
<dependency>
<groupId>c3p0</groupId>
<artifactId>c3p0</artifactId>
<version>0.9.1.2</version>
</dependency>
</dependencies>
<build>
<finalName>ssh</finalName>
<pluginManagement><!-- lock down plugins versions to avoid using Maven defaults (may be moved to parent pom) -->
<plugins>
<plugin>
<artifactId>maven-clean-plugin</artifactId>
<version>3.1.0</version>
</plugin>
<!-- see http://maven.apache.org/ref/current/maven-core/default-bindings.html#Plugin_bindings_for_war_packaging -->
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<version>3.0.2</version>
</plugin>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.0</version>
</plugin>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.22.1</version>
</plugin>
<plugin>
<artifactId>maven-war-plugin</artifactId>
<version>3.2.2</version>
</plugin>
<plugin>
<artifactId>maven-install-plugin</artifactId>
<version>2.5.2</version>
</plugin>
<plugin>
<artifactId>maven-deploy-plugin</artifactId>
<version>2.8.2</version>
</plugin>
</plugins>
</pluginManagement>
</build>
</project>
4、编写配置文件
1、在web.xml下配置struts2的前端控制器,编写webapp/WEB-INF/web.xml:
<!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>
<display-name>ssh</display-name>
<!-- 指定spring的配置文件-->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring.xml</param-value>
</context-param>
<!-- 配置struts2的前端拦截-->
<filter>
<filter-name>struts2</filter-name>
<filter-class>org.apache.struts2.dispatcher.filter.StrutsPrepareAndExecuteFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>struts2</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!-- 监听-->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
</web-app>
2、配置spring的核心配置文件spring.xml,配置文件中扫描,注入各个javaBean,并且管理了hibernate的数据源和事务:
jdbc配置文件 jdbc.properties:
mysql.driverClassName = com.mysql.jdbc.Driver
mysql.url = jdbc:mysql://www.gongsir.club:3306/student?useUnicode=true&characterEncoding=utf-8
mysql.username = username
mysql.password = password
spring.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:context="http://www.springframework.org/schema/context" 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/tx http://www.springframework.org/schema/tx/spring-tx.xsd">
<!-- 自动扫描-->
<context:component-scan base-package="club.gongsir.dao"/>
<context:component-scan base-package="club.gongsir.service"/>
<context:component-scan base-package="club.gongsir.action"/>
<!-- 读取jdbc配置文件-->
<bean id="configurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="location" value="classpath:jdbs.properties"/>
</bean>
<!-- 配置c3p0数据源-->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="${mysql.driverClassName}"/>
<property name="jdbcUrl" value="${mysql.url}"/>
<property name="user" value="${mysql.username}"/>
<property name="password" value="${mysql.password}"/>
<property name="maxPoolSize" value="50"/>
<property name="minPoolSize" value="5"/>
<property name="initialPoolSize" value="5"/>
</bean>
<!-- hibernate管理-->
<bean id="sessionFactory" class="org.springframework.orm.hibernate5.LocalSessionFactoryBean">
<!-- 引用上文配置的数据源-->
<property name="dataSource" ref="dataSource"/>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</prop>
<prop key="hibernate.autoReconnect">true</prop>
<prop key="hibernate.connection.autocommit">true</prop>
<prop key="hibernate.hbm2ddl.auto">update</prop>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.format_sql">true</prop>
<prop key="max_fetch_depth">3</prop>
<prop key="hibernate.connection.url">jdbc:mysql://www.gongsir.club:3306/student</prop>
<prop key="hibernate.connection.driver_class">com.mysql.cj.jdbc.Driver</prop>
<!-- 解决session关闭问题 -->
<prop key="hibernate.enable_lazy_load_no_trans">true</prop>
</props>
</property>
<!-- 包扫描的方式加载注解类 -->
<property name="packagesToScan">
<list>
<value>club.gongsir.model</value>
</list>
</property>
<property name="mappingLocations">
<list>
<value>classpath:club/gongsir/model/Admin.hbm.xml</value>
</list>
</property>
</bean>
<!-- 用注解来实现事务管理-->
<bean id="transactionManager" class="org.springframework.orm.hibernate5.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory"/>
</bean>
<tx:annotation-driven transaction-manager="transactionManager"/>
</beans>
3、配置struts2的核心配置文件struts.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.5//EN"
"http://struts.apache.org/dtds/struts-2.5.dtd">
<struts>
<!-- 修改常量管理struts 中的action的工程,这个常量的使用,必须引入 spring和struts的整合包,不然spring无法管理struts2 Action 中的实体类-->
<constant name="struts.objectFactory" value="spring" />
<package name="admin" extends="struts-default" namespace="/">
<action name="admin_*" class="adminAction" method="{1}">
<result name="success">/test.jsp</result>
<!-- struts 2.5 之后,使用通配符必须加上这一行 ,否则无法使用通配符访问-->
<allowed-methods>login,add</allowed-methods>
</action>
</package>
</struts>
三、开发项目(coding)
1、利用IDEA生成数据库对应实体类和hibernate的映射文件完成model层的开发
1.1 链接数据库,点击idea右侧的DATABASE,添加MySQL链接,配置数据库相关链接并测试链接,点击应用,ok:
1.2 使用IDEA的Persistence创建实体类:
选择数据库–>选择实体类存放的包–>选择要生成实体类的数据表–>ok:
注意:
如果IDEA找不到Persistence窗口,可以在models里面添加hibernate,之后就可以看到它了,详见:IDEA找不到Persistence视图
Admin实体类:自动生成的代码
package club.gongsir.model;
import javax.persistence.Basic;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
@Entity
public class Admin {
private String admId;
private String admPass;
private String admName;
@Id
@Column(name = "admId")
public String getAdmId() {
return admId;
}
public void setAdmId(String admId) {
this.admId = admId;
}
@Basic
@Column(name = "admPass")
public String getAdmPass() {
return admPass;
}
public void setAdmPass(String admPass) {
this.admPass = admPass;
}
@Basic
@Column(name = "admName")
public String getAdmName() {
return admName;
}
public void setAdmName(String admName) {
this.admName = admName;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Admin admin = (Admin) o;
if (admId != null ? !admId.equals(admin.admId) : admin.admId != null) return false;
if (admPass != null ? !admPass.equals(admin.admPass) : admin.admPass != null) return false;
if (admName != null ? !admName.equals(admin.admName) : admin.admName != null) return false;
return true;
}
@Override
public int hashCode() {
int result = admId != null ? admId.hashCode() : 0;
result = 31 * result + (admPass != null ? admPass.hashCode() : 0);
result = 31 * result + (admName != null ? admName.hashCode() : 0);
return result;
}
}
club/gongsir/model/Admin.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="club.gongsir.model.Admin" table="admin" schema="student">
<id name="admId" column="admId"/>
<property name="admPass" column="admPass"/>
<property name="admName" column="admName"/>
</class>
</hibernate-mapping>
注意:
这里用Persistence自动生成代码之前,数据表必须要设置主键,否则xml文件会报错
2、mvc-dao层开发
在dao包下新建AdminDao.java(接口:interface):
package club.gongsir.dao;
import club.gongsir.model.Admin;
public interface AdminDao {
Admin getAdmin(String id);
void saveAdmin(Admin admin);
}
实现类:AdminDaoImpl.java:
package club.gongsir.dao.impl;
import club.gongsir.dao.AdminDao;
import club.gongsir.model.Admin;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.springframework.stereotype.Repository;
import javax.annotation.Resource;
@Repository("adminDao")
public class AdminDaoImpl implements AdminDao {
// spring注入
@Resource(name = "sessionFactory")
private SessionFactory sessionFactory;
@Override
public Admin getAdmin(String id) {
// 使用getCurrentSession获取session
Session session = sessionFactory.getCurrentSession();
Admin admin = session.get(Admin.class,id);
return admin;
}
@Override
public void saveAdmin(Admin admin) {
Session session = sessionFactory.getCurrentSession();
session.save(admin);
System.out.println("admin信息:"+admin.getAdmName());
}
}
3、mvc-service层开发
在service包下新建AdminService.java(接口:interface):
package club.gongsir.service;
import club.gongsir.model.Admin;
public interface AdminService {
Admin getAdmin(String id);
void saveAdmin(Admin admin);
}
实现类:AdminServiceImpl.java:
package club.gongsir.service.impl;
import club.gongsir.dao.AdminDao;
import club.gongsir.model.Admin;
import club.gongsir.service.AdminService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource;
@Service("adminService")
public class AdminServiceImpl implements AdminService {
//注入dao
@Resource
private AdminDao adminDao;
//注入事务管理
@Transactional(rollbackFor = {Exception.class,RuntimeException.class})
@Override
public Admin getAdmin(String id) {
return adminDao.getAdmin(id);
}
//在dao层使用了getCurrentSession创建session,则必须加入事务管理,否则会出错
@Transactional(rollbackFor = {Exception.class,RuntimeException.class})
@Override
public void saveAdmin(Admin admin) {
adminDao.saveAdmin(admin);
}
}
4、mvc-action层开发
在action包下新建AdminAction.java:
package club.gongsir.action;
import club.gongsir.model.Admin;
import club.gongsir.service.AdminService;
import com.opensymphony.xwork2.ActionSupport;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Controller;
import javax.annotation.Resource;
@Controller("adminAction")
@Scope("prototype")
public class AdminAction extends ActionSupport {
public Admin getAdmin() {
return admin;
}
private Admin admin;
//注入bean
@Resource
private AdminService adminService;
//login方法,对应struts.xml的action配置
public String login(){
admin = adminService.getAdmin("201731061426");
System.out.println(admin.getAdmName());
//返回结果,对应struts.xml文件的result配置
return SUCCESS;
}
public String add(){
Admin admin = new Admin();
admin.setAdmId("ssh");
admin.setAdmName("ssh测试");
admin.setAdmPass("1234");
adminService.saveAdmin(admin);
this.admin = adminService.getAdmin("1234");
return SUCCESS;
}
}
5、编写视图
编写success
对应的test.jsp:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%-- 引入struts2 的标签库--%>
<%@ taglib prefix="s" uri="/struts-tags" %>
<html>
<head>
<title>ssh测试</title>
</head>
<body>
<%-- 获取值栈中的user对象的uname的值--%>
用户名: <s:property value="admin.admName"></s:property>
</body>
</html>
四、项目部署测试
1、配置Tomcat服务器
这个配置非常简单,就不详细说明了,参考:IDEA配置Tomcat部署项目
2、测试
点击绿色小三角运行项目,如果没有错误,会自动打开浏览器,默认访问的是index.jsp,即会看到HelloWorld:
接着,在地址栏输入http://localhost:8080/ssh_war_exploded/admin_login:
说明一下:
末尾的admin_login是通配匹配,还记得struts.xml
文件里面的配置吗?action的name属性就是admin_*
,然后*对应的是<allowed-methods>login,add</allowed-methods>
里面的方法,因此这一串地址会去adminAction里面寻找login方法,进而执行getAdmin查询,最后返回admin信息到test.jsp进行渲染。
访问成功:
控制台打印hibernate:
同样,我们将地址换成http://localhost:8080/ssh_war_exploded/admin_add:
先添加一个admin(ssh,1234,ssh测试),然后查询:
控制台:
数据库信息:
五、结束
到此,ssh基本就整合结束了,具体的运行=原理等着我们继续探索,不过还是觉得研究ssm,搞springboot吧,有问题欢迎私聊,睡了!!!