4.MVC模式

本章目标:

  1. 搭建项目
  2. 实现CRUD操作

本章内容:

一、Java Web开发模式

1、JavaBean的概念(了解)

在jsp页面中,包含html代码、css代码、java代码、以及业务逻辑处理代码等。javabean的作用就是将html代码与java代码分离,将java代码单独封装成一个处理某种业务逻辑的类,然后在jsp中调用该类,实现降低耦合多和简化页面的作用。

用途:实现一些业务逻辑或封装一些业务对象。例如:字符串处理、数据库操作等。

1.1、简介

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

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

  • 一种是有用户界面(UI,User Interface)的JavaBean;
  • 另一种是没有用户界面,主要负责处理事务(如数据运算,操纵数据库)的JavaBean

JSP通常访问的是后一种JavaBean。

1.2、特点

  1. JavaBean是一种Java类,而且是一种特殊的、可重用的类。
  2. JavaBean必须具有无参数的构造器,所有的属性都是private的,通过提供setter和getter方法来实现对成员属性的访问。
  3. Javabean 是为了和 jsp 页面传数据化简交互过程而产生的。

1.3、示例

 public class User {
     private Integer id;
     private String name;
 
  //无参构造器
     public User() {
     }
 
  //有参构造器
     public User(Integer id, String name) {
         this.id = id;
         this.name = name;
     }
 
     public Integer getId() {
         return id;
     }
 
     public void setId(Integer id) {
         this.id = id;
     }
 
     public String getName() {
         return name;
     }
 
     public void setName(String name) {
         this.name = name;
     }
 
 }

2、开发模式分类

在Java Web中占主导地位的开发模式有两种,分别称之为“模式一”和“模式二”:

  • 模式一(JSP+JavaBean): 简便、灵活,在小规模、业务逻辑简单的项目开发中有一定优势,开发效率高
  • 模式二(JSP+Servlet+JavaBean): 程序层次清晰、分工明确,可维护性、扩展性高,尤其在规模较大或是业务逻辑复杂的项目中倾向使用

3、模式一

模式 一:结合使用 JSP 页面和 JavaBean 来开发 Web 应用程序。JSP页面通过JavaBean处理数据,响应请求并返回结果

3.1、模式结构图

3.2、特点

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

3.3、示例

这个 JSP 页面包含各JSP 操作,可以用来访问 JavaBean 组件对象

 <%
 ...
   List productList = productDAO.getProduct();
   Iterator it = col.iterator();
   ProductBean temp = new ProductBean();
   if (it.hasNext()) {
     ProductBean temp = (ProductBean) it.next();
     ……
   }
 %>
 ……
 <%
   if(isPass){
     ……
   } else {
     ……
   }
 %>
 

二、模式二MVC

1、简介

所谓模式,就是为了避免重复设计相同的问题,存在于不同的抽象层,通过实践经验,不断地完善设计与产品的交互,以某种结构组合起来,可以重复利用的人工产物。

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

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

2、MVC模式结构

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

3、Modle层

指程序中的数据以及处理数据的业务规则,不关心数据以及处理结果如何展示给用户或是用户界面的显示细节

模型包括:数据模型(pojo或bean之类的东西)和业务模型(比如登陆,注册操作等)

JavaBean作为模型,可以分两层,DAO层、service层,基本功能如下:

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

DAO只完成基本的增删改查,虽然可以1-n,n-n,1-1关联,模糊、动态、子查询都可以。但是无论多么复杂的查询,dao只是封装增删改查。

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

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

4、View层

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

JSP页面作为视图层负责完成结果展示的细节,将业务处理的结果显示给用户

5、Cotroller层

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

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

控制层由一个或多个Servlet充当控制器,任务包括收集验证用户的输入内容、处理简单的业务逻辑、调用适当的业务处理方法

6、整体图

7、MVC的优点:

1、耦合性低

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

2、重用性高

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

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

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

4、可维护性高

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

8、MVC框架

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

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

三、综合案例

1、引入bootStrap

结构如下:

2、实现登录功能

controller

 package com.woniuxy.hrms.controller;
 
 import com.woniuxy.hrms.entity.Hr;
 import com.woniuxy.hrms.service.HrService;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.context.support.ClassPathXmlApplicationContext;
 
 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.IOException;
 
 /**
  * @author :fengsir
  * @date :Created in 2024/7/8 19:30
  * @description:TODO
  * @modified By:
  * @version: 1.0
  */
 @WebServlet("/user")
 public class UserController extends HttpServlet {
 
     private UserService userService;
 
     @Override
     public void init() throws ServletException {
         userService = new UserServiceImpl();
     }
 
     @Override
     protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
         request.setCharacterEncoding("utf-8");//必须放在所有请求之前才有效,不只是放到要接收的参数之前
         String method = request.getParameter("method");
         if (method.equals("login")) {
             String username = request.getParameter("username");
             String password = request.getParameter("password");
             Hr hr = hrService.login(username, password);
             if (hr != null) {
                 response.sendRedirect("admin.jsp");
             } else {
                 response.sendRedirect("login.jsp");
             }
         }
 
     }
 
     @Override
     protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
         doGet(req, resp);
     }
 }
 

mapper.xml

     <select id="login" resultType="com.woniuxy.hrms.entity.Hr">
         select * from sys_user where username=#{arg0} and password = #{arg1}
     </select>

登录页面

  <form action="hr?method=login" method="post">

3、查询全部

页面

核心代码

 <table class="table table-bordered text-center">
         <tr>
             <td>编号</td>
             <td>姓名</td>
             <td>电话</td>
             <td>创建时间</td>
             <td>操作</td>
         </tr>
         <%for(SysUser user:list){ %>
         <tr>
             <td><%=user.getId() %></td>
             <td><%=user.getNickName() %></td>
             <td><%=user.getTel() %></td>
             <td><%=user.getCreateTime() %></td>
             <td>
                 <a class="btn btn-round btn-square btn-info" href="user?method=queryById&id=<%=user.getId() %>">编辑<i class="mdi mdi-eye"></i></a>
                 <a class="btn btn-round btn-square btn-warning" href="javascript:check(<%=user.getId() %>)">删除<i class="mdi mdi-eye"></i></a>
             </td>
         </tr>
         <%} %>

 
     </table>

controller

 else if("queryAll".equals(method)) {
             List<SysUser> list = serviceImpl.selectAll();
             request.setAttribute("list", list);
             request.getRequestDispatcher("user/show.jsp").forward(request, response);
         }

mapper.xml

 <select id="selectAll"  resultMap="BaseResultMap">
     select
     <include refid="Base_Column_List" />
     from sys_user
   </select>

四、添加

controller

 else if("add".equals(method)) {
             String userName = request.getParameter("userName");
             String password = request.getParameter("password");
             String nickName = request.getParameter("nickName");
             String tel = request.getParameter("tel");
             SysUser user = new SysUser(0,userName, nickName, password, tel);
             DateFormat df = new SimpleDateFormat("yyyy-MM-dd");
             String createTime = request.getParameter("createTime");
             try {
                 Date date = df.parse(createTime);
                 user.setCreateTime(date);
             } catch (ParseException e) {
                 // TODO Auto-generated catch block
                 e.printStackTrace();
             }
             int i = serviceImpl.insertSelective(user);
             if(i>0) {
                 response.sendRedirect("user?method=queryAll");
             }else {
                 response.sendRedirect("user/add.jsp");
             }
         }

5、修改

页面

  <form action="manage/user?method=update" method="post" >
                     <div class="form-group">
                         <label for="userName">姓名</label>
                         <input type="text" placeholder="姓名" name="userName" id="userName" value="<%=user.getUserName() %>" class="form-control" />
                     </div>
                     <div class="form-group">
                         <label for="password">密码</label>
                         <input type="text" placeholder="密码" name="password" id="password" value="<%=user.getPassword() %>" class="form-control" />
                     </div>
                     <div class="form-group">
                         <label for="age">电话</label>
                         <input type="text" placeholder="电话" name="tel" id="tel"  value="<%=user.getTel() %>" class="form-control" />
                     </div>
                     <div class="form-group">
                         <label for="createDate">注册时间"</label>
                         <input type="text" placeholder="注册时间" name="createTime" id="createTime" value="<%=user.getCreateTime() %>"  class="form-control" />
                     </div>
                     <div class="form-group">
                         <input type="hidden" name="id" id="id" value="<%=user.getId() %>" />
                     </div>
                     <div class="form-group">
                         <button class="btn btn-primary" type="submit">提交信息</button>
                     </div>
 
             </form>

controller

 else if("queryById".equals(method)) {
             Integer id = Integer.parseInt(request.getParameter("id"));
             SysUser user = serviceImpl.selectByPrimaryKey(id);
             request.setAttribute("user", user);
             request.getRequestDispatcher("user/update.jsp").forward(request, response);
         }else if("update".equals(method)) {
             Integer id = Integer.parseInt(request.getParameter("id"));
             String userName = request.getParameter("userName");
             String password = request.getParameter("password");
             String nickName = request.getParameter("nickName");
             String tel = request.getParameter("tel");
             String createTime = request.getParameter("createTime");
             SysUser user = new SysUser(id,userName, nickName, password, tel);
             DateFormat df = new SimpleDateFormat("yyyy-MM-dd");
             try {
                 Date date = df.parse(createTime);
                 user.setCreateTime(date);
             } catch (ParseException e) {
                 // TODO Auto-generated catch block
                 e.printStackTrace();
             }
             int i = serviceImpl.updateByPrimaryKeySelective(user);
             if(i>0) {
                 response.sendRedirect("user?method=queryAll");
             }else {
                 response.sendRedirect("user?method=queryById");
             }
         }else if("delete".equals(method)) {
             Integer id = Integer.parseInt(request.getParameter("id"));

             int i = serviceImpl.deleteByPrimaryKey(id);
             if(i>0) {
                 response.sendRedirect("user?method=queryAll");
             }else {
                 response.sendRedirect("user?method=queryById");
             }
         }

6、删除

页面

 <a  href="javascript:check(<%=hr.getId()%>)">删除<i class="mdi mdi-eye"></i></a>
  <script type="text/javascript">
             function check(id){
                 let flag = confirm("确定要删除吗?");
                 if(flag){
                     location.href="user?method=delete&id="+id;
                 }
             }
 </script>

controller

 else if("delete".equals(method)) {
             Integer id = Integer.parseInt(request.getParameter("id"));

             int i = serviceImpl.deleteByPrimaryKey(id);
             if(i>0) {
                 response.sendRedirect("user?method=queryAll");
             }else {
                 response.sendRedirect("user?method=queryById");
             }
         }

7、综合版

  @Override
     protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
         String substring = request.getParameter("status");
         if ("login".equals(substring)) {
             login(request,response);
         } else if ("queryAll".equals(substring)) {
             queryAll(request,response);
         }else if ("add".equals(substring)) {
             add(request,response);
         }else if ("queryById".equals(substring)) {
             queryById(request,response);
         }else if ("update".equals(substring)) {
             update(request,response);
         }else if ("delete".equals(substring)) {
             delete(request,response);
         }else if ("queryByLike".equals(substring)) {
             queryByLike(request,response);
         }
 
     }

四、优化Servlet

该内容放在讲过反射之后再优化

1、创建BaseServlet

基于java反射思想根据请求路径动态调用对应的方法,这样好处无须单独再传参数来识别要操作的内容

 package com.woniuxy.hrms.controller;
 
 import javax.servlet.ServletException;
 import javax.servlet.http.HttpServlet;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 import java.io.IOException;
 import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
 
 /**
  * Description:
  * Author:
  * Date:2024-07-10
  * Time:10:56
  */
 public class BaseServlet extends HttpServlet {
     @Override
     protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
         //获取统一资源符
        // String requestURI = req.getRequestURI();
         //截取拿到最后一个斜杠,
         //String methodName = requestURI.substring(requestURI.lastIndexOf("/") + 1);
         request.setCharacterEncoding("utf-8");//必须放在所有请求之前才有效,不只是放到要接收的参数之前
         String methodName = request.getParameter("method");
         try {
             //this.getClass获取类对象,然后获取它的方法
             Method declaredMethod = this.getClass().getDeclaredMethod(methodName, HttpServletRequest.class, HttpServletResponse.class);
             //调用他的方法,因为调用的是整个service的方法,所以把两个对象传进来
             declaredMethod.invoke(this, req, resp);
         } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
             throw new RuntimeException(e);
         }
 
     }
 }
 

请求后台servlet时的方式是hr?method=login,其中method用来区分请求的方法

注意:引用BaseServlet之后处理请求编码必须要放在BaseServlet的service中来处理,因为这里已经调用了getgetParameter,调用该方法之后再设置编码不生效

2、创建HrServlet

HrServlet继承自BaseServlet即可

 package com.woniuxy.hrms.controller;
 
 import com.woniuxy.hrms.entity.Hr;
 import com.woniuxy.hrms.service.HrService;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.context.support.ClassPathXmlApplicationContext;
 
 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.IOException;
 import java.util.List;
 
 /**
  * @author :fengsir
  * @date :Created in 2024/7/8 19:30
  * @description:TODO
  * @modified By:
  * @version: 1.0
  */
 @WebServlet(value = "/user", loadOnStartup = 1)
 public class HrController extends BaseServlet {
 
     @Autowired
     private UserService userService;
 
     @Override
     public void init(ServletConfig config) throws ServletException {
         userService = new UserServiceImpl();
     }
 
 
     protected void login(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
         request.setCharacterEncoding("utf-8");//必须放在所有请求之前才有效,不只是放到要接收的参数之前
         String username = request.getParameter("username");
         String password = request.getParameter("password");
         Hr hr = hrService.login(username, password);
         if (hr != null) {
             response.sendRedirect("/admin.jsp");
         } else {
             response.sendRedirect("/login.jsp");
         }
 
     }
 
     protected void queryAll(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
         List<Hr> list = hrService.queryAll();
         req.setAttribute("list", list);
         req.getRequestDispatcher("/user/show.jsp").forward(req, resp);
     }
 
     protected void queryById(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
         req.setCharacterEncoding("utf-8");//必须放在所有请求之前才有效,不只是放到要接收的参数之前
         String id = req.getParameter("id");
         Hr hr = hrService.selectByPrimaryKey(Long.parseLong(id));
         req.setAttribute("hr", hr);
         req.getRequestDispatcher("/user/update.jsp").forward(req, resp);
     }
 
     protected void update(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
         req.setCharacterEncoding("utf-8");//必须放在所有请求之前才有效,不只是放到要接收的参数之前
         String id = req.getParameter("id");
         String realName = req.getParameter("realName");
         String username = req.getParameter("username");
         String password = req.getParameter("password");
         Hr hr = new Hr();
         hr.setId(Integer.parseInt(id));
         hr.setRealName(realName);
         hr.setUsername(username);
         hr.setPassword(password);
         int i = hrService.updateByPrimaryKeySelective(hr);
         queryAll(req, resp);
     }
 
     protected void add(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
         req.setCharacterEncoding("utf-8");//必须放在所有请求之前才有效,不只是放到要接收的参数之前
         String id = req.getParameter("id");
         String realName = req.getParameter("realName");
         String username = req.getParameter("username");
         String password = req.getParameter("password");
         Hr hr = new Hr();
         hr.setRealName(realName);
         hr.setUsername(username);
         hr.setPassword(password);
         int i = hrService.insertSelective(hr);
         queryAll(req, resp);
     }
 
     protected void delete(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
         req.setCharacterEncoding("utf-8");//必须放在所有请求之前才有效,不只是放到要接收的参数之前
         String id = req.getParameter("id");
         int i = hrService.deleteByPrimaryKey(Long.parseLong(id));
         queryAll(req, resp);
     }
 
 }
 
posted @ 2025-04-23 17:34  icui4cu  阅读(3)  评论(0)    收藏  举报