前面两篇,描述了自己刚接触时的心理,及对于下一步学习的计划。本篇博客旨在理解目前系统的业务逻辑,即数据如何传递,前后端交互的逻辑等

MVC

一切一切的根源要从数据源头说起,数据存在数据库之中,那么我们的目的就是将数据从数据库中取出,并且要显示在页面之中。那么页面和数据库中间就需要一个控制的东西,即控制器,将数据模型控制响应前端请求渲染成前端页面。这就是经典的mvc三层架构模型,如jsp+servlet+javabean。实体类与数据库中的表列名一一对应,通过javabean来传递数据库中的数据。增删改查的方法一些基本服务,为了方便添加其余的方法,定义一个服务接口,让实现类实现需要实现的方法。dao层对数据库进行增删改查,实现对数据层的操作,service层实现对dao层的操作。前端发送请求,servlet响应,将数据发送到前端,jsp解析渲染成页面。基本的数据传递过程大抵如此。

项目流程

本项目中使用了mybatis和mybatis-plus对数据库进行增删改查,用mapper映射取代了dao层原来的jdbc查询。
sringMvc起到控制层的作用。springmvc将前端所有的请求都提交到一个总控制器DispatcherServlet,再让这个总的控制器查询处理器的映射器来找到处理器,然后调用处理器将这个请求调到controller,控制器调用业务层,业务层通过mapper映射查到数据,最后控制器返回一个ModelandView,模型和视图。DispatcherServlet查询一个或多个ViewResoler视图解析器,找到ModelAndView指定的视图。视图将结果显示到客户端。详细可以参考springMvc学习小结1
后端传到前端的一般是json的格式,我们需要封装一个统一的接口,一般含有状态码,信息提示,还是数据。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
public interface Constants {
String CODE_200 = "200";//成功
String CODE_500 = "500";//系统错误
String CODE_600 = "600";//其他业务异常
String CODE_401 = "401";//权限不足
String CODE_400 = "400";//参数错误
}

@Data
@AllArgsConstructor
@NoArgsConstructor
public class Result {
private String code;
private String msg;
private Object data;

//成功
public static Result success() {
return new Result(Constants.CODE_200, "", null);
}

public static Result success(Object data) {
return new Result(Constants.CODE_200, "", data);
}

//error
public static Result error(String code, String msg) {
return new Result(code, msg, null);
}

public static Result error() {
return new Result(Constants.CODE_500, "系统错误", null);
}

}

还可以自定义异常,这样可以根据状态码返回错误信息。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
@Getter
public class ServiceException extends RuntimeException {
private String code;
public ServiceException(String code,String msg){
super(msg);
this.code=code;
}

}

//@ControllerAdvice,是Spring3.2提供的新注解,它是一个Controller增强器,可对controller中被 @RequestMapping注解的方法加一些逻辑处理。最常用的就是异常处理
//统一异常处理
//需要配合@ExceptionHandler使用。
//当将异常抛到controller时,可以对异常进行统一处理,规定返回的json格式或是跳转到一个错误页面
@ControllerAdvice
public class GlobalExceptionHandler {

@ExceptionHandler(ServiceException.class)
@ResponseBody
private Result handle(ServiceException se){
return Result.error(se.getCode(),se.getMessage());
}
}

通过Swagger来进行接口文档在线生成,方便测试。详细可以点击-》Swagger使用和注释介绍
通过JWT来对用户的登录进行认证授权,拦截登录等等。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
@Component
public class JwtInterceptor implements HandlerInterceptor {
@Autowired
UserServiceImpl userServiceImpl;

@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
String token = request.getHeader("token");
//如果不是映射直接通过
if (!(handler instanceof HandlerMethod)) {
return true;
}
//执行认证
if (StrUtil.isAllBlank(token)) {
throw new ServiceException(Constants.CODE_401, "无token,请重新登录");

}
//获取 token中的userid
String useId;
try {
useId = JWT.decode(token).getAudience().get(0);
} catch (JWTDecodeException j) {
throw new ServiceException(Constants.CODE_401, "token验证失败,请重新登录");
}
//根据token中的userid查询数据库
User user = userServiceImpl.getById(useId);
if (user == null) {
throw new ServiceException(Constants.CODE_401, "用户不存在,请重新登录");
}
//用户密码加签 验证token
JWTVerifier jwtVerifier=JWT.require(Algorithm.HMAC256(user.getPassword())).build();
try {
jwtVerifier.verify(token);
}catch (JWTDecodeException j){
throw new ServiceException(Constants.CODE_401,"token验证失败,请重新登录");
}
return true;
}
}

mvvm

View是视图层,也就是用户界面。前端主要由HTML和CSS来构成,为了更方便地展现ViewModel或者Model层的数据。
Model是指数据模型,泛指后端进行的各种业务逻辑处理和数据操控,主要围绕数据库系统展开。这里的难点主要在于需要和前端约定统一的接口规则。
ViewModel由前端开发人员组织生成和维护的视图数据层。在这一层,前端开发者从后端获取得到Model数据进行转换出来,做二次封装,以生成符合View层使用预期的视图数据模型。视图状态和行为都封装在ViewModel里。这样的封装使得ViewModel可以完整地去描述View层。

综上所述,可以看出mvvm起源于mvc,它与MVC框架的主要区别有两点:
1、实现数据与视图的分离
2、通过数据来驱动视图,开发者只需要关心数据变化,DOM操作被封装了。

mvvm

相关可以参考-》揭开MVC与MVVM的设计思想的面纱?

总结

写了自己对于mvc设计模式的一些想法,自己项目的一些业务逻辑,使用的组件,还有前端mvvm的一些理解,刚刚使用vuejs对于mvvm还是不是很了解,一些问题解释不清楚,还是需要对vue进行详细的学习的。