零晨三点半了,刚刚几个兄弟一起出去吼歌,才回来,这应该是我大学第二次去K歌,第一次是大一吧,之后每次兄弟喊我,我都不想去,因为我还是很害怕去KTV,或许是因为那里是我伤心的地方,也或许是因为我在那里失败过,所以内心一直都有点抵触,昨天是一室友的生日,也快过年,也是想和他们一起好好的玩一回,就放下一切去了,很久都没去吼歌了,嗓子现在都感觉哑哑的,今天一天仿佛没有干什么,有些不安,于是回来后把以前学习MVC时笔记写下来!
MVC设计模式是目前使用得比较多的一种设计模式,最早出现在Smalltalk中,后来广泛应用于Java Web 应用程序中。Model(模型)表示业务逻辑层,View(视图)代表表示层,Contraller(控制器)代表控制层!
在Java Web应用程序中,View部份一般用JSP和HTML构建。客户在View部份提交请求,在业务逻辑层处理后,把处理结果又返回给View部份显示出来。因此,View部份也是WEB应用程序的用户界面!
Controller部份一般由Servlet组成。当用户请求从View部分传过来时,Controller把该请求发给适当的业务逻辑组件处理,请求处理完成后,又返回给Controller.后者再把处理结果转发给适当的View组件显示。因此,Controller在视图层与业务逻辑层之间起到了桥梁作用,控制了它们两者之间的数据流向!
Model部分 包括业务逻辑层和数据库访问层。在JAVA WEB 应用程序中,业务逻辑层一般由JAVABEAN或EJB构建。EJB是J2EE的核心组件,可以构建分布式应用系统。与普通的JAVABEAN不同,它由二个接口和一个实现类组成,并且包含一些固有的用于控制容器生命周期的方法!
数据访问层也叫数据持久层,它主要负责与库打交道,用于从数据库中存取数据。在JAVA WEB应用中,我们常用JDBC API或Hibernate来构建数据持久层。例如,把与数据连接的代码以从数据库中存取数据的代码封装在不同的对象中,这样便于系统中其他业务逻辑组件调用它们。
这样,一个JAVA WEB应用程序划分为表示层,控制层,业务逻辑层和数据持久层,形成了一个多层系统。对于大型,复杂的WEB应用程序,这样的是十分必要的!
下面来构建一个简单的基于MVC模式的JAVA  WEB应用程序,我们按照MVC设计模式,用JSP,Servlet及Java Bean构建一个简单的登录系统。该系统要求当用户在登录页面上输入用户名和密码并提交后,系统将检查该用户中否已经注册,如果该用户已经注册,系统进入主页面,否则进入注册页面!
我们将 按以下步骤构建这个系统:
Step1:数据库的设计,使用MySQL作为数据库,构建数据表T_UserInfo;
Step2:构建视图组件:登录页面login.jsp,主页面main.jsp,以及注册页面register.jsp;
Step3:构建控制层组件,一个Servlet,;取名为LoginServlet.java;
Step4:构建业务逻辑层组件(Model组件),一个JavaBean,取名为LoginHandler.java;
Step5:构建数据访问层组件:珍上数据访问类,取名dbPool.java;
Step6:编译,打包程序;
Step7:部署该程序到Web服务器Tomcat中,然后运行!
该系统的工作流程图如下:

详细设计:
A:用户登录涉及数据库操作的用例!我们在MySQL中 建立一个T_UserInfo表,DDL语句如下:

create table T_UserInfo
(
    ID bigint primary key auto_increment,
    userName varchar(20),
    userPwd varchar(20)
)
--并添加一条测试数据用户名及密码均为fengyan
insert into T_UserInfo(userName,userPwd) values('fengyan','fengyan')

B:构建视图组件,由前面的分析可知本例有三个视图组件,分别是登录页面login.jsp,主页面main.jsp,以及注册页面register.jsp.它们之间的关系是当用户在登录页面login.jsp上填入用户名及密码并提交后,系统将 检测该用户是琐已经注册,如果已经注册则进入main.jsp,否则进入注册页面!
login.jsp代码如下:

<%@ page language="java" pageEncoding="GBK"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html:html lang="true">
  <head>
    <html:base />    
    <title>login.jsp</title>
  </head>  
  <body>
  <form action="servlet/LoginServlet" method="post" >     
      <table border="0">
        <tr>
          <td>Login:</td>
          <td><input type="text" name="userName" /></td>
        </tr>
        <tr>
          <td>Password:</td>
          <td><input type="password" name="userPwd" /></td>
        </tr>
        <tr>
          <td colspan="2" align="center"><input type="submit" value="login"></td>
        </tr>
      </table>
</form>
  </body>
</html:html>

当用户按下登录后就提交给叫做LoginServlet的Servlet,以做进一步处理!

为方便起见,主页面main.jsp的内容设计的很简单。当用户登录成功后,系统转入main.jsp告诉用户已经登录成功,现已进入主页面。main.jsp代码如下:

<%@ page language="java" contentType="text/html; charset=GBK"
    pageEncoding="GBK"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=GBK">
<title>Insert title here</title>
</head>
<body>
<%=session.getAttribute("userName") %>,你成功登录,现已进入主页面!
</body>
</html>

注册页面,register.jsp的内容也设计的很简单。当用户登录失败后,系统进入register.jsp,告诉用户登录失败,代码如下:

<%@ page language="java" contentType="text/html; charset=GBK"
    pageEncoding="GBK"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=GBK">
<title>Insert title here</title>
</head>
<body>
<%=session.getAttribute("userName") %>,你未能成功登录,现进入注册页面,请注册你的信息!
</body>
</html>

C:构建数据访问组件,先创建一个属性文件db.properties用于设置库连接信息代码如下:

DBDriver=com.mysql.jdbc.Driver
Connection=jdbc:mysql://localhost:3306/study
User=root
Password=root

本用例的数据访问组件是DbPool,代码如下:

package data;
/**
 * 数据访问组件
 * @author fengyan
 * @date 2007-01-06 03:25
 */
 */
import java.io.InputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.Properties;

public class DbPool {

    private static DbPool instance = null;
    private DbPool()
    {
        super();
    }
    //取得连接
    public static synchronized Connection getConnection()
    {
        if(instance == null)
            instance = new DbPool();
        return instance._getConnection();
    }
    private Connection _getConnection()
    {
        try
        {
            String dBDriver = null;
            String connectionUrl = null;
            String user = null;
            String password = null;
            
            Properties p = new Properties();
            InputStream inStream = getClass().getResourceAsStream("db.properties");
            p.load(inStream);
            
            dBDriver =p.getProperty("DBDriver",dBDriver);
            connectionUrl = p.getProperty("Connection",connectionUrl);
            user = p.getProperty("User","");//默认值为空
            password = p.getProperty("Password","");
            
            //加载驱动
            Class.forName(dBDriver).newInstance();
            return DriverManager.getConnection(connectionUrl+"?user="+user+"&password="+password);
            
        }catch(Exception e)
        {
            System.out.println(e);
            return null;
        }
    }
    
    //释放资源
    public static void DBClose(Connection con ,PreparedStatement ps,ResultSet rs)
    {
        try
        {
            if(rs !=  null)
                rs.close();
            if(ps != null)
                ps.close();
            if(con != null)
                con.close();
        }catch(Exception e)
        {
            System.out.println(e);
        }
    }
}

DbPool先从一个属性文件db.properties中获取数据库驱动程序名,URL,用户名和密码,然后利用这些信息连接数据库,取得连接!

D:构建模型组件,本用例的模型组件(或称为业务逻辑组件)是LoginHandler,代码如下:

package model;
/**
 * 模型组件
 * @author fengyan
 * date 2007-01-06 03:27
 */
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.ArrayList;

import data.DbPool;

public class LoginHandler {

    Connection con;
    PreparedStatement ps;
    ResultSet rs;
    
    //检查是否已经注册
    public boolean checkLogin(ArrayList arr)
    {
        //从数据访问组件中取得连接
        con = DbPool.getConnection();
        //得到Controller传入的用户输入的用户名及密码
        String userName = (String)arr.get(0);
        String userPwd = (String)arr.get(1);
        
        String strSql = "select * from T_UserInfo where userName=? and userPwd=?";
        try
        {
            ps = con.prepareStatement(strSql);
            ps.setString(1,userName);
            ps.setString(2, userPwd);
            rs = ps.executeQuery();
            if(rs.next())
            {    
                //释放资源
                DbPool.DBClose(con, ps, rs);            
                return true;
            }
            else
            {
                //释放资源
                DbPool.DBClose(con, ps, rs);
                return false;
            }            
        }catch(Exception e)
        {
            System.out.println(e);
            return false;
        }
        
    }
}

E:本用例的控制组件是一个Servlet,叫做LoginServlet,代码如下

package controller;
/**
 * 控制器
 * @author fengyan
 * date 2007-01-06 03:29
 */
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import model.LoginHandler;

public class LoginServlet extends HttpServlet {

    private static final String CONTENT_TYPE = "text/html;charset=GBK";

    public LoginServlet() {
        super();
    }

    public void destroy() {
        super.destroy(); // Just puts "destroy" string in log
        // Put your code here
    }

    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {

        doPost(request,response);
    }

    
    public void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {

        //从请求中取出用户名和密码
        String userName = request.getParameter("userName");
        String userPwd = request.getParameter("userPwd");
        //生成一个ArrayList对象,并把用户名和密码的值存入该对象中
        ArrayList arr = new ArrayList();
        arr.add(userName);
        arr.add(userPwd);
        
        //生成一个Session对象
        HttpSession session = request.getSession(true);
        session.removeAttribute("userName");
        session.setAttribute("userName", userName);
        
        //调用模型组件
        LoginHandler login = new LoginHandler();
        boolean flag = login.checkLogin(arr);
        
        //如果已注册
        if(flag)
        {
            response.sendRedirect("/MVC/main.jsp");
        }
        else
        {
            response.sendRedirect("/MVC/register.jsp");
        }
    }

    public void init() throws ServletException {
        // Put your code here
    }

}

该组件先处理Http POST请求,然后调用模型组件或业务逻辑组件LoginHandler检查该用户是否已注册如注册,则转入main.jsp,否则转入register.jsp,另外,Servlet都要在web.xml中声明,

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.4" 
    xmlns="http://java.sun.com/xml/ns/j2ee" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee 
    http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
 <welcome-file-list>
     <welcome-file>/login.jsp</welcome-file>
 </welcome-file-list>
  <servlet>
    <description>This is the description of my J2EE component</description>
    <display-name>This is the display name of my J2EE component</display-name>
    <servlet-name>LoginServlet</servlet-name>
    <servlet-class>controller.LoginServlet</servlet-class>
  </servlet>

  <servlet-mapping>
    <servlet-name>LoginServlet</servlet-name>
    <url-pattern>/servlet/LoginServlet</url-pattern>
  </servlet-mapping>
</web-app>

到此,整个系统完成设计!运行结果达到我们预期的的效果!

总结:上面结合使用JSP,Servlet和JavaBean构建了一个简单的基于MVC模式的登录系统。但我们看到在用这种方式构建的Java Web 应用系统中,控制器LonginController中包含重定向页面的名称,如下:

if(flag)
        {
            response.sendRedirect("/MVC/main.jsp");
        }
        else
        {
            response.sendRedirect("/MVC/register.jsp");
        }

这样会使系统的视图组件与控制层组件耦合很紧密,不便于系统的扩展和维护。对于大型Java Web系统,这样的紧密耦合性会合系统的扩展和维护变的十分困难。为了解决这些问题,一些优秀的MVC框架出现了,而Struts就是其中应用最普遍的一个。

构建一个简单的基于MVC模式的JavaWeb的更多相关文章

  1. struts1:(Struts重构)构建一个简单的基于MVC模式的JavaWeb

    在构建一个简单的基于MVC模式的JavaWeb 中,我们使用了JSP+Servlet+JavaBean构建了一个基于MVC模式的简单登录系统,但在其小结中已经指出,这种模式下的Controller 和 ...

  2. Spring学习(二)——使用Gradle构建一个简单的Spring MVC Web应用程序

    1.新建一个Gradle工程(Project) 在新建工程窗口的左侧中选择 [Gradle],右侧保持默认选择,点击next,模块命名为VelocityDemo. 2.在该工程下新建一个 module ...

  3. 并发编程概述 委托(delegate) 事件(event) .net core 2.0 event bus 一个简单的基于内存事件总线实现 .net core 基于NPOI 的excel导出类,支持自定义导出哪些字段 基于Ace Admin 的菜单栏实现 第五节:SignalR大杂烩(与MVC融合、全局的几个配置、跨域的应用、C/S程序充当Client和Server)

    并发编程概述   前言 说实话,在我软件开发的头两年几乎不考虑并发编程,请求与响应把业务逻辑尽快完成一个星期的任务能两天完成绝不拖三天(剩下时间各种浪),根本不会考虑性能问题(能接受范围内).但随着工 ...

  4. 通过Dapr实现一个简单的基于.net的微服务电商系统(十九)——分布式事务之Saga模式

    在之前的系列文章中聊过分布式事务的一种实现方案,即通过在集群中暴露actor服务来实现分布式事务的本地原子化.但是actor服务本身有其特殊性,场景上并不通用.所以今天来讲讲分布式事务实现方案之sag ...

  5. 通过Dapr实现一个简单的基于.net的微服务电商系统(十二)——istio+dapr构建多运行时服务网格

    多运行时是一个非常新的概念.在 2020 年,Bilgin Ibryam 提出了 Multi-Runtime(多运行时)的理念,对基于 Sidecar 模式的各种产品形态进行了实践总结和理论升华.那到 ...

  6. 通过Dapr实现一个简单的基于.net的微服务电商系统(十三)——istio+dapr构建多运行时服务网格之生产环境部署

    之前所有的演示都是在docker for windows上进行部署的,没有真正模拟生产环境,今天我们模拟真实环境在公有云上用linux操作如何实现istio+dapr+电商demo的部署. 目录:一. ...

  7. Django入门第一步:构建一个简单的Django项目

    Django入门第一步:构建一个简单的Django项目 1.简介 Django是一个功能完备的Python Web框架,可用于构建复杂的Web应用程序.在本文中,将通过示例跳入并学习Django.您将 ...

  8. 通过Dapr实现一个简单的基于.net的微服务电商系统(二)——通讯框架讲解

    首先感谢张队@geffzhang公众号转发了上一篇文章,希望广大.neter多多推广dapr,让云原生更快更好的在.net这片土地上落地生根. 目录:一.通过Dapr实现一个简单的基于.net的微服务 ...

  9. 通过Knockout.js + ASP.NET Web API构建一个简单的CRUD应用

    REFERENCE FROM : http://www.cnblogs.com/artech/archive/2012/07/04/Knockout-web-api.html 较之面向最终消费者的网站 ...

随机推荐

  1. getBlockTable delete pline

    AcDbBlockTable *pBlkTab; Acad::ErrorStatus es = acdbHostApplicationServices()->workingDatabase() ...

  2. nginx_gzip压缩提升网站的传输速度

    gzip on; gzip_min_length 1k; gzip_buffers 16k; #gzip_http_version 1.0; gzip_comp_level ; gzip_types ...

  3. Spring框架系列(六)--事务Transaction

    本文绝大部分内容为转载,原文地址:https://blog.csdn.net/trigl/article/details/50968079 除此之外,后面还有延伸内容 事务在企业日常开发中几乎是一定会 ...

  4. RabbitMQ系列(二)--基础组件

    声明:对于RabbitMQ的学习基于某课网相关视频和<RabbitMQ实战指南>一书,后续关于RabbitMQ的博客都是基于二者 一.什么是RabbitMQ RabbitMQ是开源代理和队 ...

  5. ThinkPHP---案例2--职员管理功能

    [一]准备工作 (1)创建菜单,修改跳转路径 <li> <a href="javascript:;" class="workerManage" ...

  6. Java之希尔排序

    希尔排序 前面已经知道了插入排序,明白插入排序的原理,不断比较来交换相邻的元素,这样的话效率不高,为此希尔排序,在插入排序上做出了改进,通过间隔增量来比较并交换元素,这样可以减少比较交换的次数. pa ...

  7. 安装charles

    简介: Charles主要的功能包括: 支持SSL代理.可以截取分析SSL的请求. 支持流量控制.可以模拟慢速网络以及等待时间(latency)较长的请求. 支持AJAX调试.可以自动将json或xm ...

  8. 第2章 取得大家的支持 录播感悟(意外的Sprint)

    关于<取得大家的支持>这个故事我看了三遍,做了计划,做了时间轴,因为之前有过第1章<知易行难>的沟通和磨合后,相信会顺利很多吧!可是却是意外不断的发生: 1.本人车钥匙掉停车场 ...

  9. 【Codeforces 1091D】New Year and the Permutation Concatenation

    [链接] 我是链接,点我呀:) [题意] 把1~n的n!种排列依次连接成一个长度为nn!的序列. 让你在这个序列当中找长度为n的连续段,使得连续段中的数字的和为n(n-1)/2 输出符合要求的连续段的 ...

  10. poj 3923 模拟

    /* 1.判断是否是一个完整边框 2.判断是否长度和宽度小于3 3.判断是否有内部覆盖的现象 */ #include<stdio.h> #define N 110 #define inf ...