week13_day03_MVC

2.MVC
注册登录案例,数据保存在json文件中。

还想在新的Moudle中导入Gson的包,在同一project的另一个Moudle中已经导入过Gson的包了,就不需要重新add as library了。
可以右击Moudle—open Moudle settings
在这里插入图片描述
然后点击右侧的library
在这里插入图片描述
Add select即可

最后注册的新的账号密码会在部署目录下的user.json中找到,在开发目录中的user.json是不会有新账号添加进去的。

代码主要逻辑:
RegisterServlet:

package com.cskaoyan;

import com.cskaoyan.bean.User;
import com.cskaoyan.utils.StringUtils;
import com.google.gson.Gson;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonParser;
import com.sun.xml.internal.messaging.saaj.util.ByteOutputStream;

import javax.imageio.spi.RegisterableService;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.util.ArrayList;
import java.util.List;

/**
 * @author shihao
 * @create 2020-07-02 10:15
 */
@WebServlet("/register")
public class registerServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //注册,注册的信息保存在json文件中
        //取出参数,判断用户名是否一致
        String username = request.getParameter("username");
        String password = request.getParameter("password");
        String confirmPassword = request.getParameter("confirmPassword");
        //校验,是否为空,密码与校验密码是否为空
        if (StringUtils.isEmpty(username) || StringUtils.isEmpty(password) || StringUtils.isEmpty(confirmPassword)) {
            response.getWriter().println("参数不能为空!");
            return;
        }
        if (!password.equals(confirmPassword)) {
            response.getWriter().println("两次密码不一致,请确认");
            return;
        }
        //封装对象
        User user = new User();
        user.setUsername(username);
        user.setPassword(password);


        //json文件中是否存在这个用户名,不存在才注册
        //读取user.json文件
        InputStream inputStream = registerServlet.class.getClassLoader().getResourceAsStream("user.json");
        //形成一个字符串就行了
        ByteArrayOutputStream byteOutputStream = new ByteArrayOutputStream();
        byte[] bytes = new byte[1024];
        int len;
        //把整个流信息读取到byte Array中
        while ((len = inputStream.read(bytes)) != -1) {
            byteOutputStream.write(bytes, 0, len);
        }
        String jsonStr = byteOutputStream.toString("utf-8");

        //将jsonStr转换成json对象
        Gson gson = new Gson();
        List<User> users = new ArrayList<>();
        if (!"".equals(jsonStr)) {
            JsonElement jsonElement = new JsonParser().parse(jsonStr);
            JsonArray jsonArray = jsonElement.getAsJsonArray();
            for (JsonElement element : jsonArray) {
                User u = gson.fromJson(element, User.class);
                //判断是否存在当前用户名
                if (u.getUsername().equals(username)) {
                    response.getWriter().println("当前用户名已经存在");
                    return;
                }
                //将user.json文件中的所有数据都写出到users这个list中
                users.add(u);
            }
        }

        //在list中再加入新的user对象
        users.add(user);

        //注册完毕,把users这个list中的数据写回到user.json文件中
        String s = gson.toJson(users);
        String file = registerServlet.class.getClassLoader().getResource("user.json").getFile();
        FileOutputStream fos = new FileOutputStream(file);
        fos.write(s.getBytes("utf-8"));
        response.getWriter().println("注册成功,即将跳转至登录页面...");
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

    }
}

如果这个时候业务需求变更,不再要求使用json来操作,而是要求使用数据库,整体的一个功能不变,只是更改技术的实现形式。下面所有的代码都需要全部替换,但是框内标注出来的需要保留下来。
在这里插入图片描述
但我们发现这段代码的耦合度非常高,这就引入了MVC的概念。
在这里插入图片描述
user对象属于model,对user对象的所有操作:比如注册、判断用户名是否存在、登录,这些都是对于user对象的操作。也算model。

View:对数据模型的显示。用户个人页面:显示的就是user的信息。Jsp。

Controller:中转站。中间人。请求到来以后,控制器做一些处理,比如校验,之后调用model的一个或者多个方法,接下来model返回结果,根据结果的不同,调用不同的视图。model和view之间就不会产生任何的影响。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

此时耦合程度相较于之前减少了很多。需要将数据保存到mysql里。
在这里插入图片描述
从json迁移到mysql,只需要将controller里面这两行代码做一个更改,其他完全不用变。

只要原先的json实现和mysql实现,他们返回的结果都是同样的含义,即true就表示存在,false就表示不存在。那么视图层的代码完全不会受到任何影响。
是不是相当于制定了一个规范、标准???????
哪个天生就是一个标准???????接口。

2.1.三层架构
接下来,需要将MVC进一步优化,这里面其实还有很大可优化的空间?如果方法很多,需要将每个方法里面的之前的model全部换成新的model,更改的地方还是很多。
仔细地去体会一下,为什么仅需要去修改类名,而不需要去修改方法名称以及返回值,因为我们是刻意这么做的,因为这样做的话修改的地方最少。潜意识里去做一个标准。
为何不用天生就适合做标准的呢?????????接口。
使用接口,不管是Json还是Mysql,其实都是在操作数据,又可以给它们重新取一个名字,叫做DAO,Data Access Object。
三层架构,究竟是哪三层呢?
说法很多,展示层、业务层service、数据层dao
Controller、service、dao
有一个疑惑:
感觉有controller和dao已经可以实现功能了,为什么还需要有service呢?
对于一些逻辑非常简单的模块,没有service感觉没有任何影响,但是
如果对于一些业务逻辑比较复杂的模块,service就体现出它的功能了。
比如分页查询数据结果。
在这里插入图片描述
分页显示图中数据。
一共多少条记录,每页多少条,一共多少页,同时展示当前页应该显示的数据条目。

Map map = userDao.queryPageUsers(currentPage);
map里面应当包含总记录数、每页数据、总页数、当前页里面的条目
所以此时dao里面的代码需要做很多的逻辑,发起两次查询,count page数据
如果dao里面的逻辑非常多,那么它的可复用性就会很差
比如在其他地方,只需要查询总记录数,那么就会显得很不方便。
每次查询数据库应当尽可能是单一的,这样可复用性就会很高。
组织在一起的话,就在service层里面做。

Request.setAttribute(map, map);
转发给视图

比较好的代码应当是这样的:
Controller:
不是直接调用dao层,而是调用service

Map map = userService.queryPageUsers(currentPage)

service层中:发起一个一个的dao调用
queryPageUsers方法内:
调用dao层的多个方法:
Total = userDao.totalCount()
List = userDao.currentPageUser(currentPage);

totalPage = total/page_size

真的不知道怎么debug的话就在doPost第一行代码中打一个断点,和在doGet中打一个断点。因为这是servlet的执行入口

在这里插入图片描述
Controller:控制器;做一些校验;调用service返回结果,根据结果调用不同的视图
Service和Dao其实就相当于之前的model
Service:业务;每个功能具体的业务逻辑应当写在service,每个功能区别于其他功能这些独特的代码应当写在service。比如分页显示数据。事务。
Dao:发起一个一个的sql语句。一个dao方法里面最好不要多次sql操作,否则它的可复用性会很差。
在这里插入图片描述
此时,不同模块之间的耦合点在哪?
在这里插入图片描述
controller和service的耦合点
在这里插入图片描述
service和dao的耦合点

此时的耦合程度算高还是低呢?低。那能不能更低呢?
在这里插入图片描述
耦合度再低一点就是红线部分的删除掉,这样controller中存的仅仅是service接口的一个引用,并没有主动去给其赋值,给他赋值可能会是其他容器在某一阶段给赋的值。

这其实就是Spring的思想。
SpringMVC:作用于controller、view
Spring:不是作用于service。一整套的解决方案,将各个部分进行解耦与整合。
Mybatis:作用于dao

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

-玫瑰少年-

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值