Spring 全家桶之 Spring Web MVC(四)- Restful CRUD

简介: Spring 全家桶之 Spring Web MVC(四)- Restful CRUD

使用Spring MVC编写一个Employee的CRUD项目,主要是编写Controller,员工数据保存在Map中,不使用数据库

Spring MVC 环境搭建

新建maven项目spring-mvc-crud,项目创建过程与配置方式及其maven依赖,创建过程参考QA 由浅入深 Spring Framework 5.0(十)- Spring MVC Restful,这里不在赘述。

在项目中新增entity包,保存Employee和Department实体类

public class Department {
   private Integer id;
   private String departmentName;
   // 省略getter/setter/toString方法
}   
复制代码
public class Employee {
   private Integer id;
   private String lastName;
   private String email;
   //1 male, 0 female
   private Integer gender;
   private Department department;
   //省略getter/setter/toString()方法
}   
复制代码

增加dao包,保存EmployeeDao和DepartmentDao

@Repository
public class EmployeeDao {
   private static Map<Integer, Employee> employees = null;
   @Autowired
   private DepartmentDao departmentDao;
   static{
      employees = new HashMap<Integer, Employee>();
      employees.put(1001, new Employee(1001, "Stark", "stark@stark-industry.com", 1, new Department(101, "Stark Industries")));
      employees.put(1002, new Employee(1002, "Steve", "steve@gmail.com", 1, new Department(102, "US Army")));
      employees.put(1003, new Employee(1003, "Thor", "thor@gmail.com", 1, new Department(103, "Asgard")));
      employees.put(1004, new Employee(1004, "Banner", "banner@gmail.com", 1, new Department(104, "None")));
      employees.put(1005, new Employee(1005, "Natasha", "natash@gmail.com", 0, new Department(105, "S.H.I.E.L.D. ")));
      employees.put(1006, new Employee(1006, "Clint", "client@gmail.com", 1, new Department(105, "S.H.I.E.L.D. ")));
   }
   //初始id
   private static Integer initId = 1007;
   public void save(Employee employee){
      if(employee.getId() == null){
         employee.setId(initId++);
      }
      //根据部门id单独查出部门信息设置到员工对象中,页面提交的只需要提交部门的id
      employee.setDepartment(departmentDao.getDepartment(employee.getDepartment().getId()));
      employees.put(employee.getId(), employee);
   }
   public Collection<Employee> getAll(){
      return employees.values();
   }
   public Employee get(Integer id){
      return employees.get(id);
   }
   public void delete(Integer id){
      employees.remove(id);
   }
}
复制代码
@Repository
public class DepartmentDao {
   private static Map<Integer, Department> departments = null;
   static{
      departments = new HashMap<Integer, Department>();
      departments.put(101, new Department(101, "Stark Industries"));
      departments.put(102, new Department(102, "US Army"));
      departments.put(103, new Department(103, "Asgard"));
      departments.put(104, new Department(104, "None"));
      departments.put(105, new Department(105, "S.H.I.E.L.D. "));
   }
   public Collection<Department> getDepartments(){
      return departments.values();
   }
   public Department getDepartment(Integer id){
      return departments.get(id);
   }
}
复制代码

Employee列表展示

获取员工列表的步骤:

  1. 项目启动,直接访问index.jsp页面
  2. 直接发送/emps请求
  3. Controller查询所有员工
  4. 放入请求域中
  5. 转发到list页面展示

controller包中增加EmployeeController,控制员工的增删改查。首先增加一个list方法,获取员工列表,将员工信息保存在emps变量中,方便页面进行提取

@Controller
public class EmployeeController {
    @Resource
    private EmployeeDao employeeDao;
    @RequestMapping("/emps")
    public String list(Model model){
        Collection<Employee> employees = employeeDao.getAll();
        model.addAttribute("emps",employees);
        return "list";
    }
}
复制代码

在page目录下增加list.jsp,用来展示员工列表,body标签中增加一个表头,并定义列属性

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>List</title>
</head>
<body>
    <h1>员工列表</h1>
    <table>
        <tr>
            <th>ID</th>
            <th>LastName</th>
            <th>Email</th>
            <th>Gender</th>
            <th>Dep</th>
            <th>EDIT</th>
            <th>DELETE</th>
        </tr>
    </table>
</body>
</html>
复制代码

修改index.jsp页面,使项目启动后自动跳转到员工列表页面

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%--访问项目首先展示员工列表页--%>
<jsp:forward page="/emps"></jsp:forward>
复制代码

pxm.xml导入jsp api依赖,修改list.jsp页面

<!-- https://mvnrepository.com/artifact/javax.servlet.jsp.jstl/jstl -->
<dependency>
    <groupId>javax.servlet.jsp.jstl</groupId>
    <artifactId>jstl</artifactId>
    <version>1.2</version>
</dependency>
复制代码

页面顶部导入

<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
复制代码

修改table内容,使用forEach循环获取保存在emps中的员工信息

<table border="1" cellpadding="5" cellspacing="0"
>
    <tr>
        <th>ID</th>
        <th>LastName</th>
        <th>Email</th>
        <th>Gender</th>
        <th>Dep</th>
        <th>EDIT</th>
        <th>DELETE</th>
    </tr>
    <c:forEach items="${emps}" var="emp">
        <tr>
            <td>${emp.id }</td>
            <td>${emp.lastName}</td>
            <td>${emp.email }</td>
            <td>${emp.gender==0?"女":"男" }</td>
            <td>${emp.department.departmentName }</td>
            <th>EDIT</th>
            <th>DELETE</th>
        </tr>
    </c:forEach>
</table>
复制代码

重新启动Tomcat,浏览器输入http://localhost:8080/

9f0005faad034a2e970843611732970c_tplv-k3u1fbpfcp-zoom-in-crop-mark_4536_0_0_0.png

新增Employee

新增Eemployee步骤:

  1. 在列表页面点击添加超链接
  2. 查询出所有部门信息,跳转至添加页面
  3. 输入新增员工信息,点击保存
  4. Controller接收到新增员工信息,执行保存操作
  5. 再次跳转至list页面

EmployeeController中新增addPage方法,跳转到add页面

// 点击增加按钮跳转至增加页面,并查询所有部分信息,供新增员工时选择
@RequestMapping("/add")
public String addPage(Model model){
    Collection<Department> departments = depmentDao.getDepartments();
    model.addAttribute("depts",departments);
    return "add";
}
复制代码

新增add页面,form表单中的属性应该与Employee实体类保持一致,部门信息通过for循环展示所有可选择的部门

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!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>Insert title here</title>
</head>
<body>
<h1>员工添加</h1>
<form action="">
   lastName:<input type="text" name="lastName"/><br/>
   email:<input type="text" name="email"/><br/>
   gender:  <br/>
      男:<input type="radio" name="gender" value="1"/><br/>
      女:<input type="radio" name="gender" value="0"><br/>
   dept:
      <select name="department.id">
         <c:forEach items="${depts}" var="deptItem">
            <!-- 标签体中的是在页面的提示选项信息,value才是真正提交的值 -->
            <option value="${deptItem.id}">${deptItem.departmentName }</option>
         </c:forEach>
      </select>
   <input type="submit" value="提交"/>
</form> 
</body>
</html>
复制代码

重新启动Tomcat,输入http://localhost:8080/ 点击列表地步的添加员工超链接,跳转至添加页面

3b75feb735f7481191f158f513459cd3_tplv-k3u1fbpfcp-zoom-in-crop-mark_4536_0_0_0.png

添加员工操作

Spring MVC表单标签:通过 SpringMVC的表单标签可以实现将模型数据中的属性和 HTML 表单元素相绑定,以实现表单数据更便捷编辑和表单值的回显

首先在add页面上导入表单标签

<%@taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
复制代码

修改form表单,使用form标签

<form:form action="" modelAttribute="employee" method="POST">
   <!-- path就是原来html-input的name项:需要写
      path:
         1)、当做原生的name项
         2)、自动回显隐含模型中某个对象对应的这个属性的值
   -->
   LastName:<form:input path="lastName"/><br/>
   Email:<form:input path="email"/><br/>
   Gender:<br/>
      男:<form:radiobutton path="gender" value="1"/><br/>
      女:<form:radiobutton path="gender" value="0"/><br/>
   Dept:
      <!--
      items="":指定要遍历的集合 ;自动遍历;遍历出的每一个元素是一个department对象
      itemLabel="属性名":指定遍历出的这个对象的哪个属性是作为option标签体的值
      itemValue="属性名":指定刚才遍历出来的这个对象的哪个属性是作为要提交 的value值
       -->
      <form:select path="department.id"
         items="${depts}"
         itemLabel="departmentName"
         itemValue="id"></form:select><br/>
   <input type="submit" value="保存"/>
</form:form>
复制代码

重启Tomcat,点击列表页面的添加员工超链接,出现报错信息

2caa537a34ee47d3b659264815f0134c_tplv-k3u1fbpfcp-zoom-in-crop-mark_4536_0_0_0.png

这个报错是因为请求域中没有command,修改跳转到增加页面的方法

model.addAttribute("command", new Employee(null,"Peter","peter@gmail.com",1,depmentDao.getDepartment(101)));
复制代码

这个员工的信息会在跳转到增加页面后直接显示出来

f1dee77b76364378b60e3ad6b968a06e_tplv-k3u1fbpfcp-zoom-in-crop-mark_4536_0_0_0.png

在页面上form标签中使用modelAttribute属性,指定取哪个字段的属性(替换command变量)

<form:form action="" modelAttribute="employee">
复制代码
model.addAttribute("employee", new Employee());
复制代码

增加员工添加的方法

@RequestMapping(value = "/emp", method = RequestMethod.POST)
public String addEmp(Employee employee){
    System.out.println("要添加的员工信息:" + employee);
    employeeDao.save(employee);
    // 返回列表页面
    return "redirect:/emps";
}
复制代码

重启Tomcat,点击进入新增页面,输入员工信息,点击保存,新增成功

398e1bafc82949ebb5cdcea5abb5ca2f_tplv-k3u1fbpfcp-zoom-in-crop-mark_4536_0_0_0.png

修改Employee

修改Employee步骤:

  1. 任选一个员工点击EDIT超链接
  2. 查询这个员工的信息,跳转到编辑页面,页面展示选择的员工信息
  3. 编辑员工信息,点击提交
  4. Controller中方法保存修改的员工
  5. 再次返回list页面

首先要回显员工信息,改造list页面中table标签中的EDIT超链接

<td><a href="${ctp}/emp/${emp.id }">EDIT</a></td>
复制代码

EmployeeController中增加方法,根据ID查询员工信息,并返回到员工信息编辑页面

@RequestMapping(value = "/emp/{id}", method = RequestMethod.GET)
public String getEmp(@PathVariable("id") Integer id, Model model) {
    // 1、查出员工信息
    Employee employee = employeeDao.get(id);
    // 2、放在请求域中
    model.addAttribute("employee", employee);
    // 3、继续查出部门信息放在隐含模型中
    Collection<Department> departments = departmentDao.getDepartments();
    model.addAttribute("depts", departments);
    return "edit";
}
复制代码

增加员工信息编辑页面edit.jsp,该页面显示的员工信息就是要编辑的员工信息

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
<!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>Insert title here</title>
<%
   pageContext.setAttribute("ctp", request.getContextPath());
%>
</head>
<body>
<h1>员工修改页面</h1>
<!-- modelAttribute:这个表单的所有内容显示绑定的是请求域中 employee的值-->
<form:form action="${ctp}/emp/${employee.id }" 
   modelAttribute="employee" method="post">
   <input type="hidden" name="_method" value="put"/>
   <input type="hidden" name="id" value="${employee.id }"/>
   email:<form:input path="email"/><br/>
   gender:&nbsp;&nbsp;&nbsp;
      男:<form:radiobutton path="gender" value="1"/>&nbsp;&nbsp;&nbsp;
      女:<form:radiobutton path="gender" value="0"/><br/>
   dept:
      <form:select path="department.id" items="${depts}"
         itemLabel="departmentName" itemValue="id"></form:select>
         <br/>
   <input type="submit" value="修改"/>
</form:form>
</body>
</html>
复制代码

重启Tomcat, 任意选择一个员工,点击EDIT,可以成功跳转到编辑页面

8abb0623893e4d888457696534cb9329_tplv-k3u1fbpfcp-zoom-in-crop-mark_4536_0_0_0.png

新增员工修改方法

@RequestMapping(value = "/emp/{id}", method = RequestMethod.PUT)
public String updateEmp(@ModelAttribute("employee")Employee employee/* ,@PathVariable("id")Integer id */) {
    System.out.println("要修改的员工:" + employee);
    // xxxx 更新保存二合一;
    employeeDao.save(employee);
    return "redirect:/emps";
}
复制代码
@ModelAttribute
public void myModelAttribute(
        @RequestParam(value = "id", required = false) Integer id, Model model) {
    if (id != null) {
        Employee employee = employeeDao.get(id);
        model.addAttribute("employee", employee);
    }
    System.out.println("hahha ");
}
复制代码

重新启动Tomcat,修改Clint部门为None

1f9d23b485a649a4a4b9f0900e00a188_tplv-k3u1fbpfcp-zoom-in-crop-mark_4536_0_0_0.png

删除Employee

删除Employee步骤:

  1. list页面点击删除超链接
  2. Controller处理删除请求,从Map中删除员工信息
  3. 再次返回list页面

Controller中增加删除方法

@RequestMapping(value="/emp/{id}",method=RequestMethod.DELETE)
public String deleteEmp(@PathVariable("id")Integer id){
    employeeDao.delete(id);
    return "redirect:/emps";
}
复制代码

修改list页面的删除超链接

<td><a href="${ctp }/emp/${emp.id }" class="delBtn">delete</a></td>
复制代码

在web目录下增加js文件夹,包含了jquery文件,dispatcherServlet-servlet.xml中配置静态资源请求

<!-- 默认前端控制器是拦截所有资源(除过jsp),js文件就404了;要js文件的请求是交给tomcat处理的 -->
    <!-- 告诉SpringMVC,自己映射的请求就自己处理,不能处理的请求直接交给tomcat -->
    <!-- 静态资源能访问,动态映射的请求就不行 -->
    <mvc:default-servlet-handler/>
    <!-- springmvc可以保证动态请求和静态请求都能访问 -->
    <mvc:annotation-driven></mvc:annotation-driven>
复制代码

在添加员工超链接下增加代码

<form id="deleteForm" action="${ctp }/emp/${emp.id }" method="post">
    <input type="hidden" name="_method" value="DELETE" />
</form>
<script type="text/javascript">
    $(function(){
        $(".delBtn").click(function(){
            //0、确认删除?
            //1、改变表单的action指向
            $("#deleteForm").attr("action",this.href);
            //2、提交表单
            $("#deleteForm").submit();
            return false;
        });
    });
</script>
复制代码

重启Tomcat,执行删除操作


相关文章
|
1月前
|
Java API 数据库
构建RESTful API已经成为现代Web开发的标准做法之一。Spring Boot框架因其简洁的配置、快速的启动特性及丰富的功能集而备受开发者青睐。
【10月更文挑战第11天】本文介绍如何使用Spring Boot构建在线图书管理系统的RESTful API。通过创建Spring Boot项目,定义`Book`实体类、`BookRepository`接口和`BookService`服务类,最后实现`BookController`控制器来处理HTTP请求,展示了从基础环境搭建到API测试的完整过程。
48 4
|
4月前
|
开发框架 JSON API
震撼发布!Python Web开发框架下的RESTful API设计全攻略,让数据交互更自由!
【7月更文挑战第22天】在Python Web开发中,设计高效的RESTful API涉及选择框架(如Flask或Django)、明确资源及使用HTTP方法(GET, POST, PUT, DELETE)来操作数据。响应格式通常是JSON,错误处理也很重要。示例展示了使用Flask创建图书管理API,包括版本控制、文档化、安全性和性能优化是最佳实践。这样的API使数据交互更顺畅。
98 2
|
25天前
|
JSON API 数据格式
如何使用Python和Flask构建一个简单的RESTful API。Flask是一个轻量级的Web框架
本文介绍了如何使用Python和Flask构建一个简单的RESTful API。Flask是一个轻量级的Web框架,适合小型项目和微服务。文章从环境准备、创建基本Flask应用、定义资源和路由、请求和响应处理、错误处理等方面进行了详细说明,并提供了示例代码。通过这些步骤,读者可以快速上手构建自己的RESTful API。
28 2
|
3月前
|
Java API 数据库
【神操作!】Spring Boot打造RESTful API:从零到英雄,只需这几步,让你的Web应用瞬间飞起来!
【8月更文挑战第12天】构建RESTful API是现代Web开发的关键技术之一。Spring Boot因其实现简便且功能强大而深受开发者喜爱。本文以在线图书管理系统为例,展示了如何利用Spring Boot快速构建RESTful API。从项目初始化、实体定义到业务逻辑处理和服务接口实现,一步步引导读者完成API的搭建。通过集成JPA进行数据库操作,以及使用控制器类暴露HTTP端点,最终实现了书籍信息的增删查改功能。此过程不仅高效直观,而且易于维护和扩展。
61 1
|
3月前
|
Java 网络架构 数据格式
Struts 2 携手 RESTful:颠覆传统,重塑Web服务新纪元的史诗级组合!
【8月更文挑战第31天】《Struts 2 与 RESTful 设计:构建现代 Web 服务》介绍如何结合 Struts 2 框架与 RESTful 设计理念,构建高效、可扩展的 Web 服务。Struts 2 的 REST 插件提供简洁的 API 和约定,使开发者能快速创建符合 REST 规范的服务接口。通过在 `struts.xml` 中配置 `&lt;rest&gt;` 命名空间并使用注解如 `@Action`、`@GET` 等,可轻松定义服务路径及 HTTP 方法。
64 0
|
3月前
|
前端开发 API 开发者
JSF与RESTful服务的完美邂逅:如何打造符合现代Web潮流的数据交互新体验
【8月更文挑战第31天】随着互联网技术的发展,RESTful架构风格因其实现简便与无状态特性而在Web服务构建中日益流行。本文探讨如何结合JavaServer Faces (JSF) 和 JAX-RS 构建RESTful API,展示从前端到后端分离的完整解决方案。通过定义资源类、配置 `web.xml` 文件以及使用依赖注入等步骤,演示了在JSF项目中实现RESTful服务的具体过程,为Java开发者提供了实用指南。
41 0
|
3月前
|
Java Spring 开发者
Java Web开发新潮流:Vaadin与Spring Boot强强联手,打造高效便捷的应用体验!
【8月更文挑战第31天】《Vaadin与Spring Boot集成:最佳实践指南》介绍了如何结合Vaadin和Spring Boot的优势进行高效Java Web开发。文章首先概述了集成的基本步骤,包括引入依赖和配置自动功能,然后通过示例展示了如何创建和使用Vaadin组件。相较于传统框架,这种集成方式简化了配置、提升了开发效率并便于部署。尽管可能存在性能和学习曲线方面的挑战,但合理的框架组合能显著提升应用开发的质量和速度。
71 0
|
3月前
|
消息中间件 Java Kafka
Spring Boot与模板引擎:整合Thymeleaf和FreeMarker,打造现代化Web应用
【8月更文挑战第29天】这段内容介绍了在分布式系统中起到异步通信与解耦作用的消息队列,并详细探讨了三种流行的消息队列产品:RabbitMQ、RocketMQ 和 Kafka。RabbitMQ 是一个基于 AMQP 协议的开源消息队列系统,支持多种消息模型,具有高可靠性及稳定性;RocketMQ 则是由阿里巴巴开源的高性能分布式消息队列,支持事务消息等多种特性;而 Kafka 是 LinkedIn 开源的分布式流处理平台,以其高吞吐量和良好的可扩展性著称。文中还提供了使用这三种消息队列产品的示例代码。
34 0
|
4月前
|
JSON API 开发者
惊!Python Web开发新纪元,RESTful API设计竟能如此性感撩人?
【7月更文挑战第24天】在 Python Web 开发领域, RESTful API 设计成为一种艺术, 关注用户体验与开发者友好性。
48 7
|
4月前
|
JSON API 数据格式
深度剖析!Python Web 开发中 RESTful API 的每一个细节,你不可不知的秘密!
【7月更文挑战第23天】在Python Web开发中,RESTful API利用HTTP协议构建强大、灵活的应用。GET获取资源,如`/products/:id`;POST创建新资源;PUT更新;DELETE删除。正确使用状态码,如200、201、404、500,至关重要。JSON化数据与版本控制(如`/v1/products`)增强API实用性。认证(OAuth, JWT)保障安全性,而清晰的错误消息提升用户体验。掌握这些细节,方能设计出高性能、易用的RESTful API。
58 7
下一篇
无影云桌面