在Java Web的发展历程中,先是由Servlet负责显示层(页面)的开发,后来因为JSP在页面层的开发更具优势,于是全面取代了Servelt,充当了页面层的开发。
但是在JSP出现之后,Java Web的设计架构出现了混乱、不成熟的时期,即所谓的JSP Model 1、JSP Model 1.2和不成熟的 JSP Model 2 时期,及成熟的Model 2时期(作为区分,可以称之为MVC模式)。除MVC模型之外,其他模型现在已经在行业中被淘汰,但也不排除仍有不专业的公司团队在保守残缺。但是学习者来说,可以了解一下,并做好对比,以便清楚的认识到为什么MVC模式更好。其中MVC模式会在下一篇文章中进行讲解。
我们以上一篇文章中的完成一个展示所有学生的表格数据为例,讲解这3种模式。效果图如下所示:
JSP Model 1
模型1的架构图,如下图所示,JSP不仅负责页面的处理,也负责业务逻辑的处理,如果你有PHP的开发经验,会发现那时候的Java Web开发和PHP的开发模式差不多,这也是我在十多年前从事过PHP开发网站时,就断定PHP不会有太好的发展前途的原因。因为PHP还在使用Java Web早就抛弃的开发模型。
模型1的优势是,将知识范畴规约在JSP之内,开发者所涉及的知识变窄,灵活方便。但是开发复杂系统,会造成混乱,不利于交流与维护。
代码如上一篇文章中的,如下所示:
<%@ page language="java" contentType="text/html; charset=utf-8"
pageEncoding="utf-8"%>
<%@ page import="java.sql.*"%>
<!DOCTYPE>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Insert title here</title>
</head>
<body>
<%
//利用反射,生成MySQL驱动类对象
Class.forName("com.mysql.jdbc.Driver");
//建立与数据库的连接:url、user、pwd
Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/school", "root", "123456");
//创建SQL语句执行器
Statement stat = conn.createStatement();
//执行SQL语句,得到结果集(select语句会得到结果集)
ResultSet rs = stat.executeQuery("select * from student");
//处理结果
//注意,这里要灵活运用JSP脚本片段特点,与HTML灵活构建出一个表格
%>
<!-- 注意,此处使用了HTML的修饰属性,而没有使用CSS修饰,这是不符合规范的,后续在对页面进行修饰时会改正 -->
<table border=1>
<tr>
<th>ID</th>
<th>姓名</th>
<th>性别</th>
<th>年龄</th>
</tr>
<%
//循环构建tr
while (rs.next()) {
%>
<tr>
<td><%=rs.getInt("id")%></td>
<td><%=rs.getString("name")%></td>
<td><%=rs.getString("gender")%></td>
<td><%=rs.getInt("age")%></td>
</tr>
<%
}
//关闭连接等资源
rs.close();
stat.close();
conn.close();
%>
</table>
</body>
</html>
JSP Model 1.2
模型1.2的架构图如下图所示,是基于解耦合的思想对模型1的改进,通过加入JavaBean的方式,由JavaBean(Java类)负责业务逻辑处理,实现了页面和业务逻辑的分离。
因为涉及JSP访问JavaBean,所以要建一个实体类Student,来方便方法调用及作为返回值来传递数据。
包、类结果如下所示:
代码:
Student.java:
package entity;
public class Student {
private int id;
private String name;
private String gender;
private int age;
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 getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
StudentDao.java:
package dao;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;
import entity.Student;
public class StudentDao {
public List<Student> search() {
List<Student> list = new ArrayList<>();
Connection conn = null;
Statement stat = null;
ResultSet rs = null;
// 利用反射,生成MySQL驱动类对象
try {
Class.forName("com.mysql.jdbc.Driver");
// 建立与数据库的连接:url、user、pwd
conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/school", "root", "123456");
// 创建SQL语句执行器
stat = conn.createStatement();
// 执行SQL语句,得到结果集(select语句会得到结果集)
rs = stat.executeQuery("select * from student");
// 处理结果
while (rs.next()) {
Student stu = new Student();
stu.setId(rs.getInt("id"));
stu.setName(rs.getString("name"));
stu.setGender(rs.getString("gender"));
stu.setAge(rs.getInt("age"));
list.add(stu);
}
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
// 正确关闭资源
try {
if (rs != null) {
rs.close();
}
if (stat != null) {
stat.close();
}
if (conn != null) {
conn.close();
}
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
return list;
}
}
show2.jsp:
<%@ page language="java" contentType="text/html; charset=utf-8"
pageEncoding="utf-8"%>
<%@ page import="java.util.*"%>
<%@ page import="entity.*,dao.*"%>
<!DOCTYPE>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Insert title here</title>
</head>
<body>
<table border=1>
<tr>
<th>ID</th>
<th>姓名</th>
<th>性别</th>
<th>年龄</th>
</tr>
<%
//JSP中调用Java中的方法, 与Java中调用Java方法一样。
StudentDao stuDao = new StudentDao();
List<Student> list = stuDao.search();
for (Student stu : list) {
%>
<tr>
<td><%=stu.getId()%></td>
<td><%=stu.getName()%></td>
<td><%=stu.getGender()%></td>
<td><%=stu.getAge()%></td>
</tr>
<%
}
%>
</table>
</body>
</html>
JSP Model 2不成熟时期
模型2的架构图如下图所示,Java开发者重新审视现有技术,发现了Servlet并不是一无是处,它可以充当控制器,即负责客户端发来的请求与类、页面之间调度。
但是这个模型不成熟的地方在于JSP和JavaBean之间仍然可以直接交互,读者可以通过JSTL的sql标签、JSP的动作元素发现那一时期的历史痕迹。
甚至目前仍有不少公司团队在做这样的不规范的事情,即JSP直接访问Java类,美其名曰“灵活”,但这实际是放弃了Java的天然优势。即严谨性,尤其要引起重视。
这种成熟时期的JSP Model 2就是调用混乱,甚至有多个入口,就不做代码举例,我们下一篇文章直接进入到成熟与规范的MVC模式的学习。