MVC在软件架构中是一种比较重要的架构思想,已经被广泛的应用在实际的java web项目开发中,我们所要了解和掌握的是mvc的架构思想和使用mvc模式来分析和解决问题的方法。当然相同或不同的项目都有各种分析解决的思路,这里采用一个应用struts2+hibernate+jsp的实例系统来进一步分析mvc模式。

以班级管理系统为例的架构图:

首先由用户通过VIEW层对系统进行业务请求:

classAdd.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>新增班级</title>
<meta charset="utf-8" />
<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="This is my page">
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<!-- Bootstrap Styles-->
<link href="assets/css/bootstrap.css" rel="stylesheet" />
<!-- FontAwesome Styles-->
<link href="assets/css/font-awesome.css" rel="stylesheet" />
<!-- Morris Chart Styles-->
<link href="assets/js/morris/morris-0.4.3.min.css" rel="stylesheet" />
<!-- Custom Styles-->
<link href="assets/css/custom-styles.css" rel="stylesheet" />
<!-- Google Fonts-->
<link href='http://fonts.googleapis.com/css?family=Open+Sans' rel='stylesheet' type='text/css' />
<!-- TABLE STYLES-->
<link href="assets/js/dataTables/dataTables.bootstrap.css" rel="stylesheet" />
<!--
<link rel="stylesheet" type="text/css" href="styles.css">
--> </head> <body>
<div id="wrapper"> <nav class="navbar navbar-default top-navbar" role="navigation">
<div class="navbar-header">
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".sidebar-collapse">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="index.html"><i class="fa fa-comments"></i> <strong>班级管理系统</strong></a>
</div> <!-- headtop最高的mune栏 -->
<ul class="nav navbar-top-links navbar-right"> <!-- 第四个 -->
<!-- /.dropdown -->
<li class="dropdown"> <a class="dropdown-toggle" data-toggle="dropdown" href="#" aria-expanded="false">
<i class="fa fa-user fa-fw"></i> <i class="fa fa-caret-down"></i>
</a> <ul class="dropdown-menu dropdown-user"> <li><a href="#"><i class="fa fa-user fa-fw"></i> User Profile</a></li>
<li><a href="#"><i class="fa fa-gear fa-fw"></i> Settings</a></li>
<li class="divider"></li>
<li><a href="#"><i class="fa fa-sign-out fa-fw"></i> Logout</a></li>
</ul>
<!-- /.dropdown-user -->
</li>
<!-- /.dropdown -->
</ul>
</nav>
<!--/. NAV TOP --> <!-- 左侧菜单栏 -->
<nav class="navbar-default navbar-side" role="navigation">
<div id="sideNav" href=""><i class="fa fa-caret-right"></i></div>
<div class="sidebar-collapse">
<ul class="nav" id="main-menu"> <li>
<a href="index.html" class="active-menu"><i class="fa fa-sitemap"></i> 班级管理<span class="fa arrow"></span></a>
<ul class="nav nav-second-level">
<li>
<a href="classAdd.jsp">新建班级</a>
</li>
<li>
<a href="ClassInformationAction.action">班级信息</a>
</li>
</ul>
</li>
<li>
<a href="ui-elements.html"><i class="fa fa-desktop"></i>学生管理<span class="fa arrow"></a>
<ul class="nav nav-second-level">
<li>
<a href="studentAdd.jsp">添加学生</a>
</li>
<li>
<a href="StudentInformationAction.action">学生信息</a>
</li>
</ul>
</li>
<li>
<a href="chart.html"><i class="fa fa-table"></i>课程管理<span class="fa arrow"></a>
<ul class="nav nav-second-level">
<li>
<a href="courseAdd.jsp">添加课程</a>
</li>
<li>
<a href="CourseInformationAction.action">课程信息</a>
</li>
</ul>
</li>
<li>
<a href="tab-panel.html"><i class="fa fa-bar-chart-o"></i>成绩管理<span class="fa arrow"></a>
<ul class="nav nav-second-level">
<li>
<a href="#">成绩录入</a>
</li>
<li>
<a href="#">查询成绩</a>
</li>
<li>
<a href="#">成绩统计</a>
</li>
</ul>
</li>
<li>
<a href="empty.html"><i class="fa fa-fw fa-file"></i> Empty Page</a>
</li>
</ul> </div> </nav>
<!-- /. NAV SIDE --> <!-- /. NAV SIDE -->
<div id="page-wrapper">
<div id="page-inner"> <div class="row">
<div class="col-md-12">
<h1 class="page-header">班级管理<small> > 新增班级</small></h1>
</div>
</div> <!-- /. ROW -->
<div class="row">
<div class="col-lg-12">
<div class="panel panel-default"> <div class="panel-heading">
请输入新增班级信息
</div>
<div class="panel-body">
<div class="row"> <!-- /.col-lg-6 (nested) -->
<div class="col-lg-6">
<form role="form" action="ClassAddAction" method="post">
<div class="form-group has-success">
<label class="control-label" for="inputSuccess">请输入班级编号</label>
<input name="classunitnumber" type="text" class="form-control" id="inputSuccess">
</div>
<div class="form-group has-warning">
<label class="control-label" for="inputWarning">请输入班级名称</label>
<input name="classunitname" type="text" class="form-control" id="inputWarning">
</div>
<button type="submit" class="btn btn-default" onclick="add()">提 交</button>
<button type="reset" class="btn btn-default">重 置</button>
</form>
</div>
<!-- /.col-lg-6 (nested) -->
</div>
<!-- /.row (nested) -->
</div>
<!-- /.panel-body -->
</div>
<!-- /.panel -->
</div>
<!-- /.col-lg-12 -->
</div>
<!-- /. ROW -->
<footer><p>Copyright &copy; 石家庄铁道大学软件工程系</p></footer>
</div>
<!-- /. PAGE INNER -->
</div>
<!-- /. PAGE WRAPPER -->
</div> </div> <!-- /. WRAPPER -->
<!-- JS Scripts-->
<!-- jQuery Js -->
<script src="assets/js/jquery-1.10.2.js"></script>
<!-- Bootstrap Js -->
<script src="assets/js/bootstrap.min.js"></script>
<!-- Metis Menu Js -->
<script src="assets/js/jquery.metisMenu.js"></script>
<script src="assets/js/dataTables/jquery.dataTables.js"></script>
<script src="assets/js/dataTables/dataTables.bootstrap.js"></script>
<script>
$(document).ready(function () {
$('#dataTables-example').dataTable();
});
</script>
<script>
$(document).ready(function() {
$('#example').dataTable( {
"sPaginationType": "full_numbers"
});
});
function add(){
alert("添加成功!");
return true;
}
</script>
<!-- Morris Chart Js -->
<script src="assets/js/morris/raphael-2.1.0.min.js"></script>
<script src="assets/js/morris/morris.js"></script> <script src="assets/js/easypiechart.js"></script>
<script src="assets/js/easypiechart-data.js"></script> <!-- Custom Js -->
<script src="assets/js/custom-scripts.js"></script> </body>
</html>

然后由Controller层通过struts的拦截器对view层的拦截过滤,实现调用不同的业务处理逻辑。

web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.0"
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
<display-name></display-name>
<welcome-file-list>
<welcome-file>login.html</welcome-file>
</welcome-file-list> <filter>
<filter-name>struts2</filter-name>
<filter-class>
org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter
</filter-class>
</filter>
<filter-mapping>
<filter-name>struts2</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/classes/applicationContext.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener> <filter>
<filter-name>openSessionInView</filter-name>
<filter-class>org.springframework.orm.hibernate3.support.OpenSessionInViewFilter</filter-class>
</filter> <filter-mapping>
<filter-name>openSessionInView</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping> </web-app>

struts.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.1//EN" "http://struts.apache.org/dtds/struts-2.1.dtd">
<struts>
<!-- 把Struts的action交给spring托管 -->
<constant name="struts.objectFactory" value="spring"/>
<!-- 设置struts为开发模式,这样能够及时的响应修改 不过没有搞懂是什么意思-->
<constant name="struts.devMode" value="false"/>
<constant name="struts.il8n.encoding" value="UTF-8"></constant>
<!--设置上传文件大小 (20MB)-->
<constant name="struts.multipart.maxSize" value="2097152"></constant>
<!-- 定位视图资源的根路径 -->
<!-- <constant name="struts.convention.result.path" value="/WEB-INF/"></constant> -->
<!--设置struts配置文件修改以后系统是否自动重新加载该文件默认为false但是在开发环境下还是要设置成true-->
<constant name="struts.configuration.xml.reload" value="true"></constant>
<!--************************************************************************************************************ --> <package name="default" namespace="/" extends="struts-default">
<action name="LoginAction" class="LoginAction"><!-- name是jsp页面识别的名字,class是action中类的名字 -->
<result name="success">home.jsp</result>
<result name="error">login.html</result>
</action>
<!-- 班级管理 -->
<action name="ClassInformationAction" class="ClassInformationAction">
<result name="success">classInformation.jsp</result>
</action> <action name="ClassAddAction" class="ClassAddAction">
<result name="success">classAdd.jsp</result>
</action> <action name="ClassEditAction" class="ClassEditAction">
<result name="success">classInformation.jsp</result>
</action> <action name="ClassDelAction" class="ClassDelAction">
<result name="success">classInformation.jsp</result>
</action> <!-- 学生管理 -->
<action name="StudentInformationAction" class="StudentInformationAction">
<result name="success">studentInformation.jsp</result>
</action> <action name="StudentAddAction" class="StudentAddAction">
<result name="success">studentAdd.jsp</result>
</action> <action name="StudentEditAction" class="StudentEditAction">
<result name="success">studentInformation.jsp</result>
</action> <action name="StudentDelAction" class="StudentDelAction">
<result name="success">studentInformation.jsp</result>
</action> </package> </struts>

找到相应的action去处理相应的业务:

ClassAddAction.java

package com.zdr.action;

import com.opensymphony.xwork2.ActionSupport;
import com.zdr.entity.Classunit;
import com.zdr.service.ClassunitService; public class ClassAddAction extends ActionSupport{
//变量
private String classunitname = "";
private String classunitnumber = "";
private String result = "";
private ClassunitService classunitService;
private Classunit classnumber; //函数
public String getClassunitname() {
return classunitname;
}
public void setClassunitname(String classunitname) {
this.classunitname = classunitname;
}
public String getClassunitnumber() {
return classunitnumber;
}
public void setClassunitnumber(String classunitnumber) {
this.classunitnumber = classunitnumber;
}
public String getResult() {
return result;
}
public void setResult(String result) {
this.result = result;
}
public ClassunitService getClassunitService() {
return classunitService;
}
public void setClassunitService(ClassunitService classunitService) {
this.classunitService = classunitService;
} @Override
public String execute() throws Exception
{
if(classunitService.checkClassnumber(getClassunitnumber()))
{
//result = "班级编号重复!";
return ERROR;
}
else
{
classnumber = new Classunit();
classnumber.setClassNumber(classunitnumber);
classnumber.setClassName(classunitname);
classunitService.addClassunit(classnumber);
}
return SUCCESS;
} }

通过调用关系,调用model层dao层方法完成业务处理:

package com.zdr.dao;

import java.util.List;
import java.util.Set;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.hibernate.Criteria;
import org.hibernate.LockMode;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.criterion.Restrictions;
import org.springframework.context.ApplicationContext;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport; import com.zdr.entity.Classunit;
import com.zdr.entity.Student; /**
* A data access object (DAO) providing persistence and search support for
* Classunit entities. Transaction control of the save(), update() and delete()
* operations can directly support Spring container-managed transactions or they
* can be augmented to handle user-managed Spring transactions. Each of these
* methods provides additional information for how to configure it for the
* desired type of transaction control.
*
* @see com.zdr.entity.Classunit
* @author MyEclipse Persistence Tools
*/
public class ClassunitDAO extends HibernateDaoSupport {
private static final Log log = LogFactory.getLog(ClassunitDAO.class);
private SessionFactory sessionFactory;
private Session session;
// property constants
public static final String CLASS_NAME = "className"; protected void initDao() {
// do nothing
} public boolean checkClassnumber(String classunitnumber)
{
if(classunitnumber!= null)
{
Classunit cun = findById(classunitnumber);
if(cun == null)
{
return false;
}
}
return true;
} public Classunit findclassunitnumber(String classunitnumber)
{
if(classunitnumber!=null)
{
return findById(classunitnumber);
}
return null; } public void save(Classunit transientInstance) {
log.debug("saving Classunit instance");
try {
getHibernateTemplate().save(transientInstance);
log.debug("save successful");
} catch (RuntimeException re) {
log.error("save failed", re);
throw re;
}
} public void delete(Classunit persistentInstance) {
log.debug("deleting Classunit instance");
try {
getHibernateTemplate().delete(persistentInstance);
log.debug("delete successful");
} catch (RuntimeException re) {
log.error("delete failed", re);
throw re;
}
} public Classunit findById(java.lang.String id) {
log.debug("getting Classunit instance with id: " + id);
try {
Classunit instance = (Classunit) getHibernateTemplate().get(
"com.zdr.entity.Classunit", id);
return instance;
} catch (RuntimeException re) {
log.error("get failed", re);
throw re;
}
} public List<Classunit> findByExample(Classunit instance) {
log.debug("finding Classunit instance by example");
try {
List<Classunit> results = (List<Classunit>) getHibernateTemplate()
.findByExample(instance);
log.debug("find by example successful, result size: "
+ results.size());
return results;
} catch (RuntimeException re) {
log.error("find by example failed", re);
throw re;
}
} public List findByProperty(String propertyName, Object value) {
log.debug("finding Classunit instance with property: " + propertyName
+ ", value: " + value);
try {
String queryString = "from Classunit as model where model."
+ propertyName + "= ?";
return getHibernateTemplate().find(queryString, value);
} catch (RuntimeException re) {
log.error("find by property name failed", re);
throw re;
}
} public List<Classunit> findByClassName(Object className) {
return findByProperty(CLASS_NAME, className);
} public List<Classunit> findAll() {
log.debug("finding all Classunit instances");
try {
String queryString = "from Classunit";
return getHibernateTemplate().find(queryString);
} catch (RuntimeException re) {
log.error("find all failed", re);
throw re;
}
} public Classunit merge(Classunit detachedInstance) {
log.debug("merging Classunit instance");
try {
Classunit result = (Classunit) getHibernateTemplate().merge(
detachedInstance);
log.debug("merge successful");
return result;
} catch (RuntimeException re) {
log.error("merge failed", re);
throw re;
}
} public void attachDirty(Classunit instance) {
log.debug("attaching dirty Classunit instance");
try {
getHibernateTemplate().saveOrUpdate(instance);
log.debug("attach successful");
} catch (RuntimeException re) {
log.error("attach failed", re);
throw re;
}
} public void attachClean(Classunit instance) {
log.debug("attaching clean Classunit instance");
try {
getHibernateTemplate().lock(instance, LockMode.NONE);
log.debug("attach successful");
} catch (RuntimeException re) {
log.error("attach failed", re);
throw re;
}
} public static ClassunitDAO getFromApplicationContext(ApplicationContext ctx) {
return (ClassunitDAO) ctx.getBean("ClassunitDAO");
}
}

处理结果再由struts.xml去返回相应的结果所对应的业务方向。

调用关系图:

总结:

当用户通过view层向系统发送业务请求时,struts.xml根据已经定义好的处理逻辑进行相应的处理,将其业务分给指定的action来处理。而model层通过不同的业务逻辑调用实现试图和逻辑的分层,由action去调用相应的dao层业务进行业务逻辑处理,处理结果再由struts.xml去返回相应的结果所对应的业务方向。

通过mvc体现的质量属性:

可修改性:将视图与业务逻辑分离,易于业务的变动和修改。

MVC模式在Java Web应用程序中的实例分析的更多相关文章

  1. SpringMVC内容略多 有用 熟悉基于JSP和Servlet的Java Web开发,对Servlet和JSP的工作原理和生命周期有深入了解,熟练的使用JSTL和EL编写无脚本动态页面,有使用监听器、过滤器等Web组件以及MVC架构模式进行Java Web项目开发的经验。

    熟悉基于JSP和Servlet的Java Web开发,对Servlet和JSP的工作原理和生命周期有深入了解,熟练的使用JSTL和EL编写无脚本动态页面,有使用监听器.过滤器等Web组件以及MVC架构 ...

  2. Java嵌入式数据库H2学习总结(二)——在Web应用程序中使用H2数据库

    一.搭建测试环境和项目 1.1.搭建JavaWeb测试项目 创建一个[H2DBTest]JavaWeb项目,找到H2数据库的jar文件,如下图所示: H2数据库就一个jar文件,这个Jar文件里面包含 ...

  3. 【转】Tomcat中部署java web应用程序

    http://www.blogjava.net/jiafang83/archive/2009/06/02/279644.html 转载:今天给大家介绍怎样在Tomcat5.5.9中部署Java Web ...

  4. 在Tomcat中部署Java Web应用程序

    在Tomcat中部署Java Web应用程序有两种方式:静态部署和动态部署.在下文中$CATALINA_HOME指的是Tomcat根目录. 一.静态部署      静态部署指的是我们在服务器启动之前部 ...

  5. 在 ASP.NET MVC Web 应用程序中输出 RSS Feeds

    RSS全称Really Simple Syndication.一些更新频率较高的网站可以通过RSS让订阅者快速获取更新信息.RSS文档需遵守XML规范的,其中必需包含标题.链接.描述信息,还可以包含发 ...

  6. Tomcat中部署Java Web应用程序的方式

    Tomcat中部署Java Web应用程序的几种方式: #PetWeb是工程名 1.在TOMCAT_HOME\conf\server.xml文件的HOST节点中加入 <Context docBa ...

  7. 在Tomcat中部署Java Web应用程序几种方式

    在Tomcat中部署Java Web应用程序有两种方式:静态部署和动态部署.在下文中$CATALINA_HOME指的是Tomcat根目录. 一.静态部署      静态部署指的是我们在服务器启动之前部 ...

  8. 【jframe】Java Web应用程序框架 - 第01篇:Get Started

    jframe是什么? jframe是一个基于MIT协议开源的java web应用程序框架,汇聚了我们团队之于java web应用程序的核心架构思想以及大量最佳实践,并且持续在实际项目中不断完善优化. ...

  9. Java Web应用开发中的一些概念

    最近在学习Java Web,发现Java Web的概念很多,而且各个概念之间的关系也挺复杂,本篇博客把这些关系总结于此,主要参考的博客附在文章末尾. 概念 服务器 服务器,硬件角度上说就是一台高性能的 ...

随机推荐

  1. Python Strings

    1. Basic #Python treats single quotes the same as double quotes. var = 'haha' var = "666" ...

  2. LCS(最长公共子序列)动规算法正确性证明

    今天在看代码源文件求diff的原理的时候看到了LCS算法.这个算法应该不陌生,动规的经典算法.具体算法做啥了我就不说了,不知道的可以直接看<算法导论>动态规划那一章.既然看到了就想回忆下, ...

  3. python变量、引用、拷贝之间的关系

    Python中一切皆为对象,不管是集合变量还是数值型or字符串型的变量都是一个引用,都指向对应内存空间中的对象. 简而言之: 变量直接赋值:新变量本身及其内部的元素都与原变量指向相同的内存空间,并且值 ...

  4. IOS 阻止 锁屏

    [UIApplication sharedApplication].idleTimerDisabled=YES;不自动锁屏 idleTimerDisabled

  5. 使用ffmpeg合并视频文件的三种方法

    ffmpeg合并视频的方法有三种.国内大多数仅介绍了其中之一.于是觉得有必要翻译一下.其实在ffmpeg的 FAQ文档中有比较详细的说明. 使用concat协议进行视频文件的合并 这种方式的适用场景是 ...

  6. CBCentralManager Class 的相关分析

    Overview 总体概述 CBCentralManager objects are used to manage discovered or connected remote peripheral ...

  7. 网页静态化—redis | freemarker

    1.   学习计划 1.商品详情页面展示,动态展示 jsp + redis 2.使用freemarker实现网页静态化 3.ActiveMq同步生成静态网页 两个方案对比,方案一依赖web容器,red ...

  8. Solo and Mute

    [Solo and Mute ] Muting means a transition will be disabled. Soloed transtions are enabled and with ...

  9. Excel VBA入门(二)数组和字典

    数组和字典也是VBA的常用到数据类型之一.但是我翻了有四五本VBA教程相关的书,里面都没有介绍到字典,数组到是在介绍数据类型时有介绍,而并没有提到字典. 事实上,字典不是VBA内置的类型,它是Wind ...

  10. Lucene介绍及简单入门案例(集成ik分词器)

    介绍 Lucene是apache软件基金会4 jakarta项目组的一个子项目,是一个开放源代码的全文检索引擎工具包,但它不是一个完整的全文检索引擎,而是一个全文检索引擎的架构,提供了完整的查询引擎和 ...