MVC开发模式
写在最前
MVC 是一种使用 MVC(Model View Controller 模型-视图-控制器)设计创建 Web 应用程序的模式: [1]
- Model(模型)表示应用程序核心(比如数据库记录列表)。
- View(视图)显示数据(数据库记录)。
- Controller(控制器)处理输入(写入数据库记录)。
MVC 模式同时提供了对 HTML、CSS 和 JavaScript 的完全控制。
Model(模型)**是应用程序中用于处理应用程序数据逻辑的部分。
通常模型对象负责在数据库中存取数据。
View(视图)**是应用程序中处理数据显示的部分。
通常视图是依据模型数据创建的。
Controller(控制器)**是应用程序中处理用户交互的部分。
通常控制器负责从视图读取数据,控制用户输入,并向模型发送数据。
MVC 分层有助于管理复杂的应用程序,因为您可以在一个时间内专门关注一个方面。例如,您可以在不依赖业务逻辑的情况下专注于视图设计。同时也让应用程序的测试更加容易。
MVC 分层同时也简化了分组开发。不同的开发人员可同时开发视图、控制器逻辑和业务逻辑。
(来自百度百科)
分层思想:强内聚、弱耦合
举个栗子
通过对每一层代码的分类来达到规范开发的要求。
项目结构图
如下图所示
代码已经上传我的GitHup,地址:https://github.com/wannengdek/MVC
如果你觉得我的代码对你有所帮助,请帮忙点亮小星星。
开发准备
数据库准备
数据库表结构如图所示,表名为users,数据库名为 day06。
Pagckage介绍
dao 接口
dao.impl 实现类
domain 实体类
service 业务类
service.impl 业务实现类
servlet servlet相关类
util 存放工具类
exception 自定义异常类
开发过程
可以按照 domain dao dao.impl service service.impl servlet 的顺序来编写
domain 实体类 (省略get set方法)
package domain;
import java.io.Serializable;
import java.util.Date;
public class User implements Serializable{
private int id;
private String username;
private String password;
private String email;
}
dao 操作数据方法
package dao;
import domain.User;
public interface UserDao {
public void addUser(User user) throws Exception ;
public User findUser(User user)throws Exception ;
}
dao.impl 实现操作方法
package dao.impl;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.text.SimpleDateFormat;
import util.DBUtils;
import dao.UserDao;
import domain.User;
public class UserDaoImpl implements UserDao {
public void addUser(User user) throws Exception {
Connection conn =null;
PreparedStatement ps =null ;
try {
conn = DBUtils.getConnection();
ps = conn.prepareStatement("INSERT INTO users(username,PASSWORD,email) VALUES(?,?,?)");
ps.setString(1, user.getUsername());
ps.setString(2, user.getPassword());
ps.setString(3, user.getEmail());
int i = ps.executeUpdate();
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException("添加失败!");
}finally{
DBUtils.closeAll(null, ps, conn);
}
}
public User findUser(User user) throws Exception {
Connection conn = null;
PreparedStatement ps = null;
ResultSet rs = null;
User u = null;
try {
conn = DBUtils.getConnection();
ps = conn.prepareStatement("select * from users where username=? and password=?");
ps.setString(1, user.getUsername());
ps.setString(2, user.getPassword());
rs = ps.executeQuery();
if(rs.next()){
u = new User();
u.setId(rs.getInt(1));
u.setUsername(rs.getString(2));
u.setPassword(rs.getString(3));
u.setEmail(rs.getString(4));
}
} catch (Exception e) {
e.printStackTrace();
}finally{
DBUtils.closeAll(rs, ps, conn);
}
return u;
}
public boolean findUserByName(String name) {
Connection conn = null;
PreparedStatement ps = null;
ResultSet rs = null;
try {
conn = DBUtils.getConnection();
ps = conn.prepareStatement("select * from users where username=?");
ps.setString(1, name);
rs = ps.executeQuery();
if(rs.next()){
return true;
}
} catch (Exception e) {
e.printStackTrace();
}finally{
DBUtils.closeAll(rs, ps, conn);
}
return false;
}
}
service 业务接口类 即具体的业务,诸如登录、注册
package service;
import domain.User;
import exception.UsersException;
public interface UserService {
public void register(User user) throws Exception ;
public User login(User user) throws UsersException;
}
service.impl 接口实现类
package service.impl;
import service.UserService;
import dao.UserDao;
import dao.impl.UserDaoImpl;
import domain.User;
import exception.UsersException;
public class UserServiceImpl implements UserService {
UserDao userDao = new UserDaoImpl();
public void register(User user) throws Exception {
userDao.addUser(user);
}
public User login(User user) throws UsersException {
User u= null ;
try {
u =userDao.findUser(user);
if (u==null) {
System.out.println("用户名或密码不正确 ");
}
} catch (Exception e) {
e.printStackTrace();
// 写入日志
}
return u;
}
}
servlet 实现分发转向
先写jsp页面
login.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
${msg }
<form action="${pageContext.request.contextPath }/servlet/loginServlet" method="post">
用户名:<input type="text" name="username"/><br/>
密码:<input type="password" name="password"/><br/>
<input type="submit" value="登录"/><br/>
</form>
</body>
</html>
index.jsp
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>">
<title>My JSP 'index.jsp' starting page</title>
<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">
<!--
<link rel="stylesheet" type="text/css" href="styles.css">
-->
</head>
<body>
This is my JSP page. <br>
<c:if test="${empty u }">
<a href="reg.jsp" >注册</a>
<a href="login.jsp" >登录</a>
</c:if>
<c:if test="${not empty u }">
欢迎你:${u.username} <a href="${pageContext.request.contextPath }/servlet/loginOutServlet">销毁</a>
</c:if>
</body>
</html>
reg.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<form action="${pageContext.request.contextPath }/servlet/regServlet " method="post">
用户名:<input type="text" name="username" value="${uf.username }"/>${uf.msg.username }${error }<br/>
密码:<input type="password" name="password" />${uf.msg.password }<br/>
确认密码:<input type="password" name="repassword"/>${uf.msg.repassword }<br/>
油箱:<input type="text" name="email" value="${uf.email }"/>${uf.msg.email }<br/>
<input type="submit" value="注册"/><br/>
</form>
</body>
</html>
servlet 获取表单数据、调用业务逻辑、分发转向
LoginServlet
package servlet;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.beanutils.BeanUtils;
import service.UserService;
import service.impl.UserServiceImpl;
import domain.User;
import exception.UsersException;
public class LoginServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html;charset=UTF-8");
User user = new User();
try {
BeanUtils.populate(user, request.getParameterMap());
} catch (Exception e) {
e.printStackTrace();
}
//调用业务逻辑
UserService us = new UserServiceImpl();
User u ;
try {
u = us.login(user) ;
//分发转向
if(u!=null)
{
//登录成功 将 user 对象放到 seesion 中
request.getSession().setAttribute("u", user);
request.getRequestDispatcher("/index.jsp").forward(request, response);
}
else
{
String msg ="用户名或密码不正确";
request.setAttribute("msg",msg);
request.getRequestDispatcher("/login.jsp").forward(request, response);
}
} catch (UsersException e) {
e.printStackTrace();
request.setAttribute("msg",e.getMessage());
request.getRequestDispatcher("/login.jsp").forward(request, response);
}
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
regServlet
package servlet;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.beanutils.BeanUtils;
import service.UserService;
import service.impl.UserServiceImpl;
import domain.User;
public class regServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html;charset=UTF-8");
User user = new User();
try {
BeanUtils.populate(user, request.getParameterMap());
//调用业务逻辑
UserService us = new UserServiceImpl();
us.register(user);
} catch (Exception e) {
e.printStackTrace();
}
response.getWriter().write("注册成功,1s之后回到主页");
response.setHeader("refresh", "1;url="+request.getContextPath()+"/index.jsp");
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
注意事项
开发过程中需要注意servlet 在XML 的配置问题。要不然容易出现404。
总结
虽然一开始我自己写项目也是简单分个数据层、业务层就完事了,但是MVC开发模式能一直存在,也是有一定道理的,别的不说,自己看自己半年前写的东西都不一定知道这个类里是啥、有什么方法。坚持使用正确模式进行项目开发,是一个合格 的程序员该做的。
代码已经上传我的GitHup,地址:https://github.com/wannengdek/MVC
如果你觉得我的代码对你有所帮助,请帮忙点亮小星星。