4.Java Web开发模式(javaBean+servlet+MVC)

news2024/11/26 3:25:40

Java Web开发模式

一、Java Web开发模式

1.javaBean简介

JavaBeans是Java中一种特殊的类,可以将多个对象封装到一个对象(bean)中。特点是可序列化,提供无参构造器,提供getter方法和setter方法访问对象的属性。名称中的“Bean”是用于Java的可重用软件组件的惯用叫法。 --from 维基百科

JavaBean是一种可重复使用、且跨平台的软件组件。JavaBean可分为两种:

  • 一种是有用户界面(UI,User Interface)的JavaBean;
  • 另一种是没有用户界面,==主要负责处理事务(如数据运算,操纵数据库)的JavaBean
1)特点:
  1. JavaBean是一种Java类,而且是一种特殊的、可重用的类。
  2. JavaBean必须具有无参数的构造器,所有的属性都是private的,通过提供setter和getter方法来实现对成员属性的访问。
  3. Javabean 是为了和 jsp 页面传数据化简交互过程而产生的。

2.开发模式分类

  • 模式一(JSP+JavaBean): 简便、灵活,在小规模、业务逻辑简单的项目开发中有一定优势,开发效率高

    JSP页面通过JavaBean处理数据,响应请求并返回结果

  • 模式二(JSP+Servlet+JavaBean): 程序层次清晰、分工明确,可维护性、扩展性高,尤其在规模较大或是业务逻辑复杂的项目中倾向使用

1)模式一特点
  • 模式 一 体系结构用于开发简单的应用程序
  • 模式 一体系结构包括多个用户可与之交互的页面
  • 客户端能够直接访问到服务器上的JSP页面
  • 在采用模式 一 开发的Web 应用程序中混杂了大量的业务逻辑代码,HTML内容、Java代码交织在一起,使程序的维护性和扩展性较差
  • 在JSP页面中可以通过链接等方式直接转向其他页面。在业务逻辑较为复杂的项目中管理页面流程较为困难。
2)模式二特点

模式 二 体系结构结合使用 JSP 页面、Servlet和 JavaBean 来开发 Web 应用程序

二、MVC模式

1.简介

MVC是英文“Model-View-Controller”的缩写,最初是在Smalltalk-80中被用来构建用户界面的。其中M代表模型Model,V代表视图View,C代表控制器Controller。

通过模型视图控制器来

采用MVC模式的目的,就是为了增加代码的重用率,减少数据表达、数据描述和提高应用操作的偶合度。同时也使得软件的可维护性、可修复性、可扩展性、灵活性以及封装性大大提高。

2.MVC模式结构

MVC,把一个应用的输入、处理、输出流程按照Model、View、Controller的方式进行分离,这样一个应用将被分成三层:模型层、视图层、控制层。

  1. 输入>>模型层(Model)
  2. 处理>>视图层(View)
  3. 输出>>控制层(Controller)

controller负责处理客户端发送的请求,经过service层业务处理并间接调用mapper接口层的数据库操作,后将结果返回给视图层

客户端请求>>controller>>service>>mapper

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

1)Model层

分为: DAO层、service层

  1. DAO层:

    负责访问数据库进行数据的操作,取得结果集之后将结果集中的数据取出封装到VO类对象之后返回给service层

    负责数据库操作,取得结果返回给service层

    public interface HrMapper {
    
        int deleteByPrimaryKey(Long id);
    
        int insert(Hr record);
    
        int insertSelective(Hr record);
    
        Hr selectByPrimaryKey(Long id);
    
        int updateByPrimaryKeySelective(Hr record);
    
        int updateByPrimaryKey(Hr record);
    
        Hr login(@Param("username") String username, @Param("password") String password);
        List<Hr> queryAll();
        List<Hr> queryByUsername(String username);
    }
    
  2. service层:

    主要负责一些业务处理,比如多个操作需要放在一个事务中进行管理,事务回滚,一些复杂的逻辑业务处理就放到service层

    通过调用DAO层接口实现业务功能

    Service层的业务实现,具体要调用到已定义的DAO层的接口。封装Service层的业务逻辑有利于通用的业务逻辑的独立性和重复利用性。

    @Service("hrService")
    public class HrServiceImpl implements HrService {
        @Autowired
        private HrMapper hrMapper;
    
        @Override
        public Hr login(String username, String password) {
            return hrMapper.login(username, password);
        }
    
        @Override
        public List<Hr> queryAll() {
            return hrMapper.queryAll();
        }
    
        @Override
        public int insertSelective(Hr record) {
            return hrMapper.insertSelective(record);
        }
    
        @Override
        public int deleteByPrimaryKey(Long id) {
            return hrMapper.deleteByPrimaryKey(id);
        }
    
        @Override
        public Hr selectByPrimaryKey(Long id) {
            return hrMapper.selectByPrimaryKey(id);
        }
    
        @Override
        public int updateByPrimaryKeySelective(Hr record) {
            return hrMapper.updateByPrimaryKeySelective(record);
        }
    
        @Override
        public  List<Hr>queryByUsername(String username) {
            return hrMapper.queryByUsername(username);
        }
    }
    
2)View层

负责处理用户界面的显示细节,以及如何向用户展示业务处理的结果(页面效果)

<%@ page import="com.woniuxy.hrms.entity.Hr" %>
<%@ page import="java.util.List" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>


<%
    String path = request.getContextPath();
    String basePath = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort() + path + "/";
%>
<base href="<%=basePath%>"/>
<!DOCTYPE html>

<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<link rel="stylesheet" type="text/css" href="static/bootstrap/css/bootstrap.min.css">

<script type="text/javascript" src="static/bootstrap/js/bootstrap.min.js"></script>
<script type="text/javascript" src="static/bootstrap/js/jquery.min.js"></script>
<script type="text/javascript">
    function check(id) {
        var flag = confirm("确认要删除吗?");
        if (flag) {
            //删除确认,服务器请求跳转至delete方法处理数据库数据
            location.href = "hr/delete?id=" + id;
        }
    }
</script>

<body>
<div class="container" style="padding-top: 40px;">
    <div class="form-group">
        <div class="row">
            <div class="col-md-8">
                <form id="searchForm" action="hr/queryByUsername" method="post">
                    <input type="text" class="form-control" id="selectUserName" name="username"
                           placeholder="请输入用户名"/>
                    <button type="submit" class="btn btn-danger search" id="searchBtn">搜索</button>
                </form>
            </div>
            <div class="col-md-3">
                <a class="btn btn-round btn-square btn-default" href="manage/hr/add.jsp">添加<i
                        class="mdi mdi-eye"></i></a>

                <!--  <button class="btn btn-default add" data-toggle="modal" data-target="#addModel">增加</button>-->
            </div>
        </div>
    </div>
    <%
        List<Hr> list = (List<Hr>) request.getAttribute("list");
    %>
    <table class="table table-bordered text-center">
        <tr>
            <td>编号</td>
            <td>姓名</td>
            <td>用户名</td>
            <td>电话</td>
            <td>地址</td>
            <td>操作</td>
        </tr>
        <%--        迭代集合--%>
        <%
            for (Hr hr : list) {
        %>
        <tr>
            <td><%=hr.getId()%>
            </td>
            <td><%=hr.getRealName()%>
            </td>
            <td><%=hr.getUsername()%>
            </td>
            <td><%=hr.getPhone()%>
            </td>
            <td><%=hr.getAddress()%>
            </td>
            <td>
                <%--                点击编辑链接,传递当前对象id,并向服务器发送请求--%>
                <%-- href="hrms/queryById?id=<%=hr.getId()%        查询字符串以?字符开始       --%>
                <%--                <%=hr.getId()%>jsp脚本表达式    --%>
                <a class="btn btn-round btn-square btn-info" href="hr/queryById?id=<%=hr.getId()%>">编辑<i
                        class="mdi mdi-eye"></i></a>
                <a class="btn btn-round btn-square btn-warning" href="javascript:check(<%=hr.getId()%>)">删除<i
                        class="mdi mdi-eye"></i></a>
            </td>
        </tr>
        <%
            }
        %>
    </table>
</div>
</body>
</html>
3)Cotroller层

处理客户端请求

叫做控制层,主要的功能是处理用户发送的请求。

负责协调视图与模型,在两者之间处于桥梁和纽带的位置

public class BaseServlet extends HttpServlet {
    //HttpServlet生命周期: 初始化init(),服务运行service(),销毁destroy()
    //1.init()仅加载一次
    //2.service()随时响应客户端请求,每次获取请求对象调用此方法
    //3.destroy()仅调用一次, 释放servlet所占用的资源。如关闭文件输入输出流,关闭与数据库的连接。
    //多次调用,每次服务器获取请求对象调用service方法,随时响应客户端请求
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //获取请求路径
        String requestURI = req.getRequestURI();
        //检索请求路径最后的方法名
        String methodName = requestURI.substring(requestURI.lastIndexOf("/") + 1);
        Method declaredMethod;
        try {
            //动态调用对象方法
            declaredMethod = this.getClass().getDeclaredMethod(methodName, HttpServletRequest.class, HttpServletResponse.class);
            declaredMethod.invoke(this, req, resp);
        } catch (NoSuchMethodException | InvocationTargetException | IllegalAccessException e) {
            throw new RuntimeException(e);
        }
    }
}
@WebServlet(value = "/hr/*", loadOnStartup = 1)
public class HrServlet extends BaseServlet {

    HrService hrService;

    @Override
    public void init(ServletConfig config) throws ServletException {
        ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring-config.xml");
        //config.getServletContext()创建ServletContext对象,用来存储applicationContext对象,整个Web应用范围内访问它
        config.getServletContext().setAttribute("applicationContext", applicationContext);
        hrService = applicationContext.getBean("hrService", HrService.class);
    }

    protected void queryByUsername(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String username = req.getParameter("username");
        List<Hr> list = hrService.queryByUsername(username);
        list.forEach(System.out::println);
        req.setAttribute("list", list);
        req.getRequestDispatcher("../manage/hr/show.jsp").forward(req, resp);
    }

    protected void queryAll(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        List<Hr> list = hrService.queryAll();
        req.setAttribute("list", list);
        req.getRequestDispatcher("../manage/hr/show.jsp").forward(req, resp);
    }

    protected void add(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//        req.setCharacterEncoding("utf-8");
        Hr hr = new Hr();
        hr.setRealName(req.getParameter("realName"));
        hr.setUsername(req.getParameter("username"));
        hr.setAddress(req.getParameter("address"));
        hr.setPhone(req.getParameter("phone"));
        System.out.println(hr);
        int i = hrService.insertSelective(hr);
        //数据库添加数据,并重新调用queryAll走页面展示流程
        queryAll(req, resp);
    }

    protected void queryById(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String id = req.getParameter("id");
        Hr hr = hrService.selectByPrimaryKey(Long.parseLong(id));
        req.setAttribute("hr", hr);
//        跳转页面,带着对象forward(),地址栏不变
        req.getRequestDispatcher("../manage/hr/update.jsp").forward(req, resp);
//        单纯跳转页面,并不能携带对象,地址栏更新
//        resp.sendRedirect("/hr/update.jsp");
    }

    protected void update(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//        req.setCharacterEncoding("utf-8");
        Hr hr = new Hr();
        //更新必须有id,负责更新所有内容,依据id更新
        //  where dept_id = #{deptId,jdbcType=INTEGER}
        //获取页面update.jsp请求对象传递的参数
        hr.setId(Integer.parseInt(req.getParameter("id")));
        hr.setRealName(req.getParameter("realName"));
        hr.setUsername(req.getParameter("username"));
        hr.setAddress(req.getParameter("address"));
        hr.setPhone(req.getParameter("phone"));
        int update = hrService.updateByPrimaryKeySelective(hr);
        //更新完显示全部数据(查询全部数据反馈给show.jsp)
        queryAll(req, resp);
    }

    protected void delete(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String id = req.getParameter("id");
        hrService.deleteByPrimaryKey(Long.parseLong(id));
        queryAll(req, resp);
    }

    protected void login(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //负责处理login.jsp提交
        //获取提交对象的username和password
        String username = req.getParameter("username");
        String password = req.getParameter("password");
        Hr hr = hrService.login(username, password);
        //
        HttpSession session = req.getSession();
        session.setAttribute("hr", hr);
        if (hr != null) {
            //本地存储,在浏览器存储数据
            Cookie[] cookies = req.getCookies();
            boolean flag = false;
            for (Cookie cookie : cookies) {
                String name = cookie.getName();
                if (name.equals("username")) {
                    flag = true;
                }
            }
            if (!flag) {
                Cookie username1 = new Cookie("username", username);
                Cookie password1 = new Cookie("password", password);
                //设置cookie存储路径
                username1.setPath("/hrms");
                password1.setPath("/hrms");
                username1.setMaxAge(60 * 60 * 24);
                password1.setMaxAge(60 * 60 * 24);
                resp.addCookie(username1);
                resp.addCookie(password1);
            }
            //路径可以: ../或/hrms根路径下的页面
            resp.sendRedirect("/hrms/admin.jsp");
        } else {
            resp.sendRedirect("../login.jsp");
        }
    }
}

3.MVC的优点:

  • 1、耦合性低

    视图层和业务层分离,这样就允许更改视图层代码而不用重新编译模型和控制器代码,同样,一个应用的业务流程或者业务规则的改变只需要改动MVC的模型层即可。因为模型与控制器和视图相分离,所以很容易改变应用程序的数据层和业务规则。

  • 2、重用性高

    MVC模式允许使用各种不同样式的视图来访问同一个服务器端的代码,因为多个视图能共享一个模型,它包括任何WEB(HTTP)浏览器或者无线浏览器(wap),比如,用户可以通过电脑也可通过手机来订购某样产品,虽然订购的方式不一样,但处理订购产品的方式是一样的。由于模型返回的数据没有进行格式化,所以同样的构件能被不同的界面使用。

  • 3、部署快,生命周期成本低

    MVC使开发和维护用户接口的技术含量降低。使用MVC模式使开发时间得到相当大的缩减,它使程序员(Java开发人员)集中精力于业务逻辑,界面程序员(HTML和JSP开发人员)集中精力于表现形式上。

  • 4、可维护性高

    分离视图层和业务逻辑层也使得WEB应用更易于维护和修改。

4.MVC框架

  1. Struts2框架:Struts2是基于MVC的轻量级的web应用框架

规则。

  • 2、重用性高

    MVC模式允许使用各种不同样式的视图来访问同一个服务器端的代码,因为多个视图能共享一个模型,它包括任何WEB(HTTP)浏览器或者无线浏览器(wap),比如,用户可以通过电脑也可通过手机来订购某样产品,虽然订购的方式不一样,但处理订购产品的方式是一样的。由于模型返回的数据没有进行格式化,所以同样的构件能被不同的界面使用。

  • 3、部署快,生命周期成本低

    MVC使开发和维护用户接口的技术含量降低。使用MVC模式使开发时间得到相当大的缩减,它使程序员(Java开发人员)集中精力于业务逻辑,界面程序员(HTML和JSP开发人员)集中精力于表现形式上。

  • 4、可维护性高

    分离视图层和业务逻辑层也使得WEB应用更易于维护和修改。

4.MVC框架

  1. Struts2框架:Struts2是基于MVC的轻量级的web应用框架

  2. SpringMVC:Spring家族产品,我们后期重点使用的框架

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

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

相关文章

顺序 IO 和 随机IO

顺序 IO 和 随机IO 顺序IO 和 随机IO 是计算机存储系统领域中的概念&#xff0c;主要涉及数据的读取和写入方式。这些术语通常在讨论硬盘驱动器&#xff08;HDDs&#xff09;、固态驱动器&#xff08;SSD&#xff09;以及其他存储设备的性能时使用。 顺序IO&#xff08;Sequen…

TeamViewer关闭访问密码或固定一组密码不变

TeamViewer的新UI界面变化较大&#xff0c;网上的一些信息已经不再有效&#xff0c;更新后的访问密码在如下图所示&#xff1a; 演示的版本为7.21.4—— 设置每次你的设备访问的密码

Hi6274 反激式20瓦电源芯片

HI6274为高性能多模式 PWM 反激式20瓦电源芯片。HI6274较少的外围元器件、较低的系统成本可设计出高性能的"无Y"开关电源。HI6274提供了极为全面和性能优异的智能化保护功能&#xff0c;包括逐周期过流保护、过载保护、软启动、芯片过温保护、可编程输出过压保护功能…

Kettle 登录示例 POST请求

登录接口是post请求&#xff0c;组装Body为json字符串 var body "{\"username\":\""username"\",\"password\": \""password"\",\"code\":\""verification"\",\"uuid\…

【算法/训练】:前缀和差分

&#x1f680; 前言&#xff1a; 前面我们已经通过 【算法/学习】前缀和&&差分-CSDN博客 学习了前缀和&&差分的效相关知识&#xff0c;现在我们开始进行相关题目的练习吧 1. 校门外的树 思路&#xff1a;给[0, n]的数组都标记为1&#xff0c;然后输出m行范围…

初学Mybatis之配置解析

MyBatis 中文网配置教程 mybatis-config.xml 环境配置&#xff08;environments&#xff09; 尽管可以配置多个环境&#xff0c;但每个 SqlSessionFactory 实例只能选择一种环境 可以有多个 enviroment&#xff0c;但是 enviroments default&#xff08;默认&#xff09;只…

Linux:Linux发展史

大家好&#xff01;此篇文章并非技术博文&#xff0c;而是简单了解Linux的时代背景和发展史&#xff0c;只有知其所以然才能让我们更好地让走进Liunx的世界&#xff01; 一、计算机的发展历史背景 首先我们要知道&#xff0c;早期大多数科技的进步都是以国家的对抗为历史背景的…

【优秀设计案例】基于K-Means聚类算法的球员数据聚类分析设计与实现

背景及意义 随着NBA比赛的日益竞争激烈&#xff0c;球队需要更加深入地了解球员的能力和特征&#xff0c;以制定更有效的战术和球队管理策略。而NBA球员的统计数据包含了大量有价值的信息&#xff0c;通过对这些数据进行聚类分析&#xff0c;可以揭示出球员之间的相似性和差异…

Java生成四位纯数字并且确保唯一性

背景&#xff1a; 给了我一个需求&#xff0c;由于某些问题原因&#xff0c;需要给属性和数据添加一个code字段&#xff0c;这是给我发的消息 这两个要求其实是同一个需求&#xff0c;就是在创建对象的时候塞入一个unique的code嘛&#xff0c;听起来很简单吧&#xff0c;但是实…

WPF串口通讯程序

目录 一 设计原型 二 后台源码 一 设计原型 二 后台源码 using HardwareCommunications; using System.IO.Ports; using System.Windows;namespace PortTest {/// <summary>/// Interaction logic for MainWindow.xaml/// </summary>public partial class MainW…

二叉树精选面试题

&#x1f48e; 欢迎大家互三&#xff1a;2的n次方_ 1. 相同的树 100. 相同的树 同时遍历两棵树 判断结构相同&#xff1a;也就是在遍历的过程中&#xff0c;如果有一个节点为null&#xff0c;另一棵树的节点不为null&#xff0c;那么结构就不相同 判断值相同&#xff1a;只需…

【刷题汇总 -- 压缩字符串(一)、chika和蜜柑、 01背包】

C日常刷题积累 今日刷题汇总 - day0181、压缩字符串(一)1.1、题目1.2、思路1.3、程序实现 2、chika和蜜柑2.1、题目2.2、思路2.3、程序实现 3、 01背包3.1、题目3.2、思路3.3、程序实现 -- dp 4、题目链接 今日刷题汇总 - day018 1、压缩字符串(一) 1.1、题目 1.2、思路 读完…

宠物空气净化器哪款除臭效果好?质量好的养狗空气净化器排名

作为一个宠物家电小博主&#xff0c;炎炎夏日&#xff0c;家中的宠物给你带来的不仅仅是温暖的陪伴&#xff0c;还有那挥之不去的宠物异味。普通空气净化器虽然能够应对一般的空气净化需求&#xff0c;但对于养猫家庭特有的挑战&#xff0c;如宠物毛发、皮屑和异味等&#xff0…

模版初阶与STL

1.泛型编程 void Swap(int& left, int& right) {int temp left;left right;right temp; } void Swap(double& left, double& right) {double temp left;left right;right temp; } void Swap(char& left, char& right) {char temp left;left r…

Linux系统安装的详细步骤详解

在VM虚拟机上安装Linux系统全过程&#xff0c;闭眼跟着走就行&#xff01;&#xff01;&#xff01; 1、准备好VMware Worestation虚拟机软件和Linux系统的映像文件 2、点击创建新的虚拟机 3、在新建虚拟机向导中&#xff0c;选择典型安装模式。典型安装模式可以通过几个简单的…

简析漏洞生命周期管理的价值与关键要求

开展全面且持续的漏洞管理工作&#xff0c;对于企业组织改善数字化应用安全状况&#xff0c;降低潜在风险&#xff0c;并保持数字资产的完整性和可信度至关重要。做好漏洞管理并不容易&#xff0c;组织不仅需要拥有健全的漏洞管理策略&#xff0c;同时还要辅以明确定义的漏洞管…

VulnHub:tenderfoot1

靶机下载地址 信息收集 主机发现 扫描攻击机同网段存活主机。nmap 192.168.31.0/24 -Pn -T4 目标主机ip&#xff1a;192.168.31.199。 端口扫描 nmap 192.168.31.199 -A -p- -T4 开放了22,80端口&#xff0c;即ssh和http服务。 目录扫描 访问http服务&#xff0c;是apac…

IPython魔法命令的深入应用

目录 IPython魔法命令的深入应用 一、魔法命令基础 1. 魔法命令的分类 2. 基本使用 二、高级应用技巧 1. 数据交互与处理 2. 交互式编程与调试 三、魔法命令的进阶操作 1. 自定义魔法命令 2. 利用魔法命令优化工作流程 四、总结与展望 IPython魔法命令的深入应用 IP…

指针!!C语言(第二篇)

目录 一. 数组名的理解 二. 一维数组传参的本质 三. 冒泡排序法 四. 二级指针与指针数组 五. 字符指针变量与数组指针 一. 数组名的理解 在我们对指针有了初步的理解之外&#xff0c;今天我们来掌握一些新的知识就是数组与指针&#xff0c;第一个对数组名的了解&#xff…

WebGIS的Web服务概述

WebGIS是互联网技术应用于GIS开发的产物&#xff0c;是现代GIS技术的重要组成部分&#xff0c;其中的Web服务是现代WebGIS的核心技术和重要标志&#xff0c;它集GIS、程序组件和互联网的优点于一身&#xff0c;深刻改变了GIS开发和应用的方式&#xff0c;绕过了本地数据转换和本…