Java Web ——MVC基础框架讲解及代码演示(上)

简介: Java Web ——MVC基础框架讲解及代码演示

了解一下类似Spring MVC框架的底层实现

相信看完这个短文,MVC你就懂了,还不懂请艾特我······

带着问题去学习

  • MVC到底是什么?
  • 如何实现MVC?

开始!

MVC是什么?

Web开发

在讲MVC之前,还是简要介绍一下Web开发吧,相信搞程序的或多或少都知道Web编程、Socket编程等等。

其实开发Web应用最原始的方式面向Http连接的底层进行开发,自己编写Web服务,需要了解和考虑的内容包括但不限于:Socket编程、端口号、报文处理、IO多路复用、线程池等等。

举个例子,用Java来编写一个Http服务器:

public class Server {
    public static void main(String[] args) throws IOException {
        ServerSocket ss = new ServerSocket(8080); // 监听指定端口
        System.out.println("server is running...");
        for (;;) {
            Socket sock = ss.accept();
            System.out.println("connected from " + sock.getRemoteSocketAddress());
            Thread t = new Handler(sock);
            t.start();
        }
    }
}

class Handler extends Thread {
    Socket sock;

    public Handler(Socket sock) {
        this.sock = sock;
    }

    public void run() {
        try (InputStream input = this.sock.getInputStream()) {
            try (OutputStream output = this.sock.getOutputStream()) {
                handle(input, output);
            }
        } catch (Exception e) {
            try {
                this.sock.close();
            } catch (IOException ioe) {
            }
            System.out.println("client disconnected.");
        }
    }

    private void handle(InputStream input, OutputStream output) throws IOException {
        System.out.println("Process new http request...");
        var reader = new BufferedReader(new InputStreamReader(input, StandardCharsets.UTF_8));
        var writer = new BufferedWriter(new OutputStreamWriter(output, StandardCharsets.UTF_8));
        // 读取HTTP请求:
        boolean requestOk = false;
        String first = reader.readLine();
        if (first.startsWith("GET / HTTP/1.")) {
            requestOk = true;
        }
        for (;;) {
            String header = reader.readLine();
            if (header.isEmpty()) { // 读取到空行时, HTTP Header读取完毕
                break;
            }
            System.out.println(header);
        }
        System.out.println(requestOk ? "Response OK" : "Response Error");
        if (!requestOk) {
            // 发送错误响应:
            writer.write("HTTP/1.0 404 Not Found\r\n");
            writer.write("Content-Length: 0\r\n");
            writer.write("\r\n");
            writer.flush();
        } else {
            // 发送成功响应:
            String data = "<html><body><h1>Hello, world!</h1></body></html>";
            int length = data.getBytes(StandardCharsets.UTF_8).length;
            writer.write("HTTP/1.0 200 OK\r\n");
            writer.write("Connection: close\r\n");
            writer.write("Content-Type: text/html\r\n");
            writer.write("Content-Length: " + length + "\r\n");
            writer.write("\r\n"); // 空行标识Header和Body的分隔
            writer.write(data);
            writer.flush();
        }
    }
}

一个Http服务器,本质上来说就是TCP服务器,处理流程就是服务器一直监听端口,客户端向指定端口发送请求,服务器接收请求进行相应的逻辑处理,而后将处理结果又返回给客户端,最后在客户端浏览器上进行展示。更详细的玩意儿还是参见《Unix网络编程》那本书的例子,可以模仿C语言写个Java的客户端

但是在实际开发过程中,这些基础、底层的工作,就是重复造轮子,需要耗费大量的时间!

为了方便开发,将这些底层工作封装到一个库中——Servlet中,于是后来的程序员只需要基于Servlet的API来开发Web应用即可,不用再去管这些端口啊、IO多路复用什么的。

基于Servlet开发

基于Servlet开发可以大大减小开发Web服务的复杂程度,例如只需要几行代码,就可以让服务端相应客户端对主页的请求:

//原址https://www.liaoxuefeng.com/wiki/1252599548343744/1304265949708322
//WebServlet注解表示这是一个Servlet,并将url地址为"/"的请求映射到这个类中进行处理
@WebServlet(urlPatterns = "/")
public class HelloServlet extends HttpServlet {
    protected void doGet(HttpServletRequest req, 
                         HttpServletResponse resp)
        throws ServletException, IOException {
        // 设置响应类型:
        resp.setContentType("text/html");
        // 获取输出流:
        PrintWriter pw = resp.getWriter();
        // 写入响应:
        pw.write("<h1>Hello, world!</h1>");
        // flush强制输出:
        pw.flush();
    }
}

一个Web应用其实就是由一个或多个Servlet组成的,每个Servlet通过注解说明自己负责的路径Url,并通过实现doGet和doPost方法来进行相应的逻辑处理。比如处理GET方法,就覆写doGet()方法:

@WebServlet(urlPatterns = "/hello")
public class HelloServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        ...
        }
}

其他的如POST等请求方法也是类似的。

可以看到,当有了Servlet之后,开发Web应用就变得简洁了起来,只需要编写处理对应url的逻辑处理即可。

但是,你们有没有发现一个问题——在Java代码里出现了跟前端有关的代码。在Servlet程序中,输出HTML的方式如下:

PrintWriter pw = resp.getWriter();
pw.write("<html>");
pw.write("<body>");
pw.write("<h1>Welcome, " + name + "!</h1>");
pw.write("</body>");
pw.write("</html>");
pw.flush();

上述这种输出HTML的步骤较为繁琐,而且容易出错,并且也不像直接编写HTML网页那么直观(比如JS、CSS语言),虽然全栈工程师前后端都可以care,不过在项目开发中还是前端和后端的东西各自分开最好,才能使两者的开发效率最高。


为了解决这个问题,后面出现了JSP(Java Server Pages)语言。


JSP代码类似于html语言,并且其中还可以嵌入Java代码,进行变量插入、变量输出等操作:

//原址:https://www.liaoxuefeng.com/wiki/1252599548343744/1266262958498784
<html>
<head>
<title>Hello World - JSP</title>
</head>
<body>
<%-- JSP Comment --%>
<h1>Hello World!</h1>
<p>
<%
out.println("Your IP address is ");
%>
    <span style="color:red">
    <%= request.getRemoteAddr() %>
    </span>
    </p>
    </body>
</html>

不过这种方式(JSP)虽然可以很方便的输出HTML,并在其中实现一定的动态内容,运行简单的代码,但是写起Java来也忒不适应了吧,总感觉怪怪的。


另外,Servlet简化了Web应用的开发,可以基于Java语言实现复杂的业务逻辑,但是不太适合输出HTML。


那么,有没有一种方式可以结合两者,从而是两者相辅相成呢?


有的!那就是MVC!

MVC设计模式

先给出MVC设计模式的简单定义——Model-View-Controller:

  • Model(模型)是前后端定义的数据传输单元,通常前端只是需要后端提供一些数据来展示而已,比如用户名、处理结果来,需要HTML输出的东西;
  • View(视图)的工作就是接收后端发过来的Model,取出数据,然后写入Html中;
  • Controller(控制器)其实就是业务逻辑,类似于之前的Servlet开发,区别在于现在将处理结果都放在Model里,然后发给View;

来个例子吧,实现用户登录,获取信息

首先,我们编写了两个JavaBean(JavaBean简单来说就是一个可以放入数据和取出数据的类),也就是之前说的Model

//源码:https://www.liaoxuefeng.com/wiki/1252599548343744/1266264917931808
public class User {
    public long id;
    public String name;
    public School school;
}
public class School {
    public String name;
    public String address;
}

接着,来实现Controller,在UserServlet中实现从数据库读取User、School等信息,并放入Request中,再发送给user.jsp,也就是View进行渲染处理:

@WebServlet(urlPatterns = "/user")
public class UserServlet extends HttpServlet {
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 假装从数据库读取:
        School school = new School("No.1 Middle School", "101 South Street");
        User user = new User(123, "Bob", school);
        // 放入Request中:
        req.setAttribute("user", user);
        // forward给user.jsp:
        req.getRequestDispatcher("/WEB-INF/user.jsp").forward(req, resp);
    }
}

View——user.jsp负责将接收到的user信息进行渲染展示,即写入Html中:

<%@ page import="com.itranswarp.learnjava.bean.*"%>
<%
User user = (User) request.getAttribute("user");
%>
    <html>
    <head>
    <title>Hello World - JSP</title>
    </head>
    <body>
    <h1>Hello <%= user.name %>!</h1>
    <p>School Name:
<span style="color:red">
<%= user.school.name %>
    </span>
    </p>
    <p>School Address:
<span style="color:red">
<%= user.school.address %>
    </span>
    </p>
    </body>
</html>

以上,就完成了一个简单的web应用,在浏览器访问http://localhost:8080/user,结果如下:

捋一捋,用一个结构图来描述上述代码:

简单来说,就是将整个Web开发分成了三个部分:逻辑处理、前端展示、数据传输,分别代表Controller、View、Model。

这种方式有什么好处?分工明确、开发简单。

Controller就好好关注逻辑处理,比如访问数据库啦、进行复杂的逻辑交互等等;View就关注如何让界面好看就完了,比如用模板引擎写出好看的界面,留几个空白给Model进行展示就ok了!


有关模板引擎的具体内容,可以了解:https://blog.csdn.net/qq_42266891/article/details/108265478


实现一个简单MVC框架

Java Web ——MVC基础框架讲解及代码演示(下):https://developer.aliyun.com/article/1508612

相关文章
|
5天前
|
SQL 安全 PHP
探索PHP的现代演进:从Web开发到框架创新
PHP是一种流行的服务器端脚本语言,自诞生以来在Web开发领域占据重要地位。从简单的网页脚本到支持面向对象编程的现代语言,PHP经历了多次重大更新。本文探讨PHP的现代演进历程,重点介绍其在Web开发中的应用及框架创新,如Laravel、Symfony等。这些框架不仅简化了开发流程,还提高了开发效率和安全性。
13 3
|
4天前
|
前端开发 JavaScript 开发工具
从框架到现代Web开发实践
从框架到现代Web开发实践
14 1
|
7天前
|
SQL 安全 PHP
探索PHP的现代演进:从Web开发到框架创新
PHP 自发布以来一直在 Web 开发领域占据重要地位,历经多次重大更新,从简单的脚本语言进化为支持面向对象编程的现代语言。本文探讨 PHP 的演进历程,重点介绍其在 Web 开发中的应用及框架创新。自 PHP 5.3 引入命名空间后,PHP 迈向了面向对象编程时代;PHP 7 通过优化内核大幅提升性能;PHP 8 更是带来了属性、刚性类型等新特性。
18 3
|
8天前
|
jenkins Java 测试技术
如何使用 Jenkins 自动发布 Java 代码,通过一个电商公司后端服务的实际案例详细说明
本文介绍了如何使用 Jenkins 自动发布 Java 代码,通过一个电商公司后端服务的实际案例,详细说明了从 Jenkins 安装配置到自动构建、测试和部署的全流程。文中还提供了一个 Jenkinsfile 示例,并分享了实践经验,强调了版本控制、自动化测试等关键点的重要性。
38 3
|
8天前
|
Java
Java代码解释++i和i++的五个主要区别
本文介绍了前缀递增(++i)和后缀递增(i++)的区别。两者在独立语句中无差异,但在赋值表达式中,i++ 返回原值,++i 返回新值;在复杂表达式中计算顺序不同;在循环中虽结果相同但使用方式有别。最后通过 `Counter` 类模拟了两者的内部实现原理。
Java代码解释++i和i++的五个主要区别
|
3月前
|
开发框架 前端开发 .NET
ASP.NET MVC WebApi 接口返回 JOSN 日期格式化 date format
ASP.NET MVC WebApi 接口返回 JOSN 日期格式化 date format
46 0
|
6月前
|
开发框架 前端开发 .NET
ASP.NET CORE 3.1 MVC“指定的网络名不再可用\企图在不存在的网络连接上进行操作”的问题解决过程
ASP.NET CORE 3.1 MVC“指定的网络名不再可用\企图在不存在的网络连接上进行操作”的问题解决过程
189 0
|
6月前
|
开发框架 前端开发 JavaScript
JavaScript云LIS系统源码ASP.NET CORE 3.1 MVC + SQLserver + Redis医院实验室信息系统源码 医院云LIS系统源码
实验室信息系统(Laboratory Information System,缩写LIS)是一类用来处理实验室过程信息的软件,云LIS系统围绕临床,云LIS系统将与云HIS系统建立起高度的业务整合,以体现“以病人为中心”的设计理念,优化就诊流程,方便患者就医。
78 0
|
存储 开发框架 前端开发
[回馈]ASP.NET Core MVC开发实战之商城系统(五)
经过一段时间的准备,新的一期【ASP.NET Core MVC开发实战之商城系统】已经开始,在之前的文章中,讲解了商城系统的整体功能设计,页面布局设计,环境搭建,系统配置,及首页【商品类型,banner条,友情链接,降价促销,新品爆款】,商品列表页面,商品详情等功能的开发,今天继续讲解购物车功能开发,仅供学习分享使用,如有不足之处,还请指正。
163 0
|
开发框架 前端开发 .NET
[回馈]ASP.NET Core MVC开发实战之商城系统(三)
[回馈]ASP.NET Core MVC开发实战之商城系统(三)
97 0
下一篇
无影云桌面