目录
[M-V-C 三部分的含义](#M-V-C 三部分的含义)
[View - 视图的实现](#View - 视图的实现)
[Model - 模型的实现](#Model - 模型的实现)
[Controller - 控制器的实现](#Controller - 控制器的实现)
[Web.xml 配置](#Web.xml 配置)
MVC的介绍
mvc是什么
MVC全名是Model View Controller,模型(model)-视图(view)-控制器(controller)的缩写
使用MVC模式,就是程序员在写代码时,将一个程序代码人为地分成了M-V-C三部分来写。
M-V-C 三部分的含义
M模型(Model)
业务逻辑层。用于封装业务逻辑和数据模型。
V视图(View)
表示层。就是与用户实现交互的界面,通常实现数据的输入和输出功能。
C控制器(controller)
控制层。起到控制整个业务流程的作用,实现View层跟Model层的协同工作
MVC运行过程

MVC的优点
1、低耦合性
视图层和业务层分离,这样就允许更改视图层代码而不用重新编译模型和控制器代码,同样,一个应用的业务流程或者业务规则的改变只需要改动MVC的模型层即可。因为模型与控制器和视图相分离,所以很容易改变应用程序的数据层和业务规则。
2、较低的生命周期成本
MVC使开发和维护用户接口的技术含量降低。
3、高重用性和可适用性
随着技术的不断进步,现在需要用越来越多的方式来访问应用程序。MVC模式允许你使用各种不同样式的视图来访问同一个服务器端的代码。它包括任何WEB(HTTP)浏览器或者无线浏览器(wap),比如,用户可以通过电脑也可通过手机来订购某样产品,虽然订购的方式不一样,但处理订购产品的方式是一样的。由于模型返回的数据没有进行格式化,所以同样的构件能被不同的界面使用。例如,很多数据可能用HTML来表示,但是也有可能用WAP来表示,而这些表示所需要的命令是改变视图层的实现方式,而控制层和模型层无需做任何改变。
4、快速的部署
使用MVC模式使开发时间得到相当大的缩减,它使程序员(Java开发人员)集中精力于业务逻辑,界面程序员(HTML和JSP开发人员)集中精力于表现形式上。
5、可维护性
分离视图层和业务逻辑层也使得WEB应用更易于维护和修改。
具体实现
两种经典MVC实现模型
在Java Web领域存在着两种经典模型,也可以称为实现模式,分别是Model1和Model2。这两种模型都可被看做是MVC的具体实现形式
模型1:JSP+JavaBean

模型1的特点是,
JSP充当控制器C与视图V的双重角色
JSP直接调用后台模型进行业务处理,同时再由JSP返回用户结果界面
JavaBean扮演了模型M的角色
模型2:JSP+Servlet+JavaBean

模型2的特点是
Servlet作为控制器C
JSP仅作为视图V
JavaBean作为模型M
整个过程:
用户通过浏览器发送请求,Servlet接收请求并调用相应的JavaBean处理请求,JavaBean负责业务逻辑和数据处理。到处理完成,JavaBean将结果返回给Servlet,Servlet根据结果指定JSP页面返回给客户浏览器,完成一次操作
MVC的具体实现-用户登录实例
实例描述
利用MVC实现模型2 ,即JSP+Servlet+JavaBean模式实现用户登录功能,数据库使用mysql
登录页面及操作效果如下

数据库中登录用表及数据如下

表名userinfo(用户信息表)
字段2个
username 用户名 字符串 10位 主键
password 密码 字符串 6位 非空
实现思路
要在程序中体现MVC的思想,核心问题就是把程序按照MVC的定义分成三部分(或者说归三类)
属于V范畴的内容写在V指定的地方
属于M范畴的内容写在M指定的地方
属于C范畴的内容写在C指定的地方
View-视图的实现
视图是MVC中的V,使用JSP 来实现,即用户界面。对于用户登录功能,我们用最简单的界面,如下图,只需要"用户名"、"密码"2个输入框,再有"提交"和"重置"2个按钮就行了

登录页面参考代码
<form action="login" method="post">
用户名:<input type="text" name="userid"><br>
密码:<input type="password" name="password"><br>
<input type="submit" value="提交">
<input type="reset" value="重置">
</form>
我们还需要登录成功、登陆失败画面,代码以下省略
Model-模型的实现
MVC中的M,使用JavaBean来实现模型,即完成业务逻辑和数据的处理。
一般地建立登录的逻辑处理类Login来实现用户登陆的业务逻辑。
该类需要做的事情是
1.获得用户填写的登录信息
2.根据用户填写的登录信息,在数据库进行查找,若找到,那么则返回成功标志,若没有找到任何记录,则返回登陆失败失败
Model-模型的实现代码
public boolean execute(HttpServletRequest request){
boolean ret=false;
DBUtil dBUtil=new DBUtil();
String sql="";
try { request.setCharacterEncoding("utf-8");
String username=request.getParameter("userid");
String password=request.getParameter("password");
sql="select count(1) from userinfo where username='"+username+"' and password='"+password+"'";
dBUtil.executeQuery(sql);
ResultSet rs=dBUtil.getRs();
int count=0;
if(rs.next()){ count=rs.getInt(1);}
if (count>0) { ret=true;}
} catch (Exception e) {
e.printStackTrace();
System.out.println("执行登录失败,请检查sql:"+sql);
}
dBUtil.close();
return ret;}
Model-数据库工具类代码
public class DBUtil{
private static final String URL="jdbc:mysql://localhost:3306/test";
private static final String LOGIN="root";private static final String PASSWORD="";
Connection conn=null;Statement st=null;private ResultSet rs=null;
public ResultSet getRs(){return rs;}
public void setRs(ResultSet rs){this.rs=rs;}
void getConnection(){
try {Class.forName("com.mysql.jdbc.Driver");
conn=DriverManager.getConnection(URL,LOGIN,PASSWORD);
} catch (ClassNotFoundException e) {
System.out.println("数据库连接出错,请检查驱动程序是否存在,驱动名是否正确");
} catch (SQLException e) {
System.out.println("数据库连接出错,请检查登录的用户名密码是否正确,数据库服务器是否启动");}}
public int executeQuery(String sql){
try {if(st==null){getConnection();st=conn.createStatement();}
rs=st.executeQuery(sql);
} catch (SQLException e) {System.out.println("数据库查询执行出错,请检查sql:"+sql);}
return 0;}
public int executeUpdate(String sql){
int ret=0;
try {if(st==null){getConnection();st=conn.createStatement();}
ret=st.executeUpdate(sql);
} catch (SQLException e) {ret=-1;System.out.println("数据库增删改执行出错,请检查sql:"+sql);}
return ret;}
public void close(){
try {if (rs!=null){rs.close();}
if (st!=null){st.close();}
if (conn!=null){conn.close();}
} catch (SQLException e) {e.printStackTrace();}}}
Controller-控制器的实现
MVC中的C,使用Servlet来实现控制
一般地,建立Servlet类LoginServlet,在这个类中在doPost()方法中写代码。
具体做的事情是
1.调用业务逻辑处理类做事情
2.得到业务逻辑处理类的返回结果
3.根据结果做出决策:跳转到登录的结果页面
Controller-控制器的参考代码
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//1.调用人家做事情
Login login=new Login();
//2.得到做的事情结果
boolean ret=login.execute(request);
//3.根据结果做出决策
if(ret){//成功
response.sendRedirect("./login_succ.jsp");
}else{//失败
response.sendRedirect("./login_err.jsp");
}
}
web:
<servlet>
<servlet-name>login</servlet-name>
<servlet-class>login.ServletLogin</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>login</servlet-name>
<url-pattern>/login</url-pattern>
</servlet-mapping>
调试运行
确定数据库表及数据
准备好****确定数据库驱动程序
准备好****分别输入错误与正确的登录数据执行程序
MVC2实现
数据库设计这里同样忽略
View - 视图的实现
视图部分使用JSP来实现用户注册页面。用户注册页面需要包含用户名和密码的输入框,以及提交和重置按钮。
register.jsp
<!DOCTYPE html>
<html>
<head>
<title>用户注册</title>
</head>
<body>
<h2>用户注册</h2>
<form action="register" method="post">
用户名:<input type="text" name="username"><br>
密码:<input type="password" name="password"><br>
<input type="submit" value="注册">
<input type="reset" value="重置">
</form>
</body>
</html>
Model - 模型的实现
模型部分使用JavaBean来处理业务逻辑和数据操作。我们需要创建一个 Register
类来处理用户注册的逻辑。
Register.java
public class Register {
public boolean execute(HttpServletRequest request) {
boolean ret = false;
DBUtil dBUtil = new DBUtil();
String sql = "";
try {
request.setCharacterEncoding("utf-8");
String username = request.getParameter("username");
String password = request.getParameter("password");
// 检查用户名是否已存在
sql = "SELECT COUNT(1) FROM userinfo WHERE username='" + username + "'";
dBUtil.executeQuery(sql);
ResultSet rs = dBUtil.getRs();
int count = 0;
if (rs.next()) {
count = rs.getInt(1);
}
if (count == 0) {
// 用户名不存在,可以注册
sql = "INSERT INTO userinfo (username, password) VALUES ('" + username + "', '" + password + "')";
int rows = dBUtil.executeUpdate(sql);
if (rows > 0) {
ret = true;
}
}
} catch (Exception e) {
e.printStackTrace();
System.out.println("执行注册失败, 请检查sql: " + sql);
}
dBUtil.close();
return ret;
}
}
Controller - 控制器的实现
控制器部分使用Servlet来处理请求和响应。我们需要创建一个 RegisterServlet
类来处理用户注册的请求。
RegisterServlet.java
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class RegisterServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 1. 调用业务逻辑处理类
Register register = new Register();
// 2. 得到业务逻辑处理类的返回结果
boolean ret = register.execute(request);
// 3. 根据结果做出决策
if (ret) {
// 注册成功
response.sendRedirect("./register_succ.jsp");
} else {
// 注册失败
response.sendRedirect("./register_err.jsp");
}
}
}
数据库工具类
数据库工具类 DBUtil
用于处理数据库连接和操作。这个类在注册功能中也会被使用。
DBUtil.java
import java.sql.*;
public class DBUtil {
private static final String URL = "jdbc:mysql://localhost:3306/test";
private static final String LOGIN = "root";
private static final String PASSWORD = "";
private Connection conn = null;
private Statement st = null;
private ResultSet rs = null;
public ResultSet getRs() {
return rs;
}
public void setRs(ResultSet rs) {
this.rs = rs;
}
private void getConnection() {
try {
Class.forName("com.mysql.jdbc.Driver");
conn = DriverManager.getConnection(URL, LOGIN, PASSWORD);
} catch (ClassNotFoundException e) {
System.out.println("数据库连接出错,请检查驱动程序是否存在,驱动名是否正确");
} catch (SQLException e) {
System.out.println("数据库连接出错,请检查登录的用户名密码是否正确,数据库服务器是否启动");
}
}
public int executeQuery(String sql) {
try {
if (st == null) {
getConnection();
st = conn.createStatement();
}
rs = st.executeQuery(sql);
} catch (SQLException e) {
System.out.println("数据库查询执行出错,请检查sql:" + sql);
}
return 0;
}
public int executeUpdate(String sql) {
int ret = 0;
try {
if (st == null) {
getConnection();
st = conn.createStatement();
}
ret = st.executeUpdate(sql);
} catch (SQLException e) {
ret = -1;
System.out.println("数据库增删改执行出错,请检查sql:" + sql);
}
return ret;
}
public void close() {
try {
if (rs != null) {
rs.close();
}
if (st != null) {
st.close();
}
if (conn != null) {
conn.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
}
}
Web.xml 配置
在 web.xml
中配置 RegisterServlet
的映射。
web.xml
<servlet>
<servlet-name>RegisterServlet</servlet-name>
<servlet-class>RegisterServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>RegisterServlet</servlet-name>
<url-pattern>/register</url-pattern>
</servlet-mapping>
注册成功和失败的页面
创建两个简单的JSP页面来显示注册成功和失败的结果。
register_succ.jsp
<!DOCTYPE html>
<html>
<head>
<title>注册成功</title>
</head>
<body>
<h2>注册成功!</h2>
</body>
</html>
register_err.jsp
<!DOCTYPE html>
<html>
<head>
<title>注册失败</title>
</head>
<body>
<h2>注册失败,用户名已存在!</h2>
</body>
</html>
小结
使用MVC模式的程序与不使用MVC,效果是一样的
不同的是,程序分成了三部分
JSP页面是视图V
servlet是控制器C
登录的Login和数据库工具类DBUtil是模型M