Java Web:我对架构中分层的理解暨 Bigfoot Web 框架简介

本文涉及的产品
数据传输服务 DTS,数据迁移 small 3个月
推荐场景:
MySQL数据库上云
简介: J2EE 世界充斥着许多概念,如 MVC、Service、DAO 等等,而且这些许多都是“似是而非”的名词。如果不对这些概念进行厘清,恐怕不能全然贯通、明晰整个框架。这就体现了概念其重要性。鄙人希望:一、概念虽然会比较”笼统“,——这是因为概念处于较高层的位置,有涵盖的作用,但应该尽量明晰和收窄定义的范围;二、从概念到某件事物,是”抽象“到”具象“的过程,会形成某个特定”名词“,既然”名词“是特指的,那么应该没有二义性,即没有歧义;三、概念最后能找到真正所对应的具体事物,可以在代码中反映出来的。

J2EE 世界充斥着许多概念,如 MVC、Service、DAO 等等,而且这些许多都是“似是而非”的名词。如果不对这些概念进行厘清,恐怕不能全然贯通、明晰整个框架。这就体现了概念其重要性。鄙人希望:一、概念虽然会比较”笼统“,——这是因为概念处于较高层的位置,有涵盖的作用,但应该尽量明晰和收窄定义的范围;二、从概念到某件事物,是”抽象“到”具象“的过程,会形成某个特定”名词“,既然”名词“是特指的,那么应该没有二义性,即没有歧义;三、概念最后能找到真正所对应的具体事物,可以在代码中反映出来的。凡事须顾名思义,有其名就当有其实;四、理想情况下,一个系统不应存在重复的代码或模块。如果赋予一个事物有一个概念或名词 A,A 具有排他性,不能再使用,但可以包含其所属的 B 事物。即,A 是 A,B 是 B。如果 A 包含 B,那么 A ≠ B。

需要指出的是,本文所讨论的定义对其他框架不一定适用,请不要周延,当前仅限于 Bigfoot 界定概念所用——这也是为了避免争议的提前声明,同时这样也比较简单,点到即止。

基础概念

分层是应对复杂性的必然手段。解决一个个各自的小问题,最终来解决大问题,“分而治之”。

程序三层结构,毋庸置疑。


与数据库打交道的三个方法

以上脑图参考自《三层究竟如何?》

我们比较推崇“半自动 SQL”的方法,既非直接写 SQL,也不是 ORM(也不熟悉 存储过程)。此方面的具体内容,参见前篇文章《浅浅地封装一层 JDBC》

一般 SSH 结构

虽然有经典 SSH 架构摆在面前,但我们并不拘泥于此,同样积极寻找适应项目变化,可重用,方便程序员的架构方法,以适应于“互联网程序架构”而非单单“企业级开发”的架构。

JavaEE 体系架构

JavaEE 体系架构采用传统的 MVC 设计模式,分为 Model、View、Controller 三层,其中:Model 即模型层,定义数据模型和业务逻辑。

为了将数据访问与业务逻辑分离,提高业务精度,降低代码之间的耦合,模型层又细分为 DAO 层与 Service 业务层,DAO 全称为 Data Access Object(数据访问对象),将数据库访问代码封闭起来,MyBatis API 也在此封装,不再出现在其他层或向其他层暴露;业务层是整个系统最核心也最具价值的一层,该层对应用程序的业务逻辑进行封装,务求关注客户需求,在业务处理过程中会访问原始数据或产生新数据,或者需要持久化数据,DAO 层提供的 DAO 类能很好地帮助业务层完成数据处理,业务层本身则侧重于对客户需求的理解和业务规则的适应,自然也包括大部分的计算。

总体说来,DAO 不处理业务逻辑,只做与存取数据有关的获取原始数据或持久化数据等操作,为业务层提供辅助。

View 即视图层,为最终用户提供一个友好的交互界面,用户可以查看请求结果,也可以通过表单等交互手段实现数据录入。

Controller 层即控制器,他是 Model 与 View的桥梁,将二者很好的衔接,通过 View 接收用户数据,Controller 将数据传输给Model,Model 对数据进行处理;或者 Model 读取数据后,Controller 将数据传递给 View,View 向用户展示数据。一来一往,Controller 成了 Model 与 View 之间的快乐使者。具体来说,Controller 负责数据验证,跳转逻辑,赋值/取值。这里会出现 Request/Response 对象——但将 Request/Response 对象放到其他层就不合适了,举个反例,如果在 Service 层出现 Request/Response 对象那么有必要进行重构修正了。

  • 从调用关系上看,左为高层,右为低层,下为高层,上为低层,高层可以调用低层,但低层不能调用高层,层与层之间的调用是单向的。
  • 从数据传输上看,数据可以从视图层传输到 DAO 进而保存到数据库,也可以从数据库中读取数据进行处理或者显示,所以数据的传输是双向的。
  • 从技术实现上看,视图层使用 HTML/JSP 组件实现,控制器使用 Servlet 或 Action 组件实现,模型层使用 JavaBean 组件或 EJB 技术实现。

MyBatis 封装在 DAO 层,负责数据访问操作;Spring MVC 充当控制器角色,对用户数据进行合法性检验和类型转换,为视图层提供标签简化页面显示,提供国际化支持等等;Spring是应用程序的管家,DAO、Service(业务)、Action 等对象由 Spring 创建并维护各对象之间关系,同时提供声明式事务管理,简化事务编程。

MVC 结构

可维护的结构



MVC 是个大领纲,不同的框架对 MVC 的理解和实践都不尽相同,有时候甚至很难一一对号入座,也有许多衍生分支的版本。实际上,MVC 是一种模式,模式不是公式,所以除了必要的条件限定之外,就没有一定的条条框框。

注意,前面说到的三层架构 ≠ MVC。

除了经典的 JSP + Bean + Servlet 架构外,还有一种更为简单的 JSP + Bean 模式。两者区别在于处理的主控部分不同。前者利用 Servlet 作为主控部分;后者利用 JSP 作为主控部分,将用户的请求、Bean 和事件响应有效的连接起来。

我比较倾向于 JSP + Bean 模式。该模式工作原理是:当 HTTP 发出请求时,JSP 接收请求并访问 Bean,当需要访问数据库或者服务器时,则通过  Bean 做相应处理。Bean 将处理的结果返回 JSP,JSP 生成动态 html 将结果传送到浏览器并显示,用户得到交互结果。JSP 作为视图,同时也有部分控制器的功能, Bean 组件作为模型和控制器组件。

这样的好处是首先不用配置 Servlet,一个 JSP 即是 Servlet(请求路径多起来维护麻烦),其次是 JSP 以显示为中心,它为 Web 前端开发提供了更方便的开发。再者是仍然可以做到显示和内容分离,显示和业务逻辑开发可以分开同时进行,实际上并不会在 JSP 嵌入大量 Java 代码,而且显得更简单。

必须提出的是,纯 service 接口的话应该使用 Bean + Servlet 的模式,那是完全排除表示层的考虑。


前端分层,围绕 HTML、CSS、JS 三大模块来处理。


模板技术我主张使用 Tag Files。有关 Tag Files 的更多教程,参见本博客《JSP Tag Files 技术总结》

项目选型

经过反复使用和衡量,决定采用下面的组件。分有前端和后端的(点击图片放大)。


前端堆栈我的方案如下:



Bigfoot 简介

“大脚 Bigfoot”是一款基于 JEE 平台研发的 Web 框架,继承了 Java 平台的高效、安全、稳定、跨平台等诸多优势,但却摒弃了传统 SSH 企业级架构所带来的庞大和臃肿,汲取了 PHP 的简洁和方便,非常适合互联网中小型网站的应用。

Bigfoot 是真正的开源、真正的免费,其代码直观、简洁,功能方面简单实用。该系统没有去做审核流程、复杂权限和日志等企业级的功能。对于这些功能,中小型互联网项目或许不是首要考虑;当前版本力求简单和通俗易懂的代码,也就是作为基础框架而考虑的。同时大脚也注重扩展性——更复杂的功能,可以留待二次开发。

个人认为 Java 在互联网应用之所以不及 PHP 那么受欢迎,其中一个主要是因为技术人员过分追求复杂的技术架构和为概念应用而应用(怕别人说技术不专业);搞得草根都不敢去用 Java 去了;于是这样的结果是严重阻碍了 Java 在互联网的应用和推广——而 PHP 在互联网的成功在于:简单和务实(PHP 的织梦成功正是这个原因)。我们的理念:Keep it simple, stupid,做一款简单实用的开源 Web。

迈普 CMS(MyPro Content Manage System)是以 Bigfoot 基础框架为依托的网站管理系统,具有懂 HTML 就能建站的优点,提供最便利、合理的使用方式。前端模板完全开放,可让用户随心所欲的自定义显示内容和显示方式。

“大脚 Bigfoot”整体特性:

  1. 免费、简单、开源
  2. 代码行数少,概念清晰,避免过渡设计
  3. 力求高聚合、低耦合
  4. 全栈式方案,包括前端控件和服务端接口,无缝对接
  5. 基于 JVM 的混合语言编程 = Java + JavaScript(服务端 Rhino)
  6. 基于 Java 1.7,积极采用 1.7 新语法,如 autoClose、多项异常抛出
  7. 特别适合从前端过来的开发人员,提供服务端 JS 环境
  8. 完备的文档、代码注释,并提供 JUnit 单元测试
  9. 谨慎采用第三方库,当前免 JAR 依赖(除数据库驱动外)。提倡“够用就好、就地取材”,例如,日志采用 JDK 自带的 Logger、JSON 转换让 JDK 自带的 Rhino 转换、数据连接池采用 Tomcat 自带的 Pool、页面标签就用 TagFiles/SimpleTag 甚至就是连 <%=……Java Code %> 都可以、使用 JSON 或 Map 作为通用的、交换的数据结构。

控制层特性:

  1. 回归简单性,结合灵活的 MVC 思想,强调前端、后端相分离,前端 = JavaBean + JSP;后端 JavaBean + Servlet。
  2. 基于 JSONTree 无序树的无限极分类,结构清晰,可维护性强。
  3. 提倡面向接口编程,实现了一个小型的 IOC 依赖注射和 AOP。
  4. 支持 JSON API 输出纯数据,与安卓、iOS、AJAX 甚至广义的客户端等等的无缝对接。

表示层特性:

  1. JSP 实际很强大完全可以做到类似 PHP 的页面优先的理念(互联网项目 UI 开发占了大量时间)——因此我们的数据绑定方式是 JSP 引入 JavaBean,而非 Servlet 控制。
  2. 有自己的前端库 Bigfoot.js(HTML5/CSS3/JavaScript),基于 LESS.js 预编译 CSS 器和 Node.js 的构建系统。
  3. 基于 JSP Tag Files 的模板继承机制,可复用性强。
  4. 模板语言基于 EL 表达式 和 SimpleTag。
  5. 后端管理界面可选使用 Ext JS。

数据层特性:

  1. 没有使用 ORM,提倡使用带变量的 SQL,提供简单的 SQL 封装手段和 DAO。
  2. 采用 Map 为输入、输出载体,如表单转换为 Map 再生成 SQL 语句;JDBC 返回数据采用 Map 为记录载体。
  3. 与 JS 引擎 Rhino 无缝对接,用 JS 定义一些方法,脚本语言 JS 在处理 JSON、字符串和正则表达式有极大的便利性和优势。
  4. 抛弃 Java POJO,改用 JS 定义实体,目的是为适合前后台所使用
  5. 使用 Tomcat 自带的数据库连接池 JDBC Pool。

最后,欢迎各位使用 Bigfoot!

Bigfoot 源码在

第一版,已废弃:http://code.taobao.org/p/bigfoot/src/

第二版,已废弃:http://code.taobao.org/p/bigfoot_v2/src/,请用 SVN 检出:http://code.taobao.org/svn/bigfoot_v2/。

第三版,基于 Spring + Spring MVC + MyBatis:http://code.taobao.org/p/bigfoot_v2/src/java_v3/

那些年我看过的 Servlet + JSP 开源框架:

EWeb4J 1.9.1 新版本发布 基于Servlet/JDBC的轻量级web开发框架

PandaJS: Rhino + MongoDB + Server-side JQuery Template

HashMap关系数据映射技术 

Eternal 框架

Nutz

Jfinal

Smart Framework

Tiny Framework

Firefly Framework

Solo

转:VO 与 PO 辨析

下面内容转载自 http://www.blogjava.net/lzhidj/archive/2011/02/21/344754.html

数据传输是程序员实现各种功能时刻需要考虑的问题,从数据模型的建立,到数据模型的转换,从数据的合法性验证,到数据类型的转化,我们要时刻小心,精心设计与组织。数据模型与数据传输可简单可复杂,完全取决于设计者的经验与意图,当然,项目的规模也是我们应该考虑的因素,一个小型项目实在没必要将问题复杂化。我们首先考虑数据从视图(View)传输到数据库(DB)的数据模型变化过程。用户从界面输入数据,此时,数据毫无结构可言,是零散的、无组织的,数据提交到控制器后,一方面考虑到 OOP 的严谨性,另一方面考虑到数据的封装,会将零散的无组织的数据封装成 Value Object(简称VO)对象,VO 就是 JavaBean,并传送到业务类中,在数据模型比较复杂的情况下,业务类的方法参数和返回值都应该是 VO 或 VO 的集合,VO 转换成 PO(Persistence Object)后传送到DAO,DAO 调用 Hibernate API 持久化数据。简单来说,业务类对外暴露的数据模型是 VO,DAO 对外暴露的数据模型是 PO。

数据从数据库传递到视图层的数据模型变化恰恰相反,Hibernate将数据库中的记录转换成 PO,PO 传递给业务类后转换成 VO,VO 被传送到视图层进行显示处理。以上转换过程如下图:

为什么同时需要 PO 和 VO?前面说过,这不是必须的,如果项目比较小,直接使用 PO 就行了。但 PO 有如下缺点:PO 反应了数据库的物理模型,向外暴露 PO 存在一定的风险;

  • PO过于僵化,无法适应变化莫测的业务需求;
  • PO在持久化状态下与数据库同步,可能导致数据意外修改;
  • PO将导致程序缺乏健壮性。

而VO没有PO的缺点,相对而言,VO更加灵活,能适应各种需求的变化,下面是 PO 和 VO 的区别:

  • VO 是用 new 关键字创建,由 GC 回收的。PO 则是向数据库中添加新数据时创建,删除数据库中数据时削除的。并且它只能存活在一个数据库连接中,断开连接即被销毁;
  • VO 是值对象,精确点讲它是业务对象,是存活在业务层的,是业务逻辑使用的,它存活的目的就是为数据提供一个生存的地方。PO 则是有状态的,每个属性代表其当前的状态。它是物理数据的对象表示。使用它,可以使我们的程序与物理数据解耦,并且可以简化对象数据与物理数据之间的转换;
  • VO 的属性是根据当前业务的不同而不同的,也就是说,它的每一个属性都一一对应当前业务逻辑所需要的数据的名称。PO 的属性是跟数据库表的字段一一对应的;
  • PO 一般只有一个,但对应的 VO 可能有多个。

我们举一个简单的例子来说明 VO 与 PO 的区别:比如要实现用户注册与登陆的功能,在物理模型中创建一个用户表,字段分别为用户 ID(标识列)、用户名、密码、注册日期等等,定义 PO 时应该有这四个字段的映射属性。现在,我们来实现用户注册这一功能,为了接收用户输入的注册信息,必须定义 VO,注册用户需要输入的信息有:用户名、密码1、密码2,这正好是 VO 的属性。而实现用户登陆功能时,用户需要输入的信息只有用户名和密码,所以,该 VO 的属性只有两个:用户名、密码。可以看出,PO 侧重于物理模型,而 VO 则更关注用户的实际需求。如下图所示:

相关实践学习
RocketMQ一站式入门使用
从源码编译、部署broker、部署namesrv,使用java客户端首发消息等一站式入门RocketMQ。
Sqoop 企业级大数据迁移方案实战
Sqoop是一个用于在Hadoop和关系数据库服务器之间传输数据的工具。它用于从关系数据库(如MySQL,Oracle)导入数据到Hadoop HDFS,并从Hadoop文件系统导出到关系数据库。 本课程主要讲解了Sqoop的设计思想及原理、部署安装及配置、详细具体的使用方法技巧与实操案例、企业级任务管理等。结合日常工作实践,培养解决实际问题的能力。本课程由黑马程序员提供。
目录
相关文章
|
15天前
|
监控 JavaScript 前端开发
《理解 WebSocket:Java Web 开发的实时通信技术》
【4月更文挑战第4天】WebSocket是Java Web实时通信的关键技术,提供双向持久连接,实现低延迟、高效率的实时交互。适用于聊天应用、在线游戏、数据监控和即时通知。开发涉及服务器端实现、客户端连接及数据协议定义,注意安全、错误处理、性能和兼容性。随着实时应用需求增加,WebSocket在Java Web开发中的地位将更加重要。
|
26天前
|
消息中间件 架构师 NoSQL
咕炮课堂Java架构师课程
针对1-5年经验开发者,【Java架构师培训】聚焦互联网热门技术,如Redis、MongoDB、Dubbo、Zookeeper、Kafka,讲授高并发、高可用分布式解决方案。由资深讲师指导,提升技术水平。
28 2
咕炮课堂Java架构师课程
|
10天前
|
安全 数据库 C++
Python Web框架比较:Django vs Flask vs Pyramid
【4月更文挑战第9天】本文对比了Python三大Web框架Django、Flask和Pyramid。Django功能全面,适合快速开发,但学习曲线较陡;Flask轻量灵活,易于入门,但默认配置简单,需自行添加功能;Pyramid兼顾灵活性和可扩展性,适合不同规模项目,但社区及资源相对较少。选择框架应考虑项目需求和开发者偏好。
|
2天前
|
负载均衡 Java 开发者
细解微服务架构实践:如何使用Spring Cloud进行Java微服务治理
【4月更文挑战第17天】Spring Cloud是Java微服务治理的首选框架,整合了Eureka(服务发现)、Ribbon(客户端负载均衡)、Hystrix(熔断器)、Zuul(API网关)和Config Server(配置中心)。通过Eureka实现服务注册与发现,Ribbon提供负载均衡,Hystrix实现熔断保护,Zuul作为API网关,Config Server集中管理配置。理解并运用Spring Cloud进行微服务治理是现代Java开发者的关键技能。
|
4天前
|
Web App开发 Java 应用服务中间件
【Java Web】在 IDEA 中部署 Tomcat
【Java Web】在 IDEA 中部署 Tomcat
18 0
|
4天前
|
前端开发 数据挖掘 API
使用Python中的Flask框架进行Web应用开发
【4月更文挑战第15天】在Python的Web开发领域,Flask是一个备受欢迎的轻量级Web框架。它简洁、灵活且易于扩展,使得开发者能够快速地构建出高质量的Web应用。本文将深入探讨Flask框架的核心特性、使用方法以及在实际开发中的应用。
|
8天前
|
云安全 数据采集 安全
阿里云安全产品,Web应用防火墙与云防火墙产品各自作用简介
阿里云提供两种关键安全产品:Web应用防火墙和云防火墙。Web应用防火墙专注网站安全,防护Web攻击、CC攻击和Bot防御,具备流量管理、大数据防御能力和简易部署。云防火墙是SaaS化的网络边界防护,管理南北向和东西向流量,提供访问控制、入侵防御和流量可视化。两者结合可实现全面的网络和应用安全。
阿里云安全产品,Web应用防火墙与云防火墙产品各自作用简介
|
14天前
|
消息中间件 安全 Java
解密 Java 后台架构设计之道
【4月更文挑战第5天】本文探讨了Java后台架构设计的最佳实践,包括分层架构、微服务、异步处理与消息队列、RESTful API设计、数据库优化、安全控制、容错高可用、配置管理、CI/CD和监控日志。强调了使用微服务、Spring Boot/Spring Cloud、异步消息队列、RESTful API、安全框架Spring Security等技术的重要性,以及监控和自动化部署在确保系统稳定性和效率上的关键角色。通过这些实践,开发者能构建高效、稳定且可扩展的后台系统。
|
16天前
|
XML JSON JavaScript
使用JSON和XML:数据交换格式在Java Web开发中的应用
【4月更文挑战第3天】本文比较了JSON和XML在Java Web开发中的应用。JSON是一种轻量级、易读的数据交换格式,适合快速解析和节省空间,常用于API和Web服务。XML则提供更强的灵活性和数据描述能力,适合复杂数据结构。Java有Jackson和Gson等库处理JSON,JAXB和DOM/SAX处理XML。选择格式需根据应用场景和需求。
|
16天前
|
前端开发 安全 Java
使用Java Web框架:Spring MVC的全面指南
【4月更文挑战第3天】Spring MVC是Spring框架的一部分,用于构建高效、模块化的Web应用。它基于MVC模式,支持多种视图技术。核心概念包括DispatcherServlet(前端控制器)、HandlerMapping(请求映射)、Controller(处理请求)、ViewResolver(视图解析)和ModelAndView(模型和视图容器)。开发流程涉及配置DispatcherServlet、定义Controller、创建View、处理数据、绑定模型和异常处理。
使用Java Web框架:Spring MVC的全面指南