MVC架构模式-各层的写法要求
MVC架构模式-各层的写法要求
M层中大概包括:pojo层、Dao层、Service层
C层中包括:Controller层
注意事项:
- 要在接口上写明方法的文档
- 无论哪个层在调用其他层对象时,最好将其实例化对象为类中属性,这样做可以不用在每个方法中都实例化对象
- 写代码的逻辑可以选择为:Controller -> service -> Dao (由前向后),先写调用 再写 方法内容
pojo层
- 实体类中的类名与表格名称应该对应
- 实体类的属性名与表格的列明应该对应
- 遇到下划线应以驼峰命名进行转换
- 每个属性都应该是私有的
- 每个属性都应该具备get/set方法
- 必须具备无参构造器
- 应该实现序列化接口(缓存 分布式项目数据传递 可能会将对象序列化)
- 应该重写hashcode和equals方法
- toString是否重写都可以
以上我们只需要注意加粗部分,其余部分使用Lombok注解即可在编译时自动生成😓
Lombok的使用方法
- 检查idea是否已经安装了Lombok插件
- 检查是否勾选了enable annotation precessing
在汉化后的idea中,此设置在 构建、执行、部署 -> 编译器 -> 注解处理器 -> 启用注解处理
- 导入Lombok的依赖添加jar包
- 在实体类中添加Lombok注解
@AllArgsConstructor //添加全参构造
@NoArgsConstructor //添加无参构造
@Data //添加get/set/hashcode/equals
DAO层
参考JDBC模块知识点进行编写
- dao
- impl目录:用于存放接口的实现类
- BaseDAO类
- xxxDao接口:用于定义Dao类功能的接口
Service层
- service
- impl目录:用于存放接口的实现类
- xxxService接口:用于定义service功能的接口(调用Dao层实现功能)
Controller层
为了区分功能的调用,我们将功能接在URI后的新增一层
例如:本Servlet的访问路径为/xxx,可以在URI加一级路径
增加的请求 :/xxx/add
删除的请求 :/xxx/remove
修改的请求 :/xxx/update
查询的请求 :/xxx/find
在service方法中,通过分割URI的方式,提取出要请求的功能,分别调用
注:WebServlet注解要写成("/xxx/*")
String[] split = req.getRequestURI().split("/");//URI:/schedule/xxx
switch (split[split.length - 1]) {
case "add": add(req, resp); break;
case "update": update(req, resp); break;
case "remove": remove(req, resp); break;
case "find": find(req, resp); break;
default: break;
}
可以看出,URI中的功能名和我们调用的方法名一致
所以,以上代码我们可以通过反射,使用分割URI的方式提取出功能名,再使用功能名调用方法!!! 😊
String[] split = req.getRequestURI().split("/");//URI:/schedule/xxx
Class<? extends SysScheduleController> clazz = getClass();
try {
Method declaredMethod = clazz.getDeclaredMethod(split[split.length - 1], HttpServletRequest.class, HttpServletResponse.class);//通过反射,使用功能名获得即将要执行的方法
declaredMethod.setAccessible(true);//设置方法穿透
declaredMethod.invoke(this,req,resp);//调用方法啊,传参
} catch (Exception e) {
e.printStackTrace();
}
这种编程思想使得代码的泛用性更高,只需要增加方法即可
再将增删改查的方法封装
protected void add(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("add");
}
protected void remove(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("remove");
}
protected void update(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("update");
}
protected void find(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("find");
}
BaseController
基于以上思想,我们将公共代码提取出一个BaseController的父类,提高代码的复用性
与BaseDAO类似,我们可以将实现类继承此类,并且不再需要继承HttpServlet类
实现类中可以不用重写service方法,直接写功能方法即可
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;
/**
* 注:WebServlet注解要写成("/xxx/*")
* 此类封装:通过URI分割获取功能名反射到Controller层执行方法的功能实现
* 其他Controller类直接继承此类即可(不需要再额外继承HttpServlet类,因为本类已经继承)
*/
public class BaseController extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String[] split = req.getRequestURI().split("/");
Class<? extends BaseController> clazz = getClass();
try {
Method declaredMethod = clazz.getDeclaredMethod(split[split.length - 1], HttpServletRequest.class, HttpServletResponse.class);
declaredMethod.setAccessible(true);
declaredMethod.invoke(this,req,resp);
} catch (Exception e) {
e.printStackTrace();
}
}
}
MD5加密工具类
MD5 常被用于对密码等敏感信息进行单向加密,以便存储在数据库中,而不需要存储原始明文密码
他是一个常量类(静态方法),通常用于在service层,对明文密码进行处理再发到数据库储存
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加密出错!!!")
}
}
}