4.MVC模式
本章目标:
- 搭建项目
- 实现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、特点
- JavaBean是一种Java类,而且是一种特殊的、可重用的类。
- JavaBean必须具有无参数的构造器,所有的属性都是private的,通过提供setter和getter方法来实现对成员属性的访问。
- 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);
}
}
本文来自博客园,作者:icui4cu,转载请注明原文链接:https://www.cnblogs.com/icui4cu/p/18843141