MVC思想
JavaEE前后的设计思想
- Model1:在早起的时候,JavaEE以JSP为中心,使用JSP和JavaBean技术
开发一个简答的应用,完全够用。
但是当项目比较大的时候,存在的问题:JSP既要展示界面,又要处理请求,而JSP本身不是很擅长处理请求。
因此将处理请求提取出来,即Servlet。 - Model2:为了解决Model中JSP不善于处理请求的操作,在Model2中引入Servlet,专门用于处理请求。
使用到的技术有:JSP、Servlet、JavaBean
以Servlet为中心,所有请求都要先发给Servlet
各自做自己擅长的,这就是责任分离思想。 - MVC:
MVC最早应用与C/S领域,在JavaEE中发扬光大。主要强调责任分离思想。
M:Model (JavaBean)
V:View (JSP)
C:Control (Servlet)
每个请求对应一个响应。
合并Servlet
一开始一个对象需要写四个(增删改查)类,这样当对象很多的时候,很不方便,于是我们用一个类来包含着四种操作。
package com.Bryan.smis.web.servlet;
import java.io.IOException;
import java.util.List;
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 com.Bryan.smis.dao.IStudentDAO;
import com.Bryan.smis.dao.impl.StudentDAOImpl;
import com.Bryan.smis.domain.Student;
//处理所有Student相关的请求操作
@WebServlet("/student")
public class StudentServlet extends HttpServlet {
private static final long serialVersionUID = 1751771427617825274L;
private IStudentDAO dao;
public void init() throws ServletException {
dao = new StudentDAOImpl();
}
//分发操作
protected void service(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
//这一点要在获取参数之前进行编码转化
req.setCharacterEncoding("UTF-8");
String cmd = req.getParameter("cmd");
if ("save".equals(cmd))
this.saveOrUpdate(req, resp);
else if ("edit".equals(cmd))
this.edit(req, resp);
else if ("delete".equals(cmd))
this.delete(req, resp);
else
this.list(req, resp);
}
//列表
//http://localhost/student
protected void list(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
//1.接收请求参数,封装对象
//2.调用业务方法处理请求
List<Student> list = dao.listAll();
//3.控制界面跳转
req.setAttribute("student", list);
req.getRequestDispatcher("/WEB-INF/views/student/list.jsp").forward(req, resp);
System.out.println("List Done!");
System.out.println("!!!");
}
//编辑
//http://localhost/student?cmd=edit
protected void edit(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
//1.接收请求参数,封装对象
String id = req.getParameter("id");
//2.调用业务方法处理请求
if (hasLength(id)) {
Student stu = dao.get(id);
req.setAttribute("student", stu);
}
//3.控制界面跳转
req.getRequestDispatcher("/WEB-INF/views/student/edit.jsp").forward(req, resp);
}
//删除操作
//http://localhost/student?cmd=delete
protected void delete(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
//1.接收请求参数,封装对象
String id = req.getParameter("id");
//2.调用业务方法处理请求
dao.delete(id);
//3.控制界面跳转
resp.sendRedirect("/student");
System.out.println("Delete Done!");
}
//新增或更新
//http://localhost/student?cmd=save
protected void saveOrUpdate(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
//1.接收请求参数,封装对象
String id = req.getParameter("id");
String name = req.getParameter("name");
String gender = req.getParameter("gender");
String age = req.getParameter("age");
Student stu = new Student(id, name, gender, Integer.valueOf(age));
//2.调用业务方法处理请求
if (dao.get(id) != null) {
dao.update(id, stu);
} else {
dao.save(stu);
}
//3.控制界面跳转
resp.sendRedirect("/student");
}
private boolean hasLength(String str) {
return str != null && !"".equals(str.trim());
}
}
同时修改 list.jsp 和 edit.jsp 中的资源名称:
list.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<!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=UTF-8">
<title>CURD</title>
</head>
<body>
<a href="/student?cmd=edit">Addition</a>
<table border="1" width="80%" cellpadding="0" cellspacing="0">
<tr>
<th>Id</th>
<th>Name</th>
<th>Age</th>
<th>Operation</th>
</tr>
<c:forEach items="${student}" var="s" varStatus="vs">
<tr style='background-color: ${vs.count % 2 == 0 ? "aqua":""}'>
<td>${s.id}</td>
<td>${s.name}</td>
<td>${s.age}</td>
<td>
<a href="/student?cmd=delete&id=${s.id}">Delete</a> |
<a href="/student?cmd=edit&id=${s.id}">Edit</a>
</td>
</tr>
</c:forEach>
</table>
</body>
</html>
edit.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"%>
<!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=UTF-8">
<title>CURD</title>
</head>
<body>
<h3>${student == null?" 添加学生 ":" 更新学生 "}</h3>
<form action="/student?cmd=save" method="post">
学号:<input type="text" name="id" required value="${student.id}"/><br/>
姓名:<input type="text" name="name" required value="${student.name}"/><br/>
性别:<input type="radio" name="gender" value="M" ${student.gender =="M" ? "checked":""}/>男
<input type="radio" name="gender" value="F" ${student.gender =="F" ? "checked":""}/>女<br/>
年龄:<input type="number" name="age" required value="${student.age}"/><br/>
<input type="submit" value='${student == null?" 保存 ":" 更新 "}'>
<input type="button" value="查看列表" onclick="window.location.href='/student?cmd=list'">
</form>
</body>
</html>
若我们将部署的工程添加上下文路径,则要修改源代码中的资源路径,这显然不是我们想要的,因此,在JSP文件中,使用
${pageContext.request.contextPath}
若报错,则从Tomcat中找一个 jsp-api.jar 包,然后带java代码中,也加上上下文路径:
resp.sendRedirect(req.getContextPath() + "/student");
注意,在保存操作时用请求转发会导致死循环:
req.getRequestDispatcher("/student").forward(req, resp);
因为会将cmd中的save值也会作为请求而保留下来继续进行请求。因此尽量使用重定向。
另一个问题,当在删除操作中重复操作删除内容时:
不能在一个请求中向不同资源做跳转。