相信大家对于mvc的三层架构已经灰常熟悉了,在这就不细讲了,个人感觉ssi的框架结构还是比较典型的mvc三层架构,还是比较容易上手的。关于这块的入门我想特别感谢下FrankHui童鞋,在他的帮助下,我才能比较快滴熟悉了这个架构,对我学习ssi的框架还是很有帮助滴。ssi的框架主要是由struts2,spring以及ibatis组成,他们负责各层之间的交互与协作,从而实现整个web端的功能实现与整合。Struts目前主要负责数据传递和控制方面,spring则依靠其强大的依赖注入技术实现了类似bean托管和整合等功能,当然这只是spring功能中的冰山一角,而ibatis作为一种轻量级的OR Mapping框架,提供了半自动化对象关系映射的实现,自由度相对于hibernate更高。
框架结构:
这是我在网上找到的一张关于ssi框架的结构图,个人感觉画的还是蛮不错的,对于入门者来说,层次机构很清晰,比较实用(感谢这位大大的分享):

在这里可以很明显的看出ssi框架的大体结构以及各层之间的交互情况,顶层表现层的话,就java而言主要是jsp,html等视图层技术的编写,其中涉及我们熟悉的javascript,jquery以及extjs等。在控制层来说的话,主要是利用strust2标签功能实现action与视图层的数据交互,当然也可以使用ajax的技术实现同样的功能,这个就按个人喜好而来了。在业务逻辑层。主要是利用spring的依赖注入实现对业务逻辑类和dao类的实例托管,当然各类的实例都可以托管在spring中进行统一管理和关联,包括事务,数据源等等。在持久层,利用ibatis提供的半自动化对象关系映射的实现,开发人员可以根据需要编写具体的sql语句,通过相应的xml的配置实现对数据库的操作。
总之,SSI框架能够降低我们代码的耦合度,增强了代码的健壮性和可重用性,加快了开发速度,但是也有一些不足之处,比如由于三种框架的配置文件较多,也给我们带来了一些不便,特别是对于较小的应用来说更是如此。
相关demo介绍:
基于之前对ssi框架的学习,我也不能免俗滴选择了做一个用户管理的web实现,项目的大致框架如下:

大体上还是按照三层的分层模型来是分的,具体就不详细说了,相信大家也应该很了解整个结构的。
Ø 开发环境简介:
工具:eclipse3.6+tomcat7+mysql5.1
框架:struts2,spring3.0.5,ibatis2.3.4.726
开发步骤及配置简介:
第一步,众所周知肯定是导入相关的lib库啦,由于我使用的前端是extjs,所以还需要导入extjs相关的js以及css依赖文件。由于lib库太多就不截图了,只截取extjs的相关依赖文件:

这样基本的环境就有了,数据库的设计则需要根据model层的对象来确定。
第二步,建立相关的model层,代码如下:
User.java:
package com.broada.demo.entity;
public class User {
private int id; //用户id
private String name; //用户名称
private String password; //用户密码
private String username; //用户昵称
private String address; //地址
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username=username;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address=address;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id=id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name=name;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password=password;
}
}
第三步,strust的相关配置,这里就不详细讲述strust的单独配置及原理了,直接上实例中的相关配置文件,主要是strust.xml以及web.xml的相关配置,部分主要配置如下:
Web.xml:
<!-- struts2模块 -->
<filter>
<filter-name>struts2</filter-name>
<!-- 这个就是struts2的核心过滤器 -->
<filter-class>
org.apache.struts2.dispatcher.FilterDispatcher
</filter-class>
</filter>
<filter-mapping>
<filter-name>struts2</filter-name>
<url-pattern>
import com.broada.demo.entity.User;
import com.broada.demo.service.UserDaoServiceInter;
import com.opensymphony.xwork2.ActionSupport;
public class RegisterAction extends ActionSupport {
private static final long serialVersionUID=1L;
private UserDaoServiceInter userdaoServiceInter;
public UserDaoServiceInter getUserdaoServiceInter() {
return userdaoServiceInter;
}
public void setUserdaoServiceInter(UserDaoServiceInter userdaoServiceInter) {
this.userdaoServiceInter=userdaoServiceInter;
}
private String name; //用户名
private String password; //密码
private String username; //昵称
private String address; //地址
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username=username;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address=address;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name=name;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password=password;
}
public String addUser() {
System.out.println("添加成功!");
User user=new User();
String name=this.name;
String password=this.password;
String username=this.username;
String address=this.address;
user.setName(name);
user.setPassword(password);
user.setUsername(username);
user.setAddress(address);
boolean b=userdaoServiceInter.insertUser(user);
if (b==true) {
return SUCCESS;
} else
return INPUT;
}
public String loginUser(){
System.out.println("登陆=======");
String name=this.name;
String password=this.password;
User user=userdaoServiceInter.querybyname(name);
if(user !=null && password.equals(user.getPassword())){
return SUCCESS;
} else
return ERROR;
}
}
UserDao.java:
package com.broada.demo.dao;
import java.util.List;
import com.broada.demo.entity.User;
public interface UserDao {
public boolean insertUser(User user);
public User queryByname(String name);
}
UserDaoImpl.java:
package com.broada.demo.daoImpl;
import org.springframework.orm.ibatis.support.SqlMapClientDaoSupport;
import com.broada.demo.dao.UserDao;
import com.broada.demo.entity.User;
public class UserDaoImpl extends SqlMapClientDaoSupport implements UserDao{
@Override
public boolean insertUser(User user) {
try {
getSqlMapClientTemplate().insert("insertUser", user);
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
@Override
public User queryByname(String name) {
// TODO Auto-generated method stub
try {
User user=(User) getSqlMapClientTemplate().queryForObject("selsectUser", name);
return user;
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
}
UserDaoServiceInter.java:
package com.broada.demo.service;
import com.broada.demo.entity.User;
public interface UserDaoServiceInter {
public boolean insertUser(User user);
public User querybyname(String name);
}
UserDaoServiceImpl.java:
package com.broada.demo.serviceImpl;
import com.broada.demo.dao.UserDao;
import com.broada.demo.entity.User;
import com.broada.demo.service.UserDaoServiceInter;
public class UserDaoServiceImpl implements UserDaoServiceInter {
private UserDao userdao;
public UserDao getUserdao() {
return userdao;
}
public void setUserdao(UserDao userdao) {
this.userdao=userdao;
}
@Override
public boolean insertUser(User user) {
return userdao.insertUser(user);
}
@Override
public User querybyname(String name) {
// TODO Auto-generated method stub
return userdao.queryByname(name);
}
}
Index.jsp:
<%@ page language="java" contentType="text/html; charset=utf8"
pageEncoding="utf8"%>
<%@ taglib prefix="s" uri="/struts-tags"%>
<!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=utf8">
<link rel="stylesheet" type="text/css" href="http://www.jb51.net/article/css/ext-all.css" />
<link rel="stylesheet" type="text/css"
href="http://www.jb51.net/article/css/ext-theme-classic-all.css" />
<script type="text/javascript" src="http://www.jb51.net/article/js/ext-all.js"></script>
<title>用户登陆</title>
<script type="text/javascript">
Ext.onReady(function(){
initPanel();
});
initPanel=function(){
var formPanel=new Ext.FormPanel({
id: 'loginPanel',
labelWidth: 75,
frame:true,
bodyStyle:'margin:0 auto',
width: 350,
defaults: {width: 250},
defaultType: 'textfield',
items: [{id: 'username',fieldLabel: '用户名',name:'name',allowBlank: false,blankText: '账号不能为空'},
{id: 'password', fieldLabel: '密 码',name:'password',inputType: 'password',allowBlank: false,blankText: '密码不能为空'}]
});
var win=new Ext.Window({
title:'登陆界面',
width:380,
autoHeight: 'true',
resizable: false,
modal:true,
closeAction: 'hide',
buttonAlign:'center',
items:formPanel,
buttons:[{text: '登陆',handler: function(){land();}},
{text: '重置',handler: function(){
Ext.getCmp('username').setValue("");
Ext.getCmp('password').setValue("");
}},{text: '注册',handler: function(){register();}}]
});
win.show();
};
var win1;
register=function(){
var registerPanel=new Ext.FormPanel({
id: 'registerPanel',
labelWidth: 75,
frame:true,
bodyStyle:'margin:0 auto',
width: 350,
defaults: {width: 250},
defaultType: 'textfield',
items: [{id: 'registername',fieldLabel: '用户名',name:'name1',allowBlank: false,blankText: '账号不能为空'},
{id: 'registerpassword', fieldLabel: '登陆密 码',name:'password1',inputType: 'password',allowBlank: false,blankText: '密码不能为空'},
{id: 'registerpassword2', fieldLabel: '密码确认',name:'password2',inputType: 'password',allowBlank: false,blankText: '密码不能为空'},
{id: 'nichen',fieldLabel: '昵称',name:'nichen1'},
{id: 'address',fieldLabel: '地址',name:'address1'}]
});
win1=new Ext.Window({
title:'注册界面',
width:380,
autoHeight: 'true',
resizable: false,
modal:true,
buttonAlign:'center',
items:registerPanel,
buttons:[{text: '提交',handler: function(){login();}},
{text: '取消',handler: function(){win1.close();}}]
});
win1.show();
};
login=function(){
var name=Ext.getCmp('registername').getValue();
var password=Ext.getCmp('registerpassword').getValue();
var password2=Ext.getCmp('registerpassword2').getValue();
var nichen=Ext.getCmp('nichen').getValue();
var address=Ext.getCmp('address').getValue();
if(name==" "|| password==" " || password2==""){
Ext.MessageBox.alert('提示','账号或密码不能为空!');
}
else if(password !=password2){
Ext.MessageBox.alert('提示','两次密码输入不一致!');
}else{
Ext.Ajax.request({
url: "<s:url value='/register.action'/>",
method: 'post',
params:{
name:name,
password:password,
username:nichen,
address:address
},
success: function (response, options) {
Ext.MessageBox.alert('提示','注册成功',function(e){
if(e=="ok"){
win1.close();
}
});
},
failure: function (response, options) {
Ext.MessageBox.alert('注册失败', '请检查您的注册信息!');
}
});
}
};
land=function(){
var name=Ext.getCmp('username').getValue();
var password=Ext.getCmp('password').getValue();
if(name==" " || password==""){
Ext.MessageBox.alert('提示', '账号或密码不能为空!');
}
else{
Ext.Ajax.request({
url: "<s:url value='/login.action'/>",
method: 'post',
params:{
name:name,
password:password
},
success: function (response, options) {
Ext.MessageBox.alert('提示','登陆成功!');
},
failure: function (response, options) {
Ext.MessageBox.alert('登陆失败', '您输入的账号或密码错误!');
}
});
}
};
</script>
</head>
<body>
</body>
</html>
大致的步骤就是这样,个人觉得ssi的框架还是蛮不错的,起码定制和自由度都比较好。
- 评论列表(网友评论仅供网友表达个人看法,并不表明本站同意其观点或证实其描述)
-
