MVC模式在Java Web应用程序中的实例分析
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 © 石家庄铁道大学软件工程系</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应用程序中的实例分析的更多相关文章
- SpringMVC内容略多 有用 熟悉基于JSP和Servlet的Java Web开发,对Servlet和JSP的工作原理和生命周期有深入了解,熟练的使用JSTL和EL编写无脚本动态页面,有使用监听器、过滤器等Web组件以及MVC架构模式进行Java Web项目开发的经验。
熟悉基于JSP和Servlet的Java Web开发,对Servlet和JSP的工作原理和生命周期有深入了解,熟练的使用JSTL和EL编写无脚本动态页面,有使用监听器.过滤器等Web组件以及MVC架构 ...
- Java嵌入式数据库H2学习总结(二)——在Web应用程序中使用H2数据库
一.搭建测试环境和项目 1.1.搭建JavaWeb测试项目 创建一个[H2DBTest]JavaWeb项目,找到H2数据库的jar文件,如下图所示: H2数据库就一个jar文件,这个Jar文件里面包含 ...
- 【转】Tomcat中部署java web应用程序
http://www.blogjava.net/jiafang83/archive/2009/06/02/279644.html 转载:今天给大家介绍怎样在Tomcat5.5.9中部署Java Web ...
- 在Tomcat中部署Java Web应用程序
在Tomcat中部署Java Web应用程序有两种方式:静态部署和动态部署.在下文中$CATALINA_HOME指的是Tomcat根目录. 一.静态部署 静态部署指的是我们在服务器启动之前部 ...
- 在 ASP.NET MVC Web 应用程序中输出 RSS Feeds
RSS全称Really Simple Syndication.一些更新频率较高的网站可以通过RSS让订阅者快速获取更新信息.RSS文档需遵守XML规范的,其中必需包含标题.链接.描述信息,还可以包含发 ...
- Tomcat中部署Java Web应用程序的方式
Tomcat中部署Java Web应用程序的几种方式: #PetWeb是工程名 1.在TOMCAT_HOME\conf\server.xml文件的HOST节点中加入 <Context docBa ...
- 在Tomcat中部署Java Web应用程序几种方式
在Tomcat中部署Java Web应用程序有两种方式:静态部署和动态部署.在下文中$CATALINA_HOME指的是Tomcat根目录. 一.静态部署 静态部署指的是我们在服务器启动之前部 ...
- 【jframe】Java Web应用程序框架 - 第01篇:Get Started
jframe是什么? jframe是一个基于MIT协议开源的java web应用程序框架,汇聚了我们团队之于java web应用程序的核心架构思想以及大量最佳实践,并且持续在实际项目中不断完善优化. ...
- Java Web应用开发中的一些概念
最近在学习Java Web,发现Java Web的概念很多,而且各个概念之间的关系也挺复杂,本篇博客把这些关系总结于此,主要参考的博客附在文章末尾. 概念 服务器 服务器,硬件角度上说就是一台高性能的 ...
随机推荐
- 【C++】
C++声明function后面加上等于0(=0)何解? https://zhidao.baidu.com/question/1446181256925153340.html
- Django学习---自定义分页
自定义分页 简单例子: urls.py: from django.contrib import admin from django.urls import path from django.conf. ...
- C# 生成序号不足补0
int Num=13 var code =Num.ToString().PadLeft(4, '0'); code:0013
- 跟我学算法-tensorflow 实现logistics 回归
tensorflow每个变量封装了一个程序,需要通过sess.run 进行调用 接下来我们使用一下使用mnist数据,这是一个手写图像的数据,训练集是55000*28*28, 测试集10000* 28 ...
- sitemap和sitemapindex
介绍: https://support.google.com/webmasters/answer/75712?hl=zh-Hans 实例: http://www.thepaper.cn/sitemap ...
- 【转】SVN 与 GIT 详细对比
git和svn的详细对比 近期就[版本管理工具是否进行切换SVN->Git]的问题进行了讨论,于是对svn和Git进行了相关研究,进而梳理出Git的特点(优.缺点),最后将Git与SVN进行 ...
- C#路径的相关操作
1.判定一个给定的C#路径是否有效,合法 通过Path.GetInvalidPathChars或Path.GetInvalidFileNameChars方法获得非法的C#路径/文件名字符,可以根据它来 ...
- 前端开发之CSS篇二
主要内容: 一.CSS的继承性和层叠性 二.盒模型 三.padding属性 四.border属性 五.margin属性 六.标准文档流 七.行内元素和块状元素转换 1️⃣ CSS的继承性和层叠性 1 ...
- 135. Candy(Array; Greedy)
There are N children standing in a line. Each child is assigned a rating value. You are giving candi ...
- Java中文乱码解决方案
Java中文乱码解决方案 1.中文乱码解决方案,确保每个文件的默认编码是UTF-8 加入 URIEncoding="UTF-8" 代码中的设置 1>在se ...