前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >简单实现MVC模式

简单实现MVC模式

作者头像
端碗吹水
发布2020-09-23 12:40:46
6020
发布2020-09-23 12:40:46
举报

我们都知道MVC有两个经典的模式,MVC1和MVC2:

简单实现MVC模式
简单实现MVC模式

View接受用户输入,并传递到Controller。 Controller统一进行处理命令,交由Model处理具体的业务。 经过处理Model更新后,通知View进行更新。

这种模式主要用于桌面程序,使用观察者模式实现,具体来说就是让View观察Model,而用户交互控制的地方用匿名类的方式统一放在Controller中。像MFC的frame-document-view架构,如果document改变了,他会主动通知View进行update。但是在WEB应用程序中,Model(在Java中通常是JavaBean)的数据更新后,无法通知View进行更新(View在Java中通常是非常多JSP页面,需要选择一个),因此,在WEB应用程序中应该使用下面这种模式:MVC2模式

简单实现MVC模式
简单实现MVC模式

View接受用户输入,并传递到Controller。 Controller统一进行处理命令,交由model处理具体的业务。 经过处理的Model更新后,Controller会选一个View并把Model内容传递(request,session)给它(forward)。然后View进行显示。

两者区别: Model是否能主动通知View就是MVC1和MVC2模式的主要差别。桌面程序可以做到,所以使用MVC1;Web程序由于Http协议的限制做不到,所以使用MVC2

本例简单使用 JSP+Servlet+JavaBean 实现一个简单的MVC模式,因为MVC1模式适合桌面程序,web应用程序适合使用MVC2模式,所以我们要实现的是MVC2模式。

1.首先创建Maven的web工程,配置pom.xml依赖如下:

代码语言:javascript
复制
<dependencies>
    <dependency>
      <groupId>org.json</groupId>
      <artifactId>json</artifactId>
      <version>20160810</version>
    </dependency>
    <dependency>
      <groupId>javax</groupId>
      <artifactId>javaee-api</artifactId>
      <version>7.0</version>
      <scope>provided</scope>
    </dependency>
    <dependency>
      <groupId>javax.servlet</groupId>
      <artifactId>jstl</artifactId>
      <version>1.2</version>
    </dependency>
  </dependencies>

2.WEB-INF目录下的web.xml文件配置内容如下,不然使用不了EL表达式:

代码语言:javascript
复制
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee     http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
         version="3.1">
</web-app>

3.在resource目录下创建一个json文件,这个json文件是用于配置model层信息以及响应页面的,它相当于一个池子,配置信息内容如下:

代码语言:javascript
复制
{
  "mvc":[
    {
      "actionName":"/login",
      "className":"org.zero01.javabean.LoginBean",
      "ok":"success.jsp",
      "error":"index.jsp"
    }
  ]
}

4.编写主页面index.jsp,做一个简单的表单提交模拟登录,内容如下:

代码语言:javascript
复制
<%@ page contentType="text/html;charset=UTF-8" language="java" pageEncoding="UTF-8" %>
<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <title>Title</title>
</head>
<body>
<p style="color: red">${error}</p>
<form action="login.action" method="post">
    <input type="text" name="username" placeholder="用户名"/><br>
    <input type="password" name="password" placeholder="密码"/><br>
    <input type="submit"/>
</form>
</body>
</html>

5.编写success.jsp,该页面是登录成功后响应的页面,内容如下:

代码语言:javascript
复制
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<script>
    alert("登录成功!");
</script>
<body>

</body>
</html>

6.完成以上view层的编写后,先编写model层。声明一个抽象接口,简单应用面向接口编程,Login.java内容如下:

代码语言:javascript
复制
package org.zero01.javabean;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public interface Login {

    public String excute(HttpServletRequest req, HttpServletResponse resp);

}

7.实现以上声明的接口,LoginBean.java内容如下:

代码语言:javascript
复制
package org.zero01.javabean;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class LoginBean implements Login {

    public String excute(HttpServletRequest req, HttpServletResponse resp) {

        // 接收表单数据
        String userName = req.getParameter("username");
        String password = req.getParameter("password");

        // 验证表单数据,返回相应的结果
        if (userName == null || userName.trim().equals("") || password == null || password.trim().equals("")) {
            req.setAttribute("error","用户名或密码不能为空!");
            return "error";
        } else if (userName.equals("lisi") && password.equals("123456")) {
            return "ok";
        }
        req.setAttribute("error","用户名或密码错误!");
        return "error";
    }
}

8.最后是完成Controller控制器的编写,ActionServlet.java内容如下:

代码语言:javascript
复制
package org.zero01.servlet;

import org.json.JSONArray;
import org.json.JSONObject;
import org.zero01.javabean.Login;

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.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;

@WebServlet("*.action")
public class ActionServlet extends HttpServlet {

    private JSONObject config = null;

    // 初始化时加载配置信息
    public void init() throws ServletException {
        try {

            // 读取json文件的内容
            File file = new File(this.getServletContext().getRealPath("WEB-INF"), "classes/mvc2.json");
            FileReader fileReader = new FileReader(file);
            BufferedReader bufferedReader = new BufferedReader(fileReader);

            StringBuffer stringBuffer = new StringBuffer();
            String line = null;

            // 将读取的内容追加到字符串里
            while ((line = bufferedReader.readLine()) != null) {
                stringBuffer.append(line);
            }

            bufferedReader.close();
            // 把字符串内容转换成json对象
            config = new JSONObject(stringBuffer.toString());
            System.out.println("配置信息加载完成!");
        } catch (Exception e) {
            e.printStackTrace();
            System.err.println("配置信息加载失败!");
        }
    }

    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

        // 如果请求资源的后缀不是.action就报404
        String uri = req.getRequestURI();
        if (!uri.endsWith(".action")) {
            resp.sendError(404, "The Page Not Found!");
            return;
        }

        // 截取出请求资源的前缀
        String actionName = uri.substring(0, uri.indexOf("."));
        System.out.println(actionName);

        try {
            // 取出mvc数组中的json对象
            JSONArray jsonArray = config.getJSONArray("mvc");
            for (int i = 0; i < jsonArray.length(); i++) {
                JSONObject object = jsonArray.getJSONObject(i);

                // 调用相应的model
                if (object.getString("actionName").equals(actionName)) {
                    Login login = (Login) Class.forName(object.getString("className")).newInstance();

                    String name = login.excute(req, resp);
                    // 将结果返回view
                    req.getRequestDispatcher(object.getString(name)).forward(req, resp);

                    return;
                }
            }
            resp.sendError(404, "The Page Not Found!");
        } catch (Exception e) {
            e.printStackTrace();
            resp.sendError(500, "The config file error!");
        }

    }
}

运行结果:

简单实现MVC模式
简单实现MVC模式
简单实现MVC模式
简单实现MVC模式
简单实现MVC模式
简单实现MVC模式
简单实现MVC模式
简单实现MVC模式
简单实现MVC模式
简单实现MVC模式
简单实现MVC模式
简单实现MVC模式
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2018-01-21 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档