SSH框架( struts+spring+hibernate)

开发环境 myeclipes2015 sqlserver2012 Java

简述

SSH是 struts+spring+hibernate的一个集成框架,是06年之前较为流行的一种Web应用程序开源框架.。集成SSH框架的系统从职责上分为四层:表示层、业务逻辑层、数据持久层和域模块层,以帮助开发人员在短期内搭建结构清晰、可复用性好、维护方便的Web应用程序。其中使用Struts作为系统的整体基础架构,负责MVC的分离,在Struts框架的模型部分,控制业务跳转,利用Hibernate框架对持久层提供支持,Spring做管理,管理struts和hibernate。


SSH框架优点
优秀的解耦性,很少有软件产品的需求从一开始就完全是固定的。客户对软件需求,是随着软件开发过程的深入,不断明晰起来的。因此,常常遇到软件开发到一定程度时,由于客户对软件需求发生了变化,使得软件的实现不得不随之改变。ssh三层构架,控制层依赖于业务逻辑层,但绝不与任何具体的业务逻辑组件耦合,只与接口耦合;同样,业务逻辑层依赖于DAO层,也不会与任何具体的DAO组件耦合,而是面向接口编程。采用这种方式的软件实现,即使软件的部分发生改变,其他部分也不会改变。

框架解析

Struts

(一般开发选用的是Struts2【Struts的升级版】})
Struts2是一个基于MVC设计模式的Web应用框架,它本质上相当于一个servlet,在MVC设计模式中,Struts2作为控制器(Controller)来建立模型与视图的数据交互。Struts 2是Struts的下一代产品,是在 struts 1和WebWork的技术基础上进行了合并的全新的Struts 2框架。其全新的Struts 2的体系结构与Struts 1的体系结构差别巨大。Struts 2以WebWork为核心,采用拦截器的机制来处理用户的请求,这样的设计也使得业务逻辑控制器能够与ServletAPI完全脱离开,所以Struts 2可以理解为WebWork的更新产品。

spring

Spring就像是整个项目中装配bean的大工厂,在配置文件中可以指定使用特定的参数去调用实体类的构造方法来实例化对象。Spring,使用基本的实体JavaBean来完成以前只能用EJB完成的事情。而其核心则是控制反转(IOC)和面向切面编程(AOP)。使用Spring,意味着一个对象的创建再也不是自己new出来的,而是全权交给了IOC容器去实例化。与此同时,Spring通过采用依赖注入(DI)的方式,通过属性的Setter和Getter方法来注入这个对象的属性,这样的好处就是不完全依赖于容器的API,且查询依赖与代码实现了解耦。而AOP,则是将应用的业务逻辑和系统级服务(例如事务)分离开来,进行内聚性的开发,应用对象只负责完成业务逻辑而不关心日志或者事务的处理。
spring优势
spring提高了一种对象管理方法,有效的组织系统中间层对象。是框架的完美“粘合剂”。有利于面向接口编程习惯的养成,使代码结构清晰。

hibernate

Hibernate,是负责了跟数据库的交接。通过持久化数据对象,进行对象关系的映射,并以对象的角度来访问数据库。通过封装JDBC,使得开发人员可以以面向对象编程的思想来操控数据库,从而摆脱了以往使用JDBC编程时的“死板”操作。通过hibernate.cfg.xml文件来取代以往的JDBC连接数据库的一大串代码,通过XXX(实体Bean的类名).hbm.xml文件来与数据库的具体表进行映射。并且Hibernate有自己的HQL语句,与数据库的SQL语句相似,但不同的是HQL语句在面向对象编程的角度上,通过Session的createQuery方法创建户一个query对象,由这个对象来完成对数据库的增删改查等操作。通过Struts2中Action的返回值,来调用Dao层中的业务处理。
hibernate优势
hibernate是JDBC轻量级的封装,占用内存较少,性能比较高。与JDBC相比,如果开发JDBC的人员技术能力非常强,hibernate执行效率会比JDBC弱一些,但是大部分情况是程序员在使用JDBC时是不可能做到最高效率,hibernate可以帮大部分开发人员提高运行效率。可以引入第三方二级缓存,提高系统查询效率,减少系统里存在大量单例类(singleton),大量的单例类,会降低系统的可测试性和面向对象程度。Hibernate兼容JDBC。理论上可以应用在任何使用JDBC的场景。
可以逆向工程,简化了手写model实体类的繁琐。

整体设计

表示层 (jsp页面)用于显示数据和接收用户输入的数据,为用户提供一种交互式操作的界面。login.jsp等layUI前端框架。
业务逻辑层 (Iplm,DAO,接口及接口实现,action,Servlet包)业务规则的制定、业务流程的实现等与业务需求有关的系统设计,对于数据访问层而言,它是调用者;对于表示层而言,它却是被调用者。UserDAO.java/ UserDAOImpl.java,AddcardAction.java/ FileUploadServlet.java
模块层 (hibernate逆向工程)实体层model包),以帮助开发人员在短期内搭建结构清晰、可复用性好、维护方便的Web应用程序。TUser.java/TUser.hbm.xml
数据持久层 (SQL server,基类实现,hql)主要是负责数据库的访问,可以访问数据库系统、二进制文件、文本文档或是XML文档。iHibBaseDAOImpl.java/ iHibBaseDAO.java

DAO接口模式为了减少业务逻辑和数据访问逻辑之间的耦合,当一个持久层框架被应用时,该模式将会减少业务对象和该框架之间的耦合,这样我们可以不修改业务对象而选择不同的持久层框架的实现。
业务逻辑层:包含了系统所需要的所有功能上的算法和计算过程,并与数据访问层和表现层交互。服务端返回数据的处理以及相应页面的改变。

设计原则:
业务层接口的设计原则:一个实体类一个接口,一次提交一个业务方法。业务方法的参数来自表现层。
持久层接口的设计原则:一个实体类一个接口,一次数据库操作一个持久方法。

实例手把手教学搭建

开发工具:myeclipes2015 sqlserver2012

  1. 新建一个SSHtest的web project项目


    输入项目名称,根据需要选择各项版本(一般默认即可),点击下一步

    点击下一步

    勾选后点击下一步

    点击Finish,项目就建好了。

  2. 搭建框架

●创建hibernate


为了更好的与spring匹配我们这里选择3.3版本的hibernate,选好后点击下一步

根据上图操作就建立好了hibernate的session工厂。
接下来我们看一下建好的hibernate配置文件
在hibernate配置文件里配置与数据库的连接,获得数据持久化(相关配置会在后面步骤中介绍)

●创建spring
Spring整合Hibernate(一般先建hibernate再建spring,因为后建spring的话,就会自动把一些相关配置整合到spring里,减少了手动操作的麻烦)


spring一般选4.1版本,切合hibernate3.3,(记得选择版本的时候,两个版本要相对应,否则会因为缺失相应的架包而报错)点击下一步

你不用管,直接下一步

到此步,点击Finish,现在spring就创建好了
接下来我们来看创建好的spring配置文件

●创建Struts2


选择2.1版本,点击下一步


到此步点击Finish,Struts2就创建好。
接下来我们来看Struts2的配置文件

现在我们已经完成了基本SSH框架的搭建。
我们的框架布局基本就搭建完成了,我们先来运行测试一下(一般运行没错,就说明搭建没问题)
将项目部署到Tomcat上:

运行

因为要连接数据库,所以我们要新建一个数据库
●以sqlserver2012为例,新建一个名为SSHtest的数据库

创建数据库

点击确定,数据库就创好了。
我们在这了以用户登录为例,建一张用户表T_User

填写数据

3. 创建所需包
4 . 配置框架
●hibernate连接数据库,获得持久化数据
新建数据池database


操作完以上点击下一步

点击Finish,数据库连接池就做好了

hibernate配置

操作完以上记得ctrl+s保存,这样hibernate就配置好了。
接下来我们看一下hibernate的配置文件

hibernate逆向工程(获得model实体类)



点击ok,

下一步

直接下一步

点击后会出现如下

选择yes

到此步逆向工程就完成了。

接下来可以写一些类
business.basic包(放置基类及帮助类)

business.dao包(放置业务接口供给调用)
创建一个用户业务接口


选择interface,下一步

点击finish,接口类就创建好了。

UserDAO代码如下(一般书写登录及增删查改接口)

package business.dao;
import java.util.List;
import model.TUser;public interface UserDAO {/*** 用户登录业务方法* @param userid   用户登录名* @param password   登录密码* @return  TUser  当前登录的用户对象*/public TUser login(String userid,String password);/*** 普通用户的注册方法* @param userid  用户注册的用户名* @param password  用户注册录密码的的* @param username  用户注册的姓名* @return  boolean  注册成功返回true 失败返回false*/public boolean addNormalUser(String userid,String password,String username);/*** 修改普通用户信息* @param userid  要修改的用户的用户名* @param password  修改后的密码* @param username  修改后的用户网站昵称* @return 修改成功返回true 失败返回false*/public boolean modifyNormalUser(String userid,String password,String username); /*** 根据用户输入的用户名返回对应的TUser对象* @param userid 用户名* @return TUser对象*/public TUser getTUserById(String userid);/*** 判断注册用户名是否可用* @param userid* @return 用户名可用返回true, 否则返回false*/public boolean isValidateUserid(String userid);}

business.impl包(放置接口实现类)
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-XTSG4bfP-1574340786841)(https://img-blog.c sdnimg.cn/20191121192641243.png)]




代码如下

package business.impl;import java.util.List;
import model.TUser;
import business.basic.iHibBaseDAO;
import business.basic.iHibBaseDAOImpl;
import business.dao.UserDAO;public class UserDAOImpl implements UserDAO {private iHibBaseDAO bdao = null;public void setBdao(iHibBaseDAO bdao) {this.bdao = bdao;}public UserDAOImpl(){bdao = new iHibBaseDAOImpl();}@Overridepublic TUser login(String userid, String password) {String hql="from TUser where userid = ? and password = ?";Object[] para = {userid,password};List<TUser> list = bdao.select(hql, para);if(list.size()>0){return (TUser)list.get(0);}else {return null;}}@Overridepublic boolean addNormalUser(String userid, String password, String username) {TUser user = new TUser();user.setUserid(userid);user.setPassword(password);user.setUsername(username);   Object obj = bdao.insert(user);if(obj != null){return true;}else {return false;}}@Overridepublic boolean modifyNormalUser(String userid, String password,String username) {TUser user = (TUser)bdao.findById(TUser.class, userid);user.setPassword(password);user.setUsername(username);return bdao.update(user);}@Overridepublic TUser getTUserById(String userid) {return (TUser)bdao.findById(TUser.class, userid);}@Overridepublic boolean isValidateUserid(String userid) {TUser user = (TUser)bdao.findById(TUser.class, userid);if(user!=null && !user.getUserid().equals("")){return false;}else {return true;}}}

business.factory包(放置工厂类)

工厂里整合了接口和接口实现类,在action里直接调用工厂类,就不用再分开调用接口和接口实现,不用再下实例化对象在调用。
代码如下
动态工厂

package business.factory;
import business.dao.UserDAO;
import business.impl.UserDAOImpl;/** 动态工厂*/
public class DAOFactory {/*** 返回一个用于对用户信息操作的UserDAO对象* @return UserDAO*/public UserDAO getUserDAO(){return new UserDAOImpl();}}

动态工厂

package business.factory;
import business.dao.UserDAO;
import business.impl.UserDAOImpl;
public class StaticDAOFactory {/*** (静态方法)返回一个用于对用户信息操作的UserDAO对象* @return UserDAO*/public static UserDAO getUserDAO(){return new UserDAOImpl();}}

一般选用动态。

spring配置
可创建bean来管理接口及接口实现(将接口及接口实现、工厂注册给bean,配置好后交给spring统一管理)也可直接在session工厂利配置
平常的java开发中,程序员在某个类中需要依赖其它类的方法,则通常是new一个依赖类再调用类实例的方法,这种开发存在的问题是new的类实例不好统一管理,spring提出了依赖注入的思想,即依赖类不由程序员实例化,而是通过spring容器帮我们new指定实例并且将实例注入到需要该对象的类中。依赖注入的另一种说法是“控制反转”,通俗的理解是:平常我们new一个实例,这个实例的控制权是我们程序员,而控制反转是指new实例工作不由我们程序员来做而是交给spring容器来做。
创建一个新springbean来注册管理,我们命名为bean1

选择other

下一步

选择sping链接(根据所需配置加载)


勾选如上复选框,点击Finish,springbean就创建好了。
接下来配置bean
这里讲一下静态工厂的方法注入
静态工厂顾名思义,就是通过调用静态工厂的方法来获取自己需要的对象,为了让spring管理所有对象,我们不能直接通过"工程类.静态方法()"来获取对象,而是依然通过spring注入的形式获取:

<?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:aop="http://www.springframework.org/schema/aop"xmlns:c="http://www.springframework.org/schema/c"xmlns:context="http://www.springframework.org/schema/context"xmlns:p="http://www.springframework.org/schema/p"xmlns:tx="http://www.springframework.org/schema/tx"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.1.xsdhttp://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.1.xsdhttp://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.1.xsd"><!-- 扫描器 扫描包中的类,将相关类注册成bean --><context:annotation-config /><context:component-scan base-package="business" /><!--注入action,service,dao  --><!-- 静态 --><bean id="login" class="business.action.LoginAction" scope="prototype"></bean><bean id="userDAO" name="userdao" class="business.factory.StaticDAOFactory"factory-method="getUserDAO" abstract="false" lazy-init="default"autowire="default"></bean>  <bean id="bdao" class="business.basic.iHibBaseDAOImpl"></bean><!-- 实现基于上iHibBaseDAOImpl --><bean id="userdaoimpl" name="userdaoimpl" class="business.impl.UserDAOImpl"><property name="bdao" ref="bdao"></property></bean></beans>

工程项目下的web.xml的配置

到此步springbean就配置成功了。

struts.xml配置

为了更好的进行配置,我们选择视图界面配置

建好后的视图界面

首先我们先创建如下几个jsp和css文件

接下来添加action


配置失败返回参数

如果跳转到网页可以使用dispatcher,页面跟共用响应对象
redirect简单的重定位,不共用响应对象
redirectAction action跳转action,不共用响应对象

建立好的包视图

看看他的配置文件
它的参数要在action里定义才会生效

接下来就可以书写action了
打开新建好的LoginAction类

公共封装方法命名为BaseAction如下

package business.action;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;import org.apache.struts2.ServletActionContext;import com.opensymphony.xwork2.ActionSupport;public class BaseAction extends ActionSupport {protected  HttpServletRequest request;protected HttpServletResponse response;protected HttpSession session;protected ServletContext application;public BaseAction() {super();request = ServletActionContext.getRequest();response = ServletActionContext.getResponse();session = request.getSession();application = ServletActionContext.getServletContext();}
}

当struts接受这个action请求时,struts调用 username的get方法把前台的值传到action中的username,当action处理完成,要返回到页面时。在生成jsp的过程中,你可以在页面中使用EL表达式,${username}进行绑值,这时调用username的set方法。
 在jsp页面顶部导入el表达式标签连接

 <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>


 LoginAction类

package business.action;import model.TUser;
import business.dao.UserDAO;
import business.factory.DAOFactory;public class LoginAction extends BaseAction {//获取jsp页面传过来的userid和passwordprivate String userid; private String password;//利用get set方法将值获取上public String getUserid() {return userid;}public String getPassword() {return password;}public void setUserid(String userid) {this.userid = userid;}public void setPassword(String password) {this.password = password;}public void setErrorsText(String errorsText) {this.errorsText = errorsText;}public void setBackurl(String backurl) {this.backurl = backurl;}private String errorsText;//设置错误提示文字private String backurl; //返回地址public String getErrorsText() {return errorsText;}public String getBackurl() {return backurl;}private String requesturl;public String getRequesturl() {return requesturl;}public void setRequesturl(String requesturl) {this.requesturl = requesturl;}/*** @return*/public String execute() {System.out.println("获取:用户名"+userid+"密码:"+password);backurl="login.jsp";//判断输入框是否为空if(userid==null ||userid.trim().equals("")){errorsText = "用户账号不能为空";return ERROR;}else if(password==null ||password.trim().equals("")){errorsText = "密码不能为空";return ERROR;}//以数据库数据进行对比UserDAO udao = new DAOFactory().getUserDAO();TUser loginUser = udao.login(userid, password);if(loginUser!=null && loginUser.getUsername()!=null){//判断登陆成功,将用户名存在session里供后续操作调用session.setAttribute("loginuser", loginUser);//记录当前地址requesturl = (String)session.getAttribute("requesturl");return SUCCESS;}else{//失败则跳转 fial.jsperrorsText = "登录失败";return ERROR;}}
}

success.jsp代码

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>"><title>SSH</title>
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="SSH"></head><body>
<h2>当前的登录用户为:<span style="color:yellow; font:bold">${loginuser.username} </span></h2>添加user,如果姓名没有冲突,那么就添加到数据库,如果姓名冲突了就不能添加,返回失败页面<form action="add.action" method="get">UserName:<input type="text" name="user.username"><br />UserPassword:<input type="password" name="user.userpassword"><br />UserMessage:<input type="text" name="user.usermessage"><br /><input type="submit" value="提交"> <input type="reset"value="重置"></form>根据姓名查询,若不输入,则查询全部<form action="query.action" method="post">UserName: <input type="text" name="queryText" value="${searchText }" /><input type="submit" value="查询" /></form><table width="70%" border="1px" align="center" cellpadding="0"cellspacing="0"><thead><tr bgcolor="#ff0"><th width="25%">编号</th><th width="25%">姓名</th><th width="25%">信息</th><th width="25%">操作</th></tr></thead><tbody><c:forEach var="user" items="${users }"><tr><td>${user.id}</td><td>${user.username}</td><td>${user.usermessage}</td><td><a href="edit.action?param=0&id=${user.id}">编辑</a> <ahref="delete.action?id=${user.id}">删除</a></td></tr></c:forEach></tbody></table></body>
</html>

fail.jsp代码


<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%String path = request.getContextPath();String basePath = request.getScheme() + "://"+ request.getServerName() + ":" + request.getServerPort()+ path + "/";
%><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>"><title>fail</title>
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="fail"></head><body><div style="color:red;">fail</div><br/><center><p><h2>${errorsText}</h2></p></center><div id = "foot"><a href="${backurl}">返回上一页面</a></div><!--  <a href="query.action?queryText=">返回主页</a> -->
</body>
</html>

建立好如上,运行测试
输入为空测试

输入账号密码测试

输入后会报如上错误
经过一番上网查询测试,发现:
主要 是里面的Structs 1.3 (structs 2)和Hibernate 3.2(或更高版本)中的JAR包里antlr2.7.2 与 antlr2.7.6 冲突,只要删除Structs 1.3中的低版本的antlr2.7.2就可以了。具体操作如下:在MyEclipse 下,windows–>preferences–>在文本框中搜索struts2–>选择 antlr2.7.2–>remove

现在重启Tomcat再次测试:

现在登陆成功了,并且获取到了用户名。
在测试查询时,利用<c:forEach items>查询多条记录可以正常使用,但存在的单条记录会报错。如下

经过小编多放查证,终于发现:
在访问某个页面出现了上标题所示的异常。一开始我也不知道什么原因,因为后台已经返回了数据,而且前端的el/jstl表达式都写的没毛病。
后来无意中想到,我这个数据是确定的只有一条,但是我还是用的<c:forEach>来写。然后我把数据包装了一下,虽然只有一条数据,但是我返回的还是一个list集合就没问题啦(重新写了一个接口)

改变后的action

测试通过

项目完整演示:

注意

本项目的SSH框架中spring是以单spring框架搭建(单纯的整合hibernate数据库连接,其间的接口及其注入配置貌似没有什么作用,其实实配置不配置程序都能运行。)而在实际项目开发中多是spring与其他技术架构结合的,比如springMVC、springBoot等等。这些项目框架会在后续博文中给大家呈现。

项目中有什么错误之处,希望有心之人在评论中指出或私发消息讨论。

此项目用SSH框架搭建,实现了用户的登录、查询、删除、添加。
项目(源码+数据库)我已上传至gitee码云上,有需要的可以进行下载:
GITEE码云地址:https://gitee.com/zhangyant/SSHtest
记得更改hibernate数据库连接(导入sql文件夹中sql语句)。



另一种ssh架构可参考:https://www.cnblogs.com/acm-bingzi/p/ssh.html
本人觉得此方法有点难以理解(–^^–)。

JAVAweb之SSH框架相关推荐

  1. 基于jsp的消防知识宣传网站ssh框架

    消防知识宣传网站主要是发布一些消防新闻和消防知识以及消防器材的介绍使用方法,对人们对火灾方面的了解有一定的普及作用,系统基于javaweb开发,使用了mvc思想ssh框架,Myeclipse作为开发平 ...

  2. java解决框架注入,SSH框架 使用Spring时 IOC无法注入解决办法

    SSH框架 使用Spring时 IOC无法注入 本人初学JavaWeb 现在在自己做一个SSH的练习 今天遇到一个 Spring无法注入的问题, 用了一个下午的时间也没找到毛病具体发生在哪儿 求经验丰 ...

  3. [转载]SSH框架搭建详细图文教程

    什么是SSH? SSH对应 struts spring hibernatestruts 采用MVC模式,主要是作用于用户交互spring 采用IOC和AOP~作用比较抽象,是用于项目的松耦合hiber ...

  4. ssh框架实现数据库_自顶向下介绍SSH及其如何实现安全的数据共享

    ssh框架实现数据库 by Sam Ollason 通过萨姆·奥拉森(Sam Ollason) This article will take a high-level and top-down app ...

  5. 使用SSH框架实现用户登录验证

    今天,写一个非常简单的通过struts+hibernate+spring的集成来实现用户登录验证的例子,让大家了解一下三者是如何是整合的. 我们可以通过myeclipse的向导,生成相应的环境搭建,如 ...

  6. SSH框架整合-慕课课程

    SSH框架整合-慕课课程 学习时间:2018年12月3日 慕课链接:基于SSH实现员工管理系统之框架整合篇 内容:Struts2+Hibernate+Spring框架整合,分为Struts2整合Spr ...

  7. java web的ssh框架_JavaWeb_(SSH论坛)_二、框架整合

    基于SSH框架的小型论坛项目 一.项目入门 传送门 二.框架整合 传送门 三.用户模块 传送门 四.页面显示 传送门 五.帖子模块 传送门 六.点赞模块 传送门 七.辅助模块传送门 导入Jar包 导入 ...

  8. java ssh框架 struts spring hibernate 简介

    目录 什么是SSH框架 浅谈Struts 什么是Struts Struts的核心构成 为什么使用Struts 浅谈Hibernate 什么是Hibernate Hibernate的核心构成 浅谈Spr ...

  9. SSH框架总结(框架分析+环境搭建+实例源代码下载)

    首先,SSH不是一个框架,而是多个框架(struts+spring+hibernate)的集成,是眼下较流行的一种Web应用程序开源集成框架,用于构建灵活.易于扩展的多层Web应用程序. 集成SSH框 ...

  10. 基于maven的ssh框架一步一步搭建(一)

    一.新建maven项目,配置ssh框架pom的最低支持 1.新建一个maven项目 2.添加一个web.xml ? 1 2 3 4 5 6 7 8 9 <?xml version="1 ...

最新文章

  1. backlight 子系统(转载)
  2. poj 1192(简单树形dp)
  3. Behave用户自定义数据类型
  4. java之Hibenate中监听事件的重写和二级cache缓存
  5. 微信小程序 - 高级 - 深度实践 - wx:for-item 与 data-xxx 的联合应用 实现后台动态数据自动加载的正确方法概述
  6. Fences桌面图标分类
  7. git detached head
  8. MAC电脑安装window系统(一):双系统安装方法
  9. java近义词,同义词查询_java 同义词查询怎么做?
  10. 超星章节内ppt课件下载
  11. NEXTCHIP图像品牌ISP和AHD都是有哪些功能?型号有多少型号?
  12. 电脑网页截屏怎么截长图?借助Safari对整个网页进行长截图
  13. 三个优秀的Android图表开源控件
  14. 自动化 夏令营 保研
  15. Ring buffer streaming in general - how to imple...
  16. Linux4.14加密框架中的主要数据结构(5)—— struct crypto_larval(算法幼虫)
  17. 西南民族大学第十届校赛(同步赛) 个人笔记 题解
  18. 有歧义(AMBIGUOUS LAYOUT)的约束布局调试方法2
  19. 基于Epoll的Reactor模式
  20. vb.net odbc mysql_在VB.net 中连接MySql的类库

热门文章

  1. 北京市常用电话号码表
  2. js正则表达式校验手机号码和电话号码
  3. 基于表面肌电信号的连续运动估计之前言(一)
  4. Keil芯片安装包下载
  5. 现代光学字符识别技术综述
  6. 汉字转拼音的代码-转
  7. cfe刷机教程 斐讯k3_玩转斐讯K3详细刷机——直接刷LEDE
  8. 汤家凤:九月前强化复习结束不了怎么办?
  9. 对象转json时,Date类型字段处理。
  10. JCam2 v1.6.0 USB摄像头工具全新发布及使用详解