本文共 5554 字,大约阅读时间需要 18 分钟。
我们都知道MVC有两个经典的模式,MVC1和MVC2:
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模式
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依赖如下:
org.json json 20160810 javax javaee-api 7.0 provided javax.servlet jstl 1.2
2.WEB-INF目录下的web.xml文件配置内容如下,不然使用不了EL表达式:
3.在resource目录下创建一个json文件,这个json文件是用于配置model层信息以及响应页面的,它相当于一个池子,配置信息内容如下:
{ "mvc":[ { "actionName":"/login", "className":"org.zero01.javabean.LoginBean", "ok":"success.jsp", "error":"index.jsp" } ]}
4.编写主页面index.jsp,做一个简单的表单提交模拟登录,内容如下:
<%@ page contentType="text/html;charset=UTF-8" language="java" pageEncoding="UTF-8" %>Title ${error}
5.编写success.jsp,该页面是登录成功后响应的页面,内容如下:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>Title
6.完成以上view层的编写后,先编写model层。声明一个抽象接口,简单应用面向接口编程,Login.java内容如下:
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内容如下:
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内容如下:
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!"); } }}
运行结果:
转载于:https://blog.51cto.com/zero01/2063403