MVC: 全名是Model View Controller,是模型(model)-视图(view)-控制器(controller)的缩写,一种软件设计典范,用一种业务逻辑、数据、界面显示分离的方法组织代码,将业务逻辑聚集到一个部件里面,在改进和个性化定制界面及用户交互的同时,不需要重新编写业务逻辑。MVC被独特的发展起来用于映射传统的输入、处理和输出功能在一个逻辑的图形化用户界面的结构中。
Struts对MVC进行了很好的封装,使用Struts的目的是为了帮助我们减少在运用MVC设计模型来开发Web应用的时间。如果我们想混合使用Servlets和JSP的优点来建立可扩展的应用,struts是一个不错的选择。(没理解透)
本文需求资源:
Eclipse
MySQL
各种JAR包
Eclipse 和 MySQL 怎么下载安装使用就不记述了,所有JAR包在第二节有下载地址。
01 Eclipse 创建 Dynamic Web Project
Eclipse -> File -> New -> Others
输入 WEB 后有 Dynamic web project 选项(如果没有应该是缺少什么组件了,网上再搜搜)
点击 NEXT,然后填好 Project Name 和 Location(其他选择项我没改)
我这里出现错误提示(红叉:这个名称的项目已经存在)是因为我已经创建了该项目,这里是为了方便以后翻阅,所以重新走了一边过程。点击NEXT
这里不需要修改,继续NEXT。
勾上产生wb.xml文件(上图黄色区域),然后点击 Finish 完成。最后创建的项目在Eclipse中目录结构如下:
图1.6中 Cardproject即为该项目
02 添加JAR包
这一节主要介绍包的分类和作用,可以不用细看,直接导入所有的JAR包,链接: https://pan.baidu.com/s/1XM97gAetV2QslH69ZiLmwA 提取码: 8k4q。(一共45个,只有JAR包,没有源码和注释文档,需要可自己对应去添加源码和注释文档的JAR包)。
02.01 Hibernate 相关 JAR 包导入
我用的应该是5.3的版本,压缩文件为:hibernate-release-5.3.4.Final.zip。解压后目录中的 libs/required 目录下所有的JAR包拷贝到 Cardproject/WebContent/WEB-INF/lib 目录下:
再把 Hibernate解压路径/lib/jpa-metamodel-generator 中的 hibernate-jpamodelgen-5.3.4.Final.jar 拷贝到 WEB-INF/lib 中。
由于我使用的是 MySQL 数据库,所以用mysql的数据库驱动(连接器)(可以直接在网上找到)
以上所有包拷入 Cardproject 后,Hibernate 相关 JAR 包导入告一段落。
02.02 Structs 相关 JAR 包导入
本文用到的 STRUCTS 包为 2.5的版本 struts-2.5.16-all.zip,注意:2.5以后的版本少了xwork-core 和 log4j-core的 JAR 包,其中 xwork-core 在struts升级到2.5版本已经包含在了struts2-core中了,而 log4j-core 的 JAR 包需要用 log4j-core-2.7.jar(2.7版本,官网下载https://www.apache.org/dyn/closer.lua/logging/log4j/2.7/apache-log4j-2.7-bin.zip);而且以前的版本中这些包也不在(struts-2.5.16-all.zip解压目录/lib)中,在(struts-2.5.16-all.zip解压目录/apps)中,以前的版本具体在该目录下的什么位置我也不太清楚,应该百度得到。(以下把struts-2.5.16-all.zip解压目录 简称 解压目录)
为了方便整理,我先把要用的一部分 JAR 包从(解压路径/lib)中拷贝了出来,放到了一个(汇总)文件夹里。
下载 log4j-2.7 后我把 log4j-api-2.7.jar 和 log4j-core-2.7.jar 复制到了 Cardproject 中,而删掉了 log4j-api-2.10.0.jar。
再把 struts2-spring-plugin-2.5.16.jar(解压目录/lib) 拷入(汇总)
导入图2.7中的包后,就必须对spring配置,否则会报错(后文提及如何配置);(汇总)JAR 包拷入 Cardproject 中:
最后,把低版本的 JAR 包删除
Structs 告一段落。
02.03 Spring 相关 JAR 包导入
Spring 我用的是 spring-framework-5.0.8.RELEASE-dist.zip 即 5.0 版本,解压后同样我新建了一个汇总的文件夹,方便整理后导入项目中去。
此外,还需要 logging 的 JAR 包,下载地址:http://commons.apache.org/proper/commons-logging/download_logging.cgi 解压后取出 commons-logging-1.2.jar 放入(汇总)
网上搜索 spring-framework-3.0.2.RELEASE-dependencies ,找到一份后直接下载(比较大,图2.12中 logging 的 JAR 包在其中也可以找到),我没有等下载完,直接搜 com.springsource.org.apache.log4j 然后找了一份下载
还有(解压路径/libs)中的 spring-web-5.0.8.RELEASE.jar 放入汇总文件中
再找到(解压路径/libs)中的 aop 相关的2个包:spring-aop-5.0.8.RELEASE.jar;spring-aspects-5.0.8.RELEASE.jar;还有两个包:com.springsource.org.aopalliance-1.0.0.jar;com.springsource.org.aspectj.weaver-1.6.8.RELEASE.jar 在解压路径中找不到,网上搜一下可以找到。汇总 JAR 包一览
然后复制进 Cardproject 中,总JAR包如图2.15所示。
还差 Spring 整合事务的JAR包,在Spring解压路径/libs 中找到以下4个包:spring-jdbc-5.0.8.RELEASE.jar;spring-orm-5.0.8.RELEASE.jar;spring-tx-5.0.8.RELEASE.jar;spring-test-5.0.8.RELEASE.jar;拷入汇总路径和 Cardproject 中。
c3p0 连接池管理包在 Spring 压缩文件中找不到,网上直接搜索下载,我用的是:c3p0-0.9.5.2.jar,在 0.9.1 以后的版本c3p0还需要一个辅助包 mchange-commons-java-0.2.11.jar,没有该包会报错。
标签库包也需要额外再找,包含两个,网上可以直接搜到,我用的是:jstl.jar;standard.jar。
以上,所有包都导入完毕,一共45项,分了两张图显示。
以上,所有包整合完毕。
03 所需文件
03.01 Src的结构
由图 3.1 可以看到,测试包共有5个,一个空包(com.shop.action)可以不用。
03.02 Demo1.java
测试文件,项目搭好后,选择到具体的方法右键即可用 JUNIT 调试(RUN)。
package com.shop.dao;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.hibernate.cfg.Configuration;
import org.hibernate.SessionFactory;
import org.hibernate.Session;
import com.shop.domain.User;
import com.shop.service.UserService;
import org.hibernate.Transaction;
public class Demo1 {
@Test
public void fun1() {
Configuration conf = new Configuration().configure();
SessionFactory sessionFactory = conf.buildSessionFactory();
Session session = sessionFactory.openSession();
Transaction tx = session.beginTransaction();
User user = new User();
user.setName("456");
session.save(user);
tx.commit();
}
@Test
public void fun2() {
ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
SessionFactory sessionFactory = (SessionFactory)ac.getBean("SessionFactory");
Session session = sessionFactory.openSession();
Transaction tx = session.beginTransaction();
User user = new User();
user.setName("234");
session.save(user);
tx.commit();
}
@Test
public void fun3() {
ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
UserDao userDao = (UserDao)ac.getBean("UserDao");
User user = userDao.getUser();
System.out.println(user);
}
@Test
public void fun4() {
ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
UserService userService = (UserService)ac.getBean("userService");
User user = userService.getUser();
System.out.println(user);
}
@Test
public void fun5() {
ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
UserService userService = (UserService)ac.getBean("userService");
User user = new User();
user.setName("new");
userService.addUser(user);
}
}
03.03 UserDao.java
package com.shop.dao;
import java.util.List;
import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.query.Query;
import org.springframework.orm.hibernate5.HibernateCallback;
import org.springframework.orm.hibernate5.HibernateTemplate;
import org.springframework.orm.hibernate5.support.HibernateDaoSupport;
import com.shop.domain.User;
public class UserDao extends HibernateDaoSupport {
/**
* By Criteria
*
*
* @return
*/
public User getUser() {
DetachedCriteria dc = DetachedCriteria.forClass(User.class);
List<User> results = (List<User>)this.getHibernateTemplate().findByCriteria(dc);
return results==null||results.size()==0 ? null : results.get(0);
}
/**
* By HQL
*
* @param id
* @return
*/
public User getUser(final Integer id) {
HibernateTemplate ht = this.getHibernateTemplate();
User user = ht.execute(new HibernateCallback<User>() {
public User doInHibernate(Session session) throws HibernateException {
String hql = "from com.shop.domain.User where id=?0";
Query query = session.createQuery(hql);
query.setParameter(0, id);
return (User)query.uniqueResult();
}
});
return user;
}
/**
* By Native Method
*
*
* @param user
*/
public void addUser(User user) {
this.getHibernateTemplate().save(user);
}
}
03.04 User.java
package com.shop.domain;
public class User {
private Integer id;
private String name;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String toString() {
return "User [id=" + id + ", name=" + name + "]";
}
}
03.05 User.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="com.shop.domain.User" table="tb_user">
<id name="id" column="id">
<generator class="native"></generator>
</id>
<property name="name" column="name"></property>
</class>
</hibernate-mapping>
03.06 UserService.java
package com.shop.service;
import com.shop.dao.UserDao;
import com.shop.domain.User;
public class UserService {
private UserDao userDao;
public UserDao getUserDao() {
return userDao;
}
public void setUserDao(UserDao userDao) {
this.userDao = userDao;
}
public User getUser() {
return userDao.getUser();
}
public User getUser(Integer id) {
return userDao.getUser(id);
}
public void addUser(User user) {
userDao.addUser(user);
}
}
03.07 UserAction.java
package com.shop.web;
import com.opensymphony.xwork2.ActionSupport;
import com.shop.service.UserService;
import com.shop.domain.User;
public class UserAction extends ActionSupport {
private UserService userService;
public UserService getUserService() {
return userService;
}
public void setUserService(UserService userService) {
this.userService = userService;
}
public String User() {
User user = userService.getUser();
System.out.println(user);
return SUCCESS;
}
}
03.08 applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/jdbc
http://www.springframework.org/schema/jdbc/spring-jdbc-3.1.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/util
http://www.springframework.org/schema/util/spring-util.xsd"
>
<bean name="userAction" class="com.shop.web.UserAction" scope="prototype">
<property name="userService" ref="userService"></property>
</bean>
<context:property-placeholder location="classpath:db.properties" />
<bean name="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="${driverClass}"></property>
<property name="jdbcUrl" value="${jdbcUrl}"></property>
<property name="user" value="${user}"></property>
<property name="password" value="${password}"></property>
</bean>
<bean name="userService" class="com.shop.service.UserService">
<property name="userDao" ref="UserDao"></property>
</bean>
<bean name="SessionFactory" class="org.springframework.orm.hibernate5.LocalSessionFactoryBean">
<!-- Not so good
<property name="configLocation" value="classpath:hibernate.cfg.xml"></property>
-->
<property name="dataSource" ref="dataSource"></property>
<property name="hibernateProperties">
<props>
<!--
<prop key="hibernate.connection.driver_class">com.mysql.jdbc.Driver</prop>
<prop key="hibernate.connection.url">jdbc:mysql://localhost:3306/test</prop>
<prop key="hibernate.connection.username">root</prop>
<prop key="hibernate.connection.password">ani1357658uiu</prop>
-->
<prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.format_sql">true</prop>
<prop key="hibernate.hbm2ddl.auto">update</prop>
</props>
</property>
<property name="mappingDirectoryLocations" value="classpath:com/shop/domain"></property>
</bean>
<bean name="UserDao" class="com.shop.dao.UserDao">
<property name="sessionFactory" ref="SessionFactory"></property>
</bean>
<bean name="TransactionManager" class="org.springframework.orm.hibernate5.HibernateTransactionManager">
<property name="sessionFactory" ref="SessionFactory"></property>
</bean>
<tx:advice id="advicer_service" transaction-manager="TransactionManager">
<tx:attributes>
<tx:method name="get*" isolation="READ_COMMITTED" propagation="SUPPORTS" read-only="true"/>
<tx:method name="add*" isolation="READ_COMMITTED" propagation="SUPPORTS" read-only="false"/>
</tx:attributes>
</tx:advice>
<aop:config>
<aop:pointcut expression="execution(* com.shop.service.UserService.*(..))" id="user"/>
<aop:advisor advice-ref="advicer_service" pointcut-ref="user"/>
</aop:config>
</beans>
03.09 db.properties
#自行修改以下内容
driverClass = com.mysql.jdbc.Driver
jdbcUrl = jdbc:mysql://localhost:3306/test
user = root
password = ********
03.10 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>
<!--
<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="hibernate.connection.url">jdbc:mysql://localhost:3306/test</property>
<property name="hibernate.connection.username">root</property>
<property name="hibernate.connection.password">********</property>
<property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
<property name="hibernate.show_sql">true</property>
<property name="hibernate.format_sql">true</property>
<property name="hibernate.hbm2ddl.auto">update</property>
<property name="hibernate.connection.autocommit">false</property>
<mapping resource="com/shop/domain/User.hbm.xml" />
-->
</session-factory>
</hibernate-configuration>
03.11 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>
<package name="shop" namespace="/" extends = "struts-default">
<action name="userAction" class="userAction" method="User">
<result name="success">/user.jsp</result>
</action>
</package>
</struts>
03.12 WebContent 结构
图3.2所示目录中,lib 为 JAR 包所在目录,一共45项,就不再展开了。注意,web.xml 在 WEB-INF 目录下;而 user.jsp 在 WebContent 目录下。
03.13 web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1">
<display-name>Cardproject</display-name>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.htm</welcome-file>
<welcome-file>index.jsp</welcome-file>
<welcome-file>default.html</welcome-file>
<welcome-file>default.htm</welcome-file>
<welcome-file>default.jsp</welcome-file>
</welcome-file-list>
<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>
<filter>
<filter-name>demo</filter-name>
<filter-class>org.apache.struts2.dispatcher.filter.StrutsPrepareAndExecuteFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>demo</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
</web-app>
03.14 user.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!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>
hello!!
</body>
</html>
把以上文件加入项目中,就可以开始测试了。
04 测试
04.01 搭建服务器
关于如何安装 TOMCAT 不在此赘述。
打开 Servers 窗口:Window > Show View > Other > Server > Servers,再点击 Open。
右键 Servers 窗口空白处,New > Server
此处,我选择了 9.0 版本的服务器,点击 NEXT。
找到对应的项目,然后 ADD 进服务器,点击 FINISH。
可以看到由于项目未被部署,红线圈起的地方是可修改的,刚创建好的服务器并不是如此配置的,按上图修改即可。若红线圈起的地方不可修改,可以按下图方式操作(会不会对已部署项目造成破坏我就不清楚了。。。应该是不会的)
右键服务器,选中 Clean,单击。
至此,服务器就配置好了。
(对了,TOMCAT 太久未用需要启动 START.BAT,就在TOMCAT安装的目录下)
04.02 MySQL 创建表格
我使用的是 test 数据库下的 tb_user 表,可按照自己的需求来。配置完后要确保服务已经打开,可以在任务管理器中查看。
User 有两个数据段,ID 为自增型KEY键,NAME 为 VARCHAR(45) 【45随意改】。
04.03 访问测试
运行刚刚建立的服务器,打开任意一个浏览器,输入 http://localhost:8080/Cardproject/userAction
其中 Cardproject 是我这个测试项目的项目名,会有 hello!! 字样显示。
04.04 数据库操作测试
首先清空数据库中 tb_user 内容。按图 4.7 的方法以此运行 Cardproject/src/com/shop/dao/Demo1.java 中的 fun1 到 fun5 方法,观察输出和数据库 tb_user 的变化。
我运行时把服务器和8080的浏览器界面都关了,不关也行。
运行 fun1() 提示错误,数据库无变化,怎么改由于是新手。。。以后加上。
运行 fun2() 输出窗口打印 SQL 语句,数据库新增一个名为 234 的 User。
运行 fun3() 输出窗口打印 SQL 语句和数据库第一个用户的信息。
运行 fun4() 输出与 fun3() 相同。
运行 fun5() 输出窗口打印 SQL 语句,数据库新增一个名为 new 的 User。