MVC 模式和模型 2

MVC框架

一个实现 MVC 模式的应用包含模型、视图、控制器 3 个模块:

模型:封装了应用的数据和业务逻辑,负责管理系统业务数据

视图:负责应用的展示

控制器:负责与用户进行交互,接收用户输入、改变模型、调整视图的显示

基于MVC架构模式的 Java Web 开发

采用了 Servlet + JSP + JavaBean 的技术实现

基于MVC架构模式的 Java Web 开发步骤

1. 定义一系列的 Bean 来表示数据

2. 使用一个 Dispatcher Servlet 和控制类来处理用户请求

3. 在 Servlet 中填充 Bean

4. 在 Servlet 中,将 Bean 存储到 request、session、servletContext中

5. 将请求转发到 JSP 页面

6. 在 JSP 页面中,从 Bean 中提取数据。

其中 Dispatcher servlet 必须完成如下功能:

1. 根据 URI 调用相应的 action

2. 实例化正确的控制器类

3. 根据请求参数值来构造表单 bean

4. 调用控制器对象的相应方法

5. 转发到一个视图(JSP页面)

每个 HTTP 请求都发送给控制器,请求中的 URI 标识出对应的 action。action 代表了应用可以执行的一个操作。一个提供了 Action 的 Java 对象称为 action 对象。

控制器会解析 URI 并调用相应的 action,然后将模型对象放到视图可以访问的区域,以便服务器端数据可以展示在浏览器上。最后控制器利用 RequestDispatcher 跳转到视图(JSP页面),在JSP页面使用 EL 以及定制标签显示数据。

注意:调用 RequestDispatcher.forward 方法并不会停止执行剩余的代码。因此,若 forward 方法不是最后一行代码,则应显示的返回。

使用MVC模式的实例

 目录结构如下

代码如下

DispatcherServlet.java

package app16c.servlet;import java.io.IOException;import javax.servlet.RequestDispatcher;
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 app16c.controller.InputProductController;
import app16c.controller.SaveProductController;@WebServlet(name = "DispatcherServlet", urlPatterns = {"/product_input.action", "/product_save.action"})
public class DispatcherServlet extends HttpServlet {private static final long serialVersionUID = 1L;public DispatcherServlet() {super();}protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {process(request, response);}protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {doGet(request, response);}private void process(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {String uri = request.getRequestURI();int lastIndex = uri.lastIndexOf("/");String action = uri.substring(lastIndex + 1);String dispatcherUrl = null;if (action.equals("product_input.action")) {InputProductController controller = new InputProductController();dispatcherUrl = controller.handleRequest(request, response);} else if (action.equals("product_save.action")) {SaveProductController controller = new SaveProductController();dispatcherUrl = controller.handleRequest(request, response);}if (dispatcherUrl != null) {RequestDispatcher rd = request.getRequestDispatcher(dispatcherUrl);rd.forward(request, response);}}
}

Controller.java

package app16c.controller;import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;public interface Controller {public abstract String handleRequest(HttpServletRequest request, HttpServletResponse response);
}

InputProductController.java

package app16c.controller;import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;public class InputProductController implements Controller {@Overridepublic String handleRequest(HttpServletRequest request, HttpServletResponse response) {return "/WEB-INF/jsp/ProductForm.jsp";}
}

SaveProductController.java

package app16c.controller;import java.util.List;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import app16c.domain.Product;
import app16c.form.ProductForm;
import app16c.validator.ProductValidator;public class SaveProductController implements Controller {@Overridepublic String handleRequest(HttpServletRequest request, HttpServletResponse response) {ProductForm productForm = new ProductForm();productForm.setName(request.getParameter("name"));productForm.setDescription(request.getParameter("description"));productForm.setPrice(request.getParameter("price"));ProductValidator productValidator = new ProductValidator();List<String> errors = productValidator.validate(productForm);System.out.println(errors);if (errors.isEmpty()) {Product product = new Product();product.setName(productForm.getName());product.setDescription(productForm.getDescription());product.setPrice(Float.parseFloat(productForm.getPrice()));// insert code to save product to the databaserequest.setAttribute("product", product);return "/WEB-INF/jsp/ProductDetails.jsp";} else {request.setAttribute("errors", errors);request.setAttribute("form", productForm);return "/WEB-INF/jsp/ProductForm.jsp";}}
}

ProductValidator.java

package app16c.validator;import java.util.ArrayList;
import java.util.List;
import app16c.form.ProductForm;public class ProductValidator {public List<String> validate(ProductForm productForm) {List<String> errors = new ArrayList<>();String name = productForm.getName();if (name == null || name.trim().isEmpty()) {errors.add("Product must have a name");}String price = productForm.getPrice();if (price == null || price.trim().isEmpty()) {errors.add("Product must have a price");}else {try {Float.parseFloat(price);} catch (NumberFormatException e) {errors.add("Invalid price value.");}}return errors;}
}

Product.java

package app16c.domain;import java.io.Serializable;public class Product implements Serializable { // 一个JavaBean 实现该接口,其实例可以安全的将数据保存到 HttpSession 中。private static final long serialVersionUID = 1L;private String name;private String description;private float price;public String getName() {return name;}public void setName(String name) {this.name = name;}public String getDescription() {return description;}public void setDescription(String description) {this.description = description;}public float getPrice() {return price;}public void setPrice(float price) {this.price = price;}
}

ProductForm.java

package app16c.form;// 表单类与 HTML表单相映射,是HTML表单在服务端的代表
public class ProductForm {  // 表单类不需要实现 Serializable 接口,因为表单对象很少保存在 HttpSession 中。private String name;private String description;private String price;public String getName() {return name;}public void setName(String name) {this.name = name;}public String getDescription() {return description;}public void setDescription(String description) {this.description = description;}public String getPrice() {return price;}public void setPrice(String price) {this.price = price;}
}

ProductForm.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>  <!-- taglib指令用来引用标签库并设置标签库的前缀  --><!DOCTYPE html>
<html>
<head><meta charset="UTF-8"><title>Add Product Form</title><link rel="stylesheet" type="text/css" href="css/main.css" />  <!-- 外部样式表 -->
</head>
<body><div id="global"><c:if test="${requestScope.errors != null }">  <!-- EL表达式 --><p id="errors">Error(s)!<ul><c:forEach var="error" items="${requestScope.errors }">  <!-- jstl 遍历 --><li>${error }</li></c:forEach></ul></p></c:if><form action="product_save.action" method="post"><fieldset><legend>Add a product</legend><p><label for="name">Product Name: </label><input type="text" id="name" name="name" tabindex="1" /></p><p><label for="description">Description: </label><input type="text" id="description" name="description" tabindex="2" /></p><p><label for="price">Price: </label><input type="text" id="price" name="price" tabindex="3" /></p><p id="buttons"><input id="reset" type="reset" tabindex="4" /><input id="submit" type="submit" tabindex="5" value="Add Product" /></p></fieldset></form></div>
</body>
</html>

ProductDetails.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head><meta charset="UTF-8"><title>Save Product</title><link rel="stylesheet" type="text/scc" href="css/main.css" />
</head>
<body><div id="global"><h4>The product has been saved.</h4><p><h5>Details</h5>Product Name: ${product.name } <br />Description: ${product.description } <br />Price: $${product.price }</p></div>
</body>
</html>

测试结果

 

转载于:https://www.cnblogs.com/0820LL/p/9949873.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/570165.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Java中线程池,你真的会用吗?

在《深入源码分析Java线程池的实现原理》这篇文章中&#xff0c;我们介绍过了Java中线程池的常见用法以及基本原理。 在文中有这样一段描述&#xff1a; 可以通过Executors静态工厂构建线程池&#xff0c;但一般不建议这样使用。 关于这个问题&#xff0c;在那篇文章中并没有深…

深入了解java虚拟机(JVM) 第四章 对象的创建

一、对象的创建过程 对象的创建过程大致可以分为六步&#xff0c;其中对象的分配尤为重要&#xff1a; 二、对象分配内存 一般来说对象分配内存有两种方式&#xff1a; 第一种是指针碰撞&#xff0c;这是一种比较理想的方式&#xff1a;如果Java堆是绝对规整的&#xff1a;一边…

[UWP]使用Picker实现一个简单的ColorPicker弹窗

[UWP]使用Picker实现一个简单的ColorPicker弹窗 原文:[UWP]使用Picker实现一个简单的ColorPicker弹窗在上一篇博文《[UWP]使用Popup构建UWP Picker》中我们简单讲述了一下使用Popup构建适用于MVVM框架下的弹窗层组件Picker的过程。但是没有应用实例的话可能体现不出Picker相对于…

C# WebRequest.Create 锚点“#”字符问题

背景 在与后台API接口对接时&#xff0c;如将网页Url作为参数请求数据时&#xff0c;如果是锚点参数&#xff0c;则会丢失。 锚点参数 请求通过WebRequest.Create创建一个WebRequest&#xff1a; 1 var uri "https://id.test.xxx.com/api/v1/auth/sso/url?redirectUrlht…

免费的编程中文书籍索引(2018第三版)

之前我在 github 上整理了来一份&#xff1a;free-programming-books-zh_CN&#xff08;免费的计算机编程类中文书籍&#xff09;。 截至目前为止&#xff0c;已经在 GitHub 收获了 40000 多的 stars&#xff0c;有 90 多人发了 600 多个 Pull Requests 和 issues。 在收集的过…

分类与监督学习,朴素贝叶斯分类算法

1.理解分类与监督学习、聚类与无监督学习。 &#xff08;1&#xff09;简述分类与聚类的联系与区别。 分类就是按照某种标准给对象贴标签&#xff0c;再根据标签来区分归类。聚类是指事先没有“标签”而通过某种成团分析找出事物之间存在聚集性原因的过程。 区别是&#xff0c…

一张图搞定OAuth2.0

转发&#xff1a;https://www.cnblogs.com/flashsun/p/7424071.html 目录 1、引言2、OAuth2.0是什么3、OAuth2.0怎么写1、引言 本篇文章是介绍OAuth2.0中最经典最常用的一种授权模式&#xff1a;授权码模式 非常简单的一件事情&#xff0c;网上一堆神乎其神的讲解&#xff0c;让…

linux部署redis详细步骤

公司一直在使用redis集群&#xff0c;寻思着自己也部署一套练练手。 打开redis的官网下载页&#xff1a;https://redis.io/download 按照官网的步骤进行操作&#xff1a; 你会发现输入src/redis-cli命令之后&#xff0c;一直连接不上。 提示信息&#xff1a;Could not connect …

四则运算 结对项目

github 地址:https://github.com/wangshicheng0213/HomeWork02 一、基本要求 1) 实现一个带有用户界面的四则运算。 2) 生成的题目不能重复。 3) 支持负数&#xff0c;例如-1&#xff0c;-1/2&#xff0c;-3‘4/5等。 4) 题目的数量&#xff08;个人项目的要求&#xff09; 5) …

大型数据库

over&#xff08;order by salary&#xff09; 按照salary排序进行累计&#xff0c;order by是个默认的开窗函数 over&#xff08;partition by deptno&#xff09;按照部门分区 如何使用Oracle Round 函数 (四舍五入)描述 : 传回一个数值&#xff0c;该数值是按照指定的小数位…

thinkPHP 数据库操作和分页类

转载于:https://www.cnblogs.com/finddata/p/10013962.html

RHCE基础环境系统的搭建

RHCE基础环境系统的搭建 安装前提&#xff1a; 安装的时候对系统和硬件的要求&#xff1a; 红帽系统安装队系统的要求&#xff1a;Windows操作系统选择64位的内存至少6GCPU需要支持虚拟化技术在做红帽系统实验的时候&#xff0c;把360类似这样的杀毒或是管家软件退出了&#xf…

Chrome Extension Dark Theme

Chrome Extension & Dark Theme https://chrome.google.com/webstore/detail/eimadpbcbfnmbkopoojfekhnkhdbieeh https://github.com/darkreader/darkreader https://github.com/xyz-data/darkreader 转载于:https://www.cnblogs.com/xgqfrms/p/10017780.html

mybatis 控制台打印执行的SQL语句

1. Spring boot 集成 mybatis 【转载】SpringBoot中Mybatis打印sql 1.1 如果使用的是application.properties文件&#xff0c;加入如下配置&#xff1a; 1 logging.level.com.example.demo.daodebug 红色部分指的是mybatis对应的方法接口所在的包路径。 1.2 如果使用的是appli…

轻知 | 为什么全球只有13组根域名服务器?

欢迎大家前往腾讯云社区&#xff0c;获取更多腾讯海量技术实践干货哦~ 本文由9527发表 根域名服务器是域名解析系统&#xff08;DNS&#xff09;中最为顶级的域名服务器&#xff0c;它们负责管理顶级域的权威域名服务器地址。作为互联网基础设施的重要部分&#xff0c;所有域名…

check_http语法和选项

check_http H hostname (or) -I ip-address {optional options} 常用的几个例子 1. 检测http协议 $ check_http -H 192.168.1.50 HTTP OK HTTP/1.1 200 OK - 332 bytes in 0.004 seconds |time0.004144s;;;0.000000 size332B;;;0 2.检测https协议 $ check_http -H 192.168.1.50…

CentOs如何挂载硬盘

远程SSH登录上Centos服务器后&#xff0c;进行如下操作提醒&#xff1a;挂载操作会清空数据&#xff0c;请确认挂载盘无数据或者未使用第一步&#xff1a;列出所有磁盘 命令&#xff1a; ll /dev/disk/by-path 提示&#xff1a;如果无法确认数据盘设备名称&#xff0c;请使…

挂载

df -Th 查看磁盘挂载情况 ls /dev/sdx* fdisk -l 查看分区情况 fdisk /dev/sdb 分区mnpw uuid:设备的唯一号 blkidUUID"0a59654a-6f2c-4bc1-bbaf-df844e60e2e3" UUID"fe8c9dd4-571c-40a4-837a-a4ab6e4ae7e转载于:https://www.cnblogs.com/finddata/p/10041496.h…

AWS EC2实例Ubuntu系统设置root用户密码并使用root/ubuntu用户登录

参考链接&#xff1a;http://www.wangchao.info/1137.html 注意&#xff1a;链接中写的简化了&#xff0c;其中重启服务的命令似乎不太适用&#xff0c;可能是不通用&#xff0c;我下面描述的方式亲测可行&#xff0c;如有其他疑问请留言&#xff1b; https://blog.csdn.net/p…

坑题

题目描述 小姐姐想要配 n 把钥匙&#xff0c;她走过开锁铺问老板价钱&#xff0c;老板是这么说的&#xff1a; 小姐姐想知道完成配n把钥匙的任务最少需要花费多少钱 输入描述: 题目有多组测试数据。第一行输入一个整数T&#xff08;组数少于100组&#xff09;&#xff0c;表示测…