MVC模式实现简单的访问数据库(JSP+Servlet+JavaBean)

2023-11-10

MVC模式:

        MVC模式一般由JSP+Servlet+JavaBean组成。其中JSP用于表示数据;Servlet用于处理客户请求,充当控制器的角色;JavaBean用于数据的存取。其运行机制如下:

        下面用一个简单的留言板例子来实现一下MVC模型,功能是登录账号之后可以看到所有留言的内容。那么这个模型的业务流程大概就是:

        首先在login页面输入账号和密码,再将输入的送到loginServlet中,loginServlet先调用Users类来验证账号和密码是否正确,若不正确则返回login重新输入;若正确则调用Message类来取出数据库中的所有留言信息,最后将这些留言信息送到MessageList页面显示出来。代码如下:

 

        1、登录页面,账号与密码信息已经存到了数据库中,这里就不细说了。用户填好账号和密码之后将调用Servlet来处理请求。调用Servlet方法就是将表单的action设为Servlet的名字。本页面还加入了检查输入的函数,检查完之后再提交表单。

<%@ page language="java" contentType="text/html; charset=utf-8"
	pageEncoding="UTF-8" import="java.util.*"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>用户登录</title>
</head>
<script type="text/javaScript">
	function checkLogin() {
		var username = document.getElementById("username_id");
		if (username.value == "") {
			alert("请输入用户名!");
			username.focus();
			return;
		}
		var password = document.getElementById("password_id");
		if (password.value == "") {
			alert("密码不能为空");
			password.focus();
			return;
		}
		login_form.submit();
	}
</script>
<body>
	<center>
		<form name="login_form" action="loginservlet" method="post">
			<table border=1>
				<tr>
					<td align="center" colspan=2 style="font-size: 30px">用户登录</td>
				</tr>
				<tr>
					<td>用户名:</td>
					<td><input type="text" id="username_id" name="username"
						size="25" /></td>
				</tr>
				<tr>
					<td>密 码:</td>
					<td><input type="password" id="password_id" name="password"
						size="25"></td>
				</tr>
			</table>
			<input type="button" value="登录" style="height: 30px; width: 80px"
				onclick="checkLogin()">
		</form>
	</center>
</body>
</html>

        2、loginServlet,这个Servlet首先new一个Users对象,将该对象的属性值设成用户输入的账号和密码,再调用他的check方法来验证账号和密码是否正确。若不正确则返回重新登录;若正确则调用Message类来访问数据库,将所有留言信息存到一个List中,然后通过request的setAttribute方法将该List传递给MessageList.jsp页面上来显示。

PS:为了防止中文账号传过来之后乱码,加入request.setCharacterEncoding("utf-8");这一句,使JSP和此Servlet的字符集相同。否则程序会用乱码去和数据库中的账号做比较,结果肯定出错。

package com.servlet;

import java.io.IOException;
import java.util.*;

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 javax.swing.JOptionPane;

import com.bean.Message;
import com.bean.Users;

/**
 * Servlet implementation class loginservlet
 */
@WebServlet("/loginservlet")
public class loginservlet extends HttpServlet {
	private static final long serialVersionUID = 1L;

	/**
	 * @see HttpServlet#HttpServlet()
	 */
	public loginservlet() {
		super();
		// TODO Auto-generated constructor stub
	}

	/**
	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse
	 *      response)
	 */
	protected void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		// TODO Auto-generated method stub
		request.setCharacterEncoding("utf-8");
		Users user = new Users();
		String name = request.getParameter("username");
		String password = request.getParameter("password");
		user.setUsername(name);
		user.setPassword(password);
		if (!user.check()) {
			JOptionPane.showMessageDialog(null, "用户名或密码错误! ", "登录失败 ", JOptionPane.ERROR_MESSAGE);
			request.getRequestDispatcher("login.jsp").forward(request, response);
		} else {
			Message m = new Message();
			List<Message> list = m.searchall();
			request.setAttribute("list", list);
			request.getRequestDispatcher("MessageList.jsp").forward(request, response);
		}
	}

	/**
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse
	 *      response)
	 */
	protected void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		// TODO Auto-generated method stub
		doGet(request, response);
	}

}

        3、Users和Message类,这是MVC中的JavaBean,用来实现数据库的数据存取。这两个类中我都调用了DButil这个类,这是个工具类,用来连接数据库,下面再说。

        Users类,实现的功能是检查用户登录时输入的账号和密码是否正确,用户在输入账号和密码之后会定义一个Users对象,通过调用他的check()方法,来将输入的信息与数据库中的信息作对比。

        验证账号密码的时候,我是先从数据库中,将用户输入的用户名所在的这一行取出来。若数据库中不存在输入的用户名,即结果集的行数为0,则登录失败(求结果集的行数之前必须先调用last方法);若有数据,但是数据库中存着的密码与输入的不符,则登录失败(java中判断两个字符串相等不能用==,要调用其中一个字符串的equal方法,getString用于取出该列的值)。

package com.bean;

import com.util.DButil;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

import javax.swing.JOptionPane;

@SuppressWarnings("unused")
public class Users {
	private String Username;
	private String password;

	public String getUsername() {
		return Username;
	}

	public void setUsername(String username) {
		this.Username = username;
	}

	public String getPassword() {
		return password;
	}

	public void setPassword(String password) {
		this.password = password;
	}

	public boolean check() {
		Connection conn = DButil.open();
		String sql = "select * from user where name=" + "'" + this.Username + "'";
		try {
			PreparedStatement ps = (PreparedStatement) conn.prepareStatement(sql);
			ResultSet rs = ps.executeQuery(sql);
			rs.last();
			int row = rs.getRow();
			if (row == 0) {
				JOptionPane.showMessageDialog(null, "无数据", "登录失败 ", JOptionPane.ERROR_MESSAGE);
				return false;
			}
			if (!rs.getString(2).equals(this.password)) {
				JOptionPane.showMessageDialog(null, "密码错误", "登录失败 ", JOptionPane.ERROR_MESSAGE);
				return false;
			}
		} catch (SQLException e) {
			// TODO 自动生成的 catch 块
			e.printStackTrace();
			return false;
		}
		return true;
	}

}

        Message类,实现的是将所有留言信息从数据库中读出来,返回一个List。

package com.bean;

import java.util.*;

import javax.swing.JOptionPane;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

import com.util.DButil;

public class Message {
	String title;
	String context;
	String author;

	public String getTitle() {
		return title;
	}

	public void setTitle(String title) {
		this.title = title;
	}

	public String getContext() {
		return context;
	}

	public void setContext(String context) {
		this.context = context;
	}

	public String getAuthor() {
		return author;
	}

	public void setAuthor(String author) {
		this.author = author;
	}

	public List<Message> searchall() {
		String sql = "select * from message";
		Connection conn = DButil.open();
		try {
			PreparedStatement ps = (PreparedStatement) conn.prepareStatement(sql);
			ResultSet rs = ps.executeQuery(sql);
			List<Message> list = new ArrayList<Message>();
			while (rs.next()) {
				Message m = new Message();
				m.setTitle(rs.getString(1));
				m.setContext(rs.getString(2));
				m.setAuthor(rs.getString(3));
				list.add(m);
			}
			return list;
		} catch (SQLException e) {
			// TODO 自动生成的 catch 块
			e.printStackTrace();
		}
		return null;
	}
}

        4、MessageList.jsp,此页面用于显示从数据库中取出的所有留言信息。刚才在loginServlet中已经将结果集list传递了过来,那么我们这里就直接调用getAttribute方法来接收,再遍历输出即可。输出方法就是在java代码中插入HTML标签,一边遍历一边输出。代码如下:

<%@ page language="java" contentType="text/html; charset=UTF-8"
	pageEncoding="UTF-8" import="java.util.*" import="com.bean.Message"
	import="javax.swing.*"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>留言列表</title>
</head>
<body>
	<table align="center" border="1" width="50%" cellpadding="8">
		<tr>
			<th align="center" colspan=6>留言列表</th>
		</tr>
		<tr>
			<th align="center" width=100>序号</th>
			<th align="center" width=500>标题</th>
			<th align="center" width=100>作者</th>
			<th align="center" width=100>操作</th>
		</tr>
		<%
			List<Message> list = (List<Message>) request.getAttribute("list");
			int i = 1;
			for (Message m : list) {
		%>
		<tr align="center">
			<td><%=i++%></td>
			<td><%=m.getContext()%></td>
			<td><%=m.getAuthor()%></td>
			<td>
				<form action="" method="post">
					<input type="button" value="查看" onclick="" />
				</form>
			</td>
		</tr>
		<%
			}
		%>
	</table>
</body>
</html>

        5、BDutil类,这是个工具类,只封装了一个方法,就是获取一个与数据库的连接Connection。代码如下:

package com.util;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;

@SuppressWarnings("unused")
public class DButil {
	private static String url = "jdbc:mysql://127.0.0.1:3306/实验?useUnicode=true&characterEncoding=utf-8&serverTimezone=GMT%2B8&useSSL=false";// 连接数据库的驱动
	private static String driver = "com.mysql.cj.jdbc.Driver";
	private static String username = "root";
	private static String password = "123456";

	public static Connection open() {
		try {
			Class.forName(driver);
			return (Connection) DriverManager.getConnection(url, username, password);
		} catch (ClassNotFoundException | SQLException e) {
			// TODO 自动生成的 catch 块
			System.out.print("数据库打开失败!");
			e.printStackTrace();
		}
		return null;
	}

	public static void close(Connection conn) {
		try {
			conn.close();
		} catch (SQLException e) {
			// TODO 自动生成的 catch 块
			e.printStackTrace();
		}
	}
}

        实现效果大致如下,(一些前段的代码为了简练并没有贴上来,但实现功能的代码是齐全的):

1、用户登录

2、瞎输入用户名和密码的话会显示登录错误

3、登录成功后显示留言列表(第一条就是数据库中的数据,是我随便插入的):

 

209年6月22日更新:

        前几天学习了DAO模式,然后才发现我的MVC其实不是很正宗的MVC,正宗的MVC是将与数据库做数据交换的函数放到了Servlet中,而我是放进了java bean中。然后我就更加感受到了MVC模式的弊端,Servlet本来是实现业务控制的地方,但是加入了与数据库的访问操作,这两个模块的耦合度太高了,不利于分工。

        可能当时写这个留言板的时候已经感觉到这个问题了,所以我很自觉地把对数据库的访问放在了java bean中,但是今天回过头发现我这既不是DAO也不是MVC。我又写了一篇将MVC扩展为DAO的博客,可以很好地对数据层和控制层降耦,并将留言板的最终版本放到了GitHub上。

链接:https://blog.csdn.net/Q_M_X_D_D_/article/details/93315608

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

MVC模式实现简单的访问数据库(JSP+Servlet+JavaBean) 的相关文章

  • 使用docker部署fastdfs集群版

    一 前言 本文档说明在node01和node02两台主机上安装部署FastDFS双节点 node01 ip 198 168 1 121 安装tracker1 storage1 node02 ip 198 168 1 122 安装tracke
  • 2020年,给你7个程序员接私活必备网站!

    2020互联网圈不好混 不是每个公司都能像蚂蚁金服一样这么大气 不少公司今年因为疫情已经开始裁员 不要抱怨 加油干就完事了 今天给大家推荐几个赚钱养家的好渠道 一起来看看吧 1 程序员客栈 程序员的经纪人 https www proginn
  • Python人员信息管理系统(简直期末人福音)

    1 涉及模块 datetime os random sys PyQt5 2 运行效果 支持功能 添加信息 修改信息 删除信息 查询信息 文件存储数据 每次运行都会加载显示之前的信息 3 部分源码 创建字体对象 用来对要显示的文字进行设定fo
  • IIS 网站安装SSL证书

    步骤一 申请SSL证书 申请免费证书步骤 阿里云申请免费证书步骤 申请完成后 等待证书签发 签发后下载到本地 解压缩后会得到如下两个文件 一个证书文件 一个密码文件 步骤二 将文件复制到服务器上 双击证书文件安装 安装选计算机 安装过程中要
  • Graph Stacked Hourglass Networks for 3D Human Pose Estimation

    方法重复使用编码器 解码器 图形结构特征在三种不同尺度的骨骼中表示 获取局部和全局特征 使用不同深度中间特征的多层次特征学习方法 目前的基于GCN的方法有一些局限性 图卷积利用所有关节点信息 可以看做是所有特征仅在 一个尺度 上处理 很难获
  • 安全类常用网站

    目录 Burp Suite Burpsuite学院 安全测试常用的几个工具 Burp Suite Burp Suite Application Security Testing Software PortSwiggerGet Burp Su
  • UniswapV2核心合约学习(3)——UniswapV2Pair.sol

    记得朋友圈看到过一句话 如果Defi是以太坊的皇冠 那么Uniswap就是这顶皇冠中的明珠 Uniswap目前已经是V2版本 相对V1 它的功能更加全面优化 然而其合约源码却并不复杂 本文为个人学习UniswapV2核心合约源码的系列文章的
  • k8s指南-DNS与服务发现

    目录 1 k8s指南 概述 2 k8s指南 架构 3 k8s指南 工作负载 1 4 k8s指南 工作负载 2 5 k8s指南 工作负载 3 6 k8s指南 工作负载 4 7 k8s指南 Service 8 k8s指南 Ingress 9 k
  • Apache APISIX信息泄露漏洞(CVE-2022-29266)

    目录 漏洞概述 漏洞复现 环境搭建 攻击复现 漏洞概述 在2 13 1版本之前的APache APISIX中 攻击者可以通过向受 jwt auth 插件保护的路由发送不正确的 JSON Web 令牌来通过错误消息响应获取插件配置的机密 依赖
  • 百度、德勤管理咨询联合发布《知识中台白皮书》,聚焦企业知识赋能高效创新...

    近日 十九届五中全会审议通过的十四五规划36次提及科技 其中人工智能成为最高优先级 引领新一轮科技革命和产业革命的战略性技术 在十四五规划中发挥着关键作用 百度作为国内人工智能的头雁企业 致力于发挥 AI 技术领域多年积累的优势 以云计算为
  • 3. 内存管理(Memory Management)

    计算机有几兆字节的非常快速 昂贵 且易变的 cache memory 几千兆字节的中速 中等价格 易变的 main memory 以及几千兆字节缓慢 便宜 非易变的磁盘 固态硬盘存储 不涉及可移除的存储 例如 DVDs 和 USB 存储器
  • 再见以前说再见 数据结构复习

    数据结构 实验14 15 基本排序算法实现 数据结构 实验12 13 基本查找算法实现 数据结构 实验10 11 图及其应用 数据结构 实验7 9 二叉树的基本操作和应用 数据结构 实验六 模式匹配 数据结构 实验五 队列的算法实现及应用
  • 配置setting.json解决vscode和vim按键冲突

    vim 对于需要经常使用的vscode中的复制 粘贴 剪切 全选 查找和新建等 在vim正常模式下是不可用的 不过可以在配置文件中取消vim handleKeys键位映射 即保留这些原始按键功能 对于上述可能存在和正常按键冲突 可以通过设置
  • LeetCode 1、两数之和(C)

    作者只是一个小白 最近希望能提升自己的代码水平 所以开始刷leetcode 写博客是为了整理自己的学习内容 难免会出错 如果有大大发现 非常欢迎指正哦 目录 题目 1 两数之和 题解 方法一 双重for循环 暴力枚举 1 自己的代码 2 代
  • 数据库键(key)、主键(primaryKey)、索引(index)、唯一索引(uniqueIndex)区别

    1 键 key 数据库的物理结构 一是约束 偏重于约束和规范数据库的结构完整性 二是索引 辅助查询用的 包括 primary key unique key foreign key 主键 唯一键 外键 1 primary key 主键 一个表
  • IKE与IPSec详解

    一 IKE简介 安全联盟SA 定义 安全联盟是要建立IPSec 隧道的通信双方对隧道参数的约定 包括隧道两端的IP地址 隧道采用的验证方式 验证算法 验证密钥 加密算法 共享密钥以及生命周期等一系列参数 SA由三元组来唯一标识 这个三元组包
  • Could not find method jackOptions() for arguments

    去掉 jackOptions enabled true 就好了
  • 【软件工程基础复习整理】第四章需求分析(5)UML建模语言

    结构化方法 数据流建模 IDEF0功能建模 IDEF1X数据建模 数据和功能分开 面向对象方法 封装起来 UML建模语言 面向对象方法的统一建模语言 UML建模语言 结构化方法70年代高潮 面向对象方法80年代末90年代初高潮 多种面向对象

随机推荐