当前位置: 移动技术网 > IT编程>开发语言>Java > ssi框架学习总结(mvc三层架构)

ssi框架学习总结(mvc三层架构)

2017年12月12日  | 移动技术网IT编程  | 我要评论

3456网址大全,lzr种子,智能家居设备

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

框架结构:

这是我在网上找到的一张关于ssi框架的结构图,个人感觉画的还是蛮不错的,对于入门者来说,层次机构很清晰,比较实用(感谢这位大大的分享):

ssi框架学习总结

在这里可以很明显的看出ssi框架的大体结构以及各层之间的交互情况,顶层表现层的话,就java而言主要是jsp,html等视图层技术的编写,其中涉及我们熟悉的javascript,jquery以及extjs等。在控制层来说的话,主要是利用strust2标签功能实现action与视图层的数据交互,当然也可以使用ajax的技术实现同样的功能,这个就按个人喜好而来了。在业务逻辑层。主要是利用spring的依赖注入实现对业务逻辑类和dao类的实例托管,当然各类的实例都可以托管在spring中进行统一管理和关联,包括事务,数据源等等。在持久层,利用ibatis提供的半自动化对象关系映射的实现,开发人员可以根据需要编写具体的sql语句,通过相应的xml的配置实现对数据库的操作。

总之,ssi框架能够降低我们代码的耦合度,增强了代码的健壮性和可重用性,加快了开发速度,但是也有一些不足之处,比如由于三种框架的配置文件较多,也给我们带来了一些不便,特别是对于较小的应用来说更是如此。

相关demo介绍:

基于之前对ssi框架的学习,我也不能免俗滴选择了做一个用户管理的web实现,项目的大致框架如下:

ssi框架学习总结

大体上还是按照三层的分层模型来是分的,具体就不详细说了,相信大家也应该很了解整个结构的。

ø  开发环境简介:

工具:eclipse3.6+tomcat7+mysql5.1

框架:struts2,spring3.0.5,ibatis2.3.4.726

开发步骤及配置简介:

第一步,众所周知肯定是导入相关的lib库啦,由于我使用的前端是extjs,所以还需要导入extjs相关的js以及css依赖文件。由于lib库太多就不截图了,只截取extjs的相关依赖文件:

ssi框架学习总结

这样基本的环境就有了,数据库的设计则需要根据model层的对象来确定。 

第二步,建立相关的model层,代码如下:

user.java:

package com.broada.demo.entity;
/**
 * 
 * @author smm
 *
 */
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>/*</url-pattern>
  </filter-mapping>

strust.xml:

<?xml version="1.0" encoding="utf-8"?>
<!doctype struts public "-//apache software foundation//dtd struts configuration 2.0//en"
"http://struts.apache.org/dtds/struts-2.0.dtd">
<struts>
  <!-- 这是一个重要的地方,很多人在使用<s:include>子页面后,发现子页面乱码,怎么改都不行,原因就在次,struts2的默认编码为utf-8,乱码的同志请看看你的jsp页面上的编码是不是和这个不一致呢。只要把这里和jsp编码改一致就行了 -->
  <constant name="struts.i18n.encoding" value="utf-8" />
	<!-- 告诉struts2,我要用spring装配工厂,其实默认就是这个了-_-!!! -->
  <constant name="struts.objectfactory" value="spring" />
	<!-- struts2的扩展名,比如struts1的时候,用的.do,struts2默认为.action,可以改成其它的,比如.dxd -->
  <constant name="struts.action.extension" value="action" />
	<!-- 资源文件 -->
  <constant name="struts.custom.i18n.resources"
    value="messageresource">
  </constant> 
 
  <!-- 用户注册类 -->
	<!-- abstract属性就说明了该action继承自自己定义的基础action,而class采用的registeraction是由spring产生的 -->
  <package name="register" extends="struts-default">
    <action name="register" class="registeraction" method="adduser">
      <!-- 注册成功 -->
      <result name="success">success.jsp</result>
      <!-- 注册失败 -->
      <result name="input">error.jsp</result>
    </action>
    <action name="login" class="registeraction" method="loginuser">
    	<!-- 注册成功 -->
      <result name="success">success.jsp</result>
      <!-- 注册失败 -->
      <result name="error">error.jsp</result>    	
    </action>
  </package> 
</struts>

这样strust的配置大致就完成了。 

第四步:配置ibatis的相关配置文件,主要是jdbc.propertiessqlmapconfig.xml以及user.xml的配置,jdbc.properties主要用于配置数据库的数据源参数,会在加载spring的时候自动初始化,ibatis数据源的配置到时可以托管给spring初始化,所以这里就不细讲了。sqlmapconfig.xml主要是配置ibatis的配置文件的位置,user.xml则用于编写相关的数据库语句等,配置大致如下:

jdbc.properties:

jdbc.driverclass=com.mysql.jdbc.driver
jdbc.url=jdbc:mysql://localhost:3306/userinfo
jdbc.user=root
jdbc.password=123456
jdbc.minpoolsize=5
jdbc.maxpoolsize=20
jdbc.maxidletime=1800
jdbc.acquireincrement=5
jdbc.maxstatements=50
jdbc.initialpoolsize=10
jdbc.idleconnectiontestperiod=1800
jdbc.acquireretryattempts=30

详细的参数含义在spring的配置文件会提及,就不细说了。

sqlmapconfig.xml

<?xml version="1.0" encoding="utf-8" ?>
<!doctype sqlmapconfig public "-//ibatis.apache.org//dtd sql map config 2.0//en"
"http://ibatis.apache.org/dtd/sql-map-config-2.dtd">
<sqlmapconfig>
<!-- 用户信息表 -->
<sqlmap resource="com/broada/demo/dao/ibaties/map/user.xml" />
</sqlmapconfig>

user.xml:

<?xml version="1.0" encoding="utf-8" ?>
<!doctype sqlmap public "-//ibatis.apache.org//dtd sql map 2.0//en"   
"http://ibatis.apache.org/dtd/sql-map-2.dtd">
<sqlmap>
  <typealias alias="user" type="com.broada.demo.entity.user" />
  <!-- 保存注册信息 -->
  <insert id="insertuser" parameterclass="user">
    insert into
    user (name,password,username,address)values(#name#,#password#,#username#,#address#)
  </insert>
  
  <select id="selsectuser" parameterclass="java.lang.string" resultclass="user">
  	select * from user
  	where name = #name#;
  </select>
</sqlmap>

这样,ibatis的配置大致就完成。

第五步:配置spring的相关配置文件,主要是整合ibatis以及strust中用到的bean,需要配置web.xml以及applicationcontext-web.xml两个配置文件:

web.xml:

<listener>
    <!-- 这个就是今后用到的webapplicationutilcontent -->
    <listener-class>
			org.springframework.web.context.contextloaderlistener
    </listener-class>
  </listener>
  <!-- springframework config files -->
  <context-param>
    <param-name>contextconfiglocation</param-name>
    <!-- 把spring的配置文件放到了/web-inf/下的springframework包里,方便统一管理,命名规则是以applicationcontent-开头的xml文件,初始化时会自动搜索所有符合规则的配置文件 -->
    <param-value>
      /web-inf/spring/applicationcontext-*.xml
    </param-value>
</context-param>

applicationcontext-web.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"
  xsi:schemalocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd">
  <!-- 配置数据源,连接池采用的是c3p0,具体各参数代表意义参看c3p0自带的doc,非常详细。 -->
  <bean id="datasource"
    class="com.mchange.v2.c3p0.combopooleddatasource"
    destroy-method="close">
    <property name="driverclass" value="${jdbc.driverclass}" />
    <property name="jdbcurl" value="${jdbc.url}" />
    <property name="user" value="${jdbc.user}" />
    <property name="password" value="${jdbc.password}" />
    <property name="minpoolsize" value="${jdbc.minpoolsize}" />
    <property name="maxpoolsize" value="${jdbc.maxpoolsize}" />
    <property name="maxidletime" value="${jdbc.maxidletime}" />
    <property name="acquireincrement"
      value="${jdbc.acquireincrement}" />
    <property name="maxstatements" value="${jdbc.maxstatements}" />
    <property name="initialpoolsize"
      value="${jdbc.initialpoolsize}" />
    <property name="idleconnectiontestperiod"
      value="${jdbc.idleconnectiontestperiod}" />
    <property name="acquireretryattempts"
      value="${jdbc.acquireretryattempts}" />
  </bean>
 
  
  <!-- 上面的数据源的value值用的是表达式,原因就在这里,这将配置文件放到了ibatis目录下,也就是jdbc.properties,设置了c3p0的各项参数 -->
  <bean id="propertyconfig"
    class="org.springframework.beans.factory.config.propertyplaceholderconfigurer">
    <property name="location">
      <value>/web-inf/ibatis/jdbc.properties</value>
    </property>
  </bean> 
  
  <!-- 配置ibatis的sqlmapclient,这里当然是交给了spring去处理,其中,将sqlmapconfig文件放到了web-inf的ibatis目录下,也是便于管理 -->
  <bean id="sqlmapclient"
    class="org.springframework.orm.ibatis.sqlmapclientfactorybean">
    <property name="configlocation">
      <value>/web-inf/ibatis/sqlmapconfig.xml</value>
    </property>
    <!-- 这里使用的数据源就是上面配置的数据源 -->
    <property name="datasource">
      <ref bean="datasource" />
    </property>
  </bean> 
 
  <bean id="userdaoid" class="com.broada.demo.daoimpl.userdaoimpl">
   	<property name="sqlmapclient" ref="sqlmapclient"></property>
  </bean>
   
  <bean id="userdaoserviceid" class="com.broada.demo.serviceimpl.userdaoserviceimpl">
   <property name="userdao" ref="userdaoid">
  </property>
  </bean> 
   <!-- 用户注册action--> 
  <bean id="registeraction" name="registeraction" class="com.broada.demo.action.registeraction" scope="prototype">    
   <property name="userdaoserviceinter" ref="userdaoserviceid"></property>
  </bean> 
  
  
</beans>

这样,ssi框架的大致配置就完成了。 

最后编写相关的dao层,service层,action层以及jsp等等,我就不详细说明了,直接上相关代码:

registeraction.java:

package com.broada.demo.action;
 
/**
 * @author smm
 */
 
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;
 
/**
 * @author smm
 */
 
import java.util.list;
 
import com.broada.demo.entity.user;
 
public interface userdao {
	
	/**
	 * 用户注册
	 * @param user
	 * @return
	 */
	
	public boolean insertuser(user user);
	
	/**
	 * 根据用户名获取用户信息
	 * @param name
	 * @return
	 */
	
	public user querybyname(string name);	
}

userdaoimpl.java

package com.broada.demo.daoimpl;
/**
 * @author smm
 */
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;
 
/**
 * @author smm
 */
 
import com.broada.demo.entity.user;
 
public interface userdaoserviceinter {
	
	/**
	 * 用户注册服务接口
	 * @param user
	 * @return
	 */
	
	public boolean insertuser(user user);
	
	/**
	 * 根据用户名获取用户信息接口
	 * @param name
	 * @return
	 */
	
	public user querybyname(string name);
}

userdaoserviceimpl.java

package com.broada.demo.serviceimpl;
 
/**
 * @author smm
 */
 
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="css/ext-all.css" />
<link rel="stylesheet" type="text/css"
	href="css/ext-theme-classic-all.css" />
<script type="text/javascript" src="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的框架还是蛮不错的,起码定制和自由度都比较好。

如对本文有疑问,请在下面进行留言讨论,广大热心网友会与你互动!! 点击进行留言回复

相关文章:

验证码:
移动技术网