1. MVC架构模式
MVC是软件工程中的一种 软件架构模式
它把软件系统分为 模型 视图 和 控制器`**三个基本部分。
用一种业务逻辑、数据、界面显示分离的方法组织代码,将业务逻辑聚集到一个部件里面,在改进和个性化定制界面及用户交互的同时,不需要重新编写业务逻辑。
mvc模式实现:高内聚低耦合,开闭原则
-
M:Model 模型层,具体功能如下
- 存放和数据库对象的实体类以及一些用于存储非数据库表完整相关的VO对象
- 存放一些对数据进行逻辑运算操作的的一些业务处理代码
-
V:View 视图层,具体功能如下
- 存放一些视图文件相关的代码 html css js等
- 在前后端分离的项目中,后端已经没有视图文件,该层次已经衍化成独立的前端项目
-
C:Controller 控制层,具体功能如下
- 接收客户端请求,获得请求数据
- 将准备好的数据响应给客户端
案例:张三网络购物买10本 《^JAVA》*
1.1 MVC模式下,项目常见的包
-
M:
- 实体类包(pojo /entity /bean) 专门存放和数据库对应的实体类和一些VO对象
- 数据库访问包(dao/mapper) 专门存放对数据库不同表格CURD方法封装的一些类
- 服务包(service) 专门存放对数据进行业务逻辑运算的一些类
-
C:
- 控制层包(controller)
-
V:
- web目录下的视图资源 html css js img 等
- 前端工程化后,在后端项目中已经不存在了
1.2 实体类常见要求
- 1.实体类的类名和表格名称对应;
- 2.实体类属性名和表格的列名对应;
- 3.属性必须私有,属性都具备getter/setter方法,必须具备无参构造器
- 4.应该实现序列化接口(缓存,分布式项目数据传递)
- 5.应该重写类的hashcode和equals方法
- 6.toString可写可不写
1.3 M层(PoJo)使用lombok自动生成
- 使用lombok帮助生成1.2节相关内容getter,setter无参构造,有参构造,equals,hashcode等
- 使用流程
1.检查idea是否安装此插件
2.检查是否勾选了enable,annotation,processer
3.导入lombok依赖
- 此处有诈,此勾选换工程就掉;需要常勾选;
- 导入依赖,实体类添加注解即可
- 添加注解
@Data //getter,setter,toString,hashcode
1.4 M层(Dao)针对表格操作的增删改查;
-
dao包下,一般来说,你有几个表格,就有几个Dao类
-
dao层一般要定义接口dao层下面 定义impl实现dao层接口的方法
-
上层调用 看一下dao层都需要实现了哪些功能,而无需关注dao层是怎么样实现的,具体实现在impl包下;
- 此外dao层定义的接口需要写注释文档,标注你这个dao能实现什么功能;
1.5 M(层) 实现Service服务层
- 和上述一样,比葫芦画瓢
- 几个表对应几个服务层接口
2.MVC架构模式 Controller层
-
controller层主要使用servlet技术实现;
-
这一层调用model层,处理业务逻辑,接收结果,将结果响应给客户端;
-
至于接收哪些Servlet也是根据我们的数据表进行定义的;
2.1 创建响应的controller类
-
继承HttpServlet 父类
-
HttpServlet 间接实现了Servlet接口(技术接口)
-
Controller层的Servlet接口一般都是业务接口,而HttpServlet实现的是Servlet技术接口;二者存在根本性区别
-
Controller层应用的是Servlet技术,具有一定的特殊性,因此不需要向其他层一样必要使用接口,而是直接上类;
-
一般定义映射路径时候,Controller就不写了
@WebServlet(“”) 可以看心情指定
2.2 设计控制层对应不同的请求路径
- WebServlet设置为/schedule/*,但是控制层会接收到不同的业务
- 我们的需求就是判断不同的业务,然后指定不同的路径
2.3 Controller配置高可用
- 业务需求 通过URI判断,执行哪一个业务
* 未来业务
* 1.增加日程 /schedule/add
* 2.查询日程 /schedule/find
* 3.修改日程 /schedule/update
* 4.删除日程请求/schedule/remove
思路:先获取URI,进行判断,最终跳转到响应方法,如果没有,重定向;
- controller中创建BaseController类文件
package com.atguigu.schedule.controller;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.lang.reflect.Method;
public class BaseController extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String requestURI = req.getRequestURI();
String[] split = requestURI.split("/");
String methodName =split[split.length-1];
// 通过反射获取要执行的方法
Class clazz = this.getClass();
try {
Method method=clazz.getDeclaredMethod(methodName,HttpServletRequest.class,HttpServletResponse.class);
// 设置方法可以访问
method.setAccessible(true);
// 通过反射执行代码
method.invoke(this,req,resp);
} catch (Exception e) {
e.printStackTrace();
}
}
}
- 多个处理器继承BaseController
@WebServlet("/schedule/*")
public class SysScheduleController extends BaseController {
protected void add(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("add");
}
protected void find(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("find");
}
protected void update(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("update");
}
protected void remove(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("remove");
}
protected void create(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("create");
}
}
2.5 加密
- 用户客户端输入的是明文密码,但是我们存入到数据库是加密后的密文密码;
-
方式有2
-
数据库自带MD5加密,其次就是我们自己写一个工具类对其进行加密;
-
MD5加密工具类
package com.atguigu.schedule.util;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
public final class MD5Util {
public static String encrypt(String strSrc) {
try {
char hexChars[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8',
'9', 'a', 'b', 'c', 'd', 'e', 'f' };
byte[] bytes = strSrc.getBytes();
MessageDigest md = MessageDigest.getInstance("MD5");
md.update(bytes);
bytes = md.digest();
int j = bytes.length;
char[] chars = new char[j * 2];
int k = 0;
for (int i = 0; i < bytes.length; i++) {
byte b = bytes[i];
chars[k++] = hexChars[b >>> 4 & 0xf];
chars[k++] = hexChars[b & 0xf];
}
return new String(chars);
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
throw new RuntimeException("MD5加密出错!!!")
}
}
}
- 明文转密文 根据上述方法
String encrypt = MD5Util.encrypt("123456");
System.out.println(encrypt); //e10adc3949ba59abbe56e057f20f883e
3. 登录注册业务案例
- 首先准备好注册登录页面
- 需求分析
Controller层控制用户注册业务,但是可能会失败,因为数据库可能存在id重名;
整体业务逻辑
regest.html携带着kv键值对-->服务器访问控制层-->控制层首先获取参数-->调用服务层-->服务层先明文转化为密文,并将用户参数中的pwd给设置为密文-->将用户信息存入数据库交给DAO来做-->调用dao接口增加一个用户
Appendix
1.mvc这一块比较细,不能着急
2.目录结构如下
- impl对应每一个pojo实体类对应每一个dao接口
- dao接口定义所有表处理方法
- impl类实现dao方法,完成每一个dao方法的处理(具体 连接数据库,进行操作,等都使用BaseDao封装好了,但是调包的时候要注意对应);
3.别搞笑,之前Servlet也是一直是继承HttpServlet而不是实现