SpringMVC 學習筆記(五) 基於RESTful的CRUD

u013457570發表於2016-12-18

1.1. 概述

當提交的表單帶有_method欄位時,通過HiddenHttpMethodFilter 將 POST 請求轉換成 DELETEPUT請求,加上@PathVariable註解從而實現 RESTful 風格的CRUD


1.2. 配置資訊

Web.xml

[html] view plain copy
  1. <?xml version="1.0" encoding="UTF-8"?>  
  2. <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
  3.     xmlns="http://java.sun.com/xml/ns/javaee"  
  4.     xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"  
  5.     version="3.0" >  
  6.     <!-- The front controller of this Spring Web application, responsible for handling all application requests -->  
  7.     <servlet>  
  8.         <servlet-name>springDispatcherServlet</servlet-name>  
  9.         <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>  
  10.         <init-param>  
  11.             <param-name>contextConfigLocation</param-name>  
  12.             <param-value>classpath:spring-mvc.xml</param-value>  
  13.         </init-param>  
  14.         <load-on-startup>1</load-on-startup>  
  15.     </servlet>  
  16.   
  17.     <!-- Map all requests to the DispatcherServlet for handling -->  
  18.     <servlet-mapping>  
  19.         <servlet-name>springDispatcherServlet</servlet-name>  
  20.         <url-pattern>/</url-pattern>  
  21.     </servlet-mapping>  
  22.       
  23.     <!--配置  HiddenHttpMethodFilter 可以將   POST 請求轉為 DELETE、PUT 請求 -->  
  24.     <filter>  
  25.         <filter-name>hiddenHttpMethodFilter</filter-name>  
  26.         <filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class>  
  27.     </filter>  
  28.       
  29.     <filter-mapping>  
  30.         <filter-name>hiddenHttpMethodFilter</filter-name>  
  31.         <url-pattern>/*</url-pattern>  
  32.     </filter-mapping>  
  33. </web-app>  

1.3. 效果

① 通過POST 請求增加員工資訊

② 通過PUT 請求修改員工資訊

③ 通過DELETE 請求刪除員工資訊

④ 通過GET 請求 獲取所有的 員工資訊




1.4. 程式碼

Employee.Java

[java] view plain copy
  1. package com.ibigsea.springmvc.model;  
  2.   
  3. public class Employee {  
  4.       
  5.     private Integer id;  
  6.     private String name;  
  7.     private String email;  
  8.     private int sex;  
  9.       
  10.     private Department department;  
  11.       
  12.     public Employee(Integer id, String name, String email, int sex,  
  13.             Department department) {  
  14.         super();  
  15.         this.id = id;  
  16.         this.name = name;  
  17.         this.email = email;  
  18.         this.sex = sex;  
  19.         this.department = department;  
  20.     }  
  21.       
  22.     public Employee() {  
  23.         super();  
  24.     }  
  25.   
  26.     public Integer getId() {  
  27.         return id;  
  28.     }  
  29.   
  30.     public void setId(Integer id) {  
  31.         this.id = id;  
  32.     }  
  33.   
  34.     public String getName() {  
  35.         return name;  
  36.     }  
  37.   
  38.     public void setName(String name) {  
  39.         this.name = name;  
  40.     }  
  41.   
  42.     public String getEmail() {  
  43.         return email;  
  44.     }  
  45.   
  46.     public void setEmail(String email) {  
  47.         this.email = email;  
  48.     }  
  49.   
  50.     public int getSex() {  
  51.         return sex;  
  52.     }  
  53.   
  54.     public void setSex(int sex) {  
  55.         this.sex = sex;  
  56.     }  
  57.   
  58.     public Department getDepartment() {  
  59.         return department;  
  60.     }  
  61.   
  62.     public void setDepartment(Department department) {  
  63.         this.department = department;  
  64.     }  
  65.   
  66.     @Override  
  67.     public String toString() {  
  68.         return "Employee [id=" + id + ", name=" + name + ", email=" + email  
  69.                 + ", sex=" + sex + ", department=" + department + "]";  
  70.     }  
  71.       
  72. }  

Department.java

[java] view plain copy
  1. package com.ibigsea.springmvc.model;  
  2.   
  3. import java.io.Serializable;  
  4.   
  5. public class Department implements Serializable {  
  6.   
  7.     private static final long serialVersionUID = 6881984318733090395L;  
  8.       
  9.     private Integer id;  
  10.     private String name;  
  11.   
  12.     public Integer getId() {  
  13.         return id;  
  14.     }  
  15.     public void setId(Integer id) {  
  16.         this.id = id;  
  17.     }  
  18.     public String getName() {  
  19.         return name;  
  20.     }  
  21.     public void setName(String name) {  
  22.         this.name = name;  
  23.     }  
  24.   
  25.     @Override  
  26.     public String toString() {  
  27.         return "Department [id=" + id + ", name=" + name + "]";  
  28.     }  
  29.       
  30. }  

RestfulController.java

[java] view plain copy
  1. package com.ibigsea.springmvc.rest;  
  2.   
  3. import java.util.Map;  
  4.   
  5. import org.springframework.beans.factory.annotation.Autowired;  
  6. import org.springframework.stereotype.Controller;  
  7. import org.springframework.web.bind.annotation.ModelAttribute;  
  8. import org.springframework.web.bind.annotation.PathVariable;  
  9. import org.springframework.web.bind.annotation.RequestMapping;  
  10. import org.springframework.web.bind.annotation.RequestMethod;  
  11. import org.springframework.web.bind.annotation.RequestParam;  
  12.   
  13. import com.ibigsea.springmvc.dao.DepartmentDao;  
  14. import com.ibigsea.springmvc.dao.EmployeeDao;  
  15. import com.ibigsea.springmvc.model.Employee;  
  16.   
  17. /** 
  18.  * 基於Restful風格的增刪改查 
  19.  * @author bigsea 
  20.  */  
  21. @Controller  
  22. @RequestMapping("/restful")  
  23. public class RestfulController {  
  24.       
  25.     @Autowired  
  26.     private EmployeeDao employeeDao;  
  27.       
  28.     @Autowired  
  29.     private DepartmentDao departmentDao;  
  30.       
  31.     /** 
  32.      * 因為修改的時候不能修改員工姓名, 
  33.      * 所以通過 @ModelAttribute 註解, 
  34.      * 表示在執行目標方法時,先獲取該員工物件 
  35.      * 將員工物件存入 implicitMode 中 
  36.      * @param id 員工ID 
  37.      * @param map 實際傳入的是implicitMode 
  38.      */  
  39.     @ModelAttribute  
  40.     public void getEmployee(@RequestParam(value="id",required=false) Integer id,Map<String,Object> map){  
  41.         if (id != null) {  
  42.             map.put("employee", employeeDao.getEmpById(id));  
  43.         }  
  44.     }  
  45.       
  46.     /** 
  47.      * 檢視所有的員工資訊 
  48.      * @param map 
  49.      * @return 
  50.      */  
  51.     @RequestMapping("/list")  
  52.     public String list(Map<String, Object> map){  
  53.         map.put("emps", employeeDao.getAll());  
  54.         return "list";  
  55.     }  
  56.       
  57.     /** 
  58.      * 跳轉到員工新增頁面 
  59.      * @param map 
  60.      * @return 
  61.      */  
  62.     @RequestMapping(value="/add",method=RequestMethod.GET)  
  63.     public String add(Map<String, Object> map){  
  64.         map.put("depts", departmentDao.getAll());  
  65.         map.put("action""add");  
  66.         return "emp";  
  67.     }  
  68.       
  69.     /** 
  70.      * 新增員工 
  71.      * @param emp 
  72.      * @return 
  73.      */  
  74.     @RequestMapping(value="/add",method=RequestMethod.POST)  
  75.     public String add(Employee emp){  
  76.         if (emp == null) {  
  77.             return "emp";  
  78.         }  
  79.         if (emp.getDepartment().getId() != null) {  
  80.             emp.setDepartment(departmentDao.getDepartmentById(emp.getDepartment().getId()));  
  81.         }  
  82.         employeeDao.save(emp);  
  83.         return "redirect:/restful/list";  
  84.     }  
  85.   
  86.     /** 
  87.      * 刪除員工資訊 
  88.      * @param id 
  89.      * @return 
  90.      */  
  91.     @RequestMapping(value="/delete/{id}",method=RequestMethod.DELETE)  
  92.     public String delete(@PathVariable("id") Integer id){  
  93.         employeeDao.delEmpById(id);  
  94.         return "redirect:/restful/list";  
  95.     }  
  96.       
  97.     /** 
  98.      * 因為先執行了 @ModelAttribute 註解的方法, 
  99.      * 獲取了該員工ID所對應的員工資訊 
  100.      * 然後在將前臺獲取的員工資料存入獲取的員工資訊中, 
  101.      * 這樣就不用提交name屬性也可以獲取到值 
  102.      * @param emp 
  103.      * @return 
  104.      */  
  105.     @RequestMapping(value="/edit",method=RequestMethod.PUT)  
  106.     public String edit(Employee emp){  
  107.         if (emp == null) {  
  108.             return "emp";  
  109.         }  
  110.         if (emp.getDepartment().getId() != null) {  
  111.             emp.setDepartment(departmentDao.getDepartmentById(emp.getDepartment().getId()));  
  112.         }  
  113.         employeeDao.save(emp);  
  114.         return "redirect:/restful/list";  
  115.     }  
  116.       
  117.     /** 
  118.      * 跳轉到員工修改頁面 
  119.      * @param id 員工ID 
  120.      * @param map implicitMode 
  121.      * @return  
  122.      */  
  123.     @RequestMapping(value="/edit/{id}",method=RequestMethod.GET)  
  124.     public String edit(@PathVariable("id") Integer id,Map<String, Object> map){  
  125.         map.put("emp", employeeDao.getEmpById(id));  
  126.         map.put("depts", departmentDao.getAll());  
  127.         map.put("action""edit");  
  128.         return "emp";  
  129.     }  
  130.       
  131.       
  132.       
  133. }  

EmployeeDao.java

[java] view plain copy
  1. package com.ibigsea.springmvc.dao;  
  2.   
  3. import java.util.Collection;  
  4. import java.util.HashMap;  
  5. import java.util.Map;  
  6.   
  7. import org.springframework.stereotype.Component;  
  8.   
  9. import com.ibigsea.springmvc.model.Department;  
  10. import com.ibigsea.springmvc.model.Employee;  
  11.   
  12. @Component  
  13. public class EmployeeDao {  
  14.       
  15.     private static Map<Integer,Employee> emps = new HashMap<Integer, Employee>();  
  16.       
  17.     /** 
  18.      * 初始化員工資訊 
  19.      */  
  20.     static {  
  21.         emps.put(1001new Employee(1001,"AA","AA@ibigsea.com",0,new Department(101"JAVA")));  
  22.         emps.put(1002new Employee(1002,"BB","BB@ibigsea.com",0,new Department(102".NET")));  
  23.         emps.put(1003new Employee(1003,"CC","CC@ibigsea.com",1,new Department(103"PHP")));  
  24.         emps.put(1004new Employee(1004,"DD","DD@ibigsea.com",0,new Department(104"C")));  
  25.     }  
  26.       
  27.     private static int employeeId = 1005;  
  28.       
  29.     /** 
  30.      * 儲存員工資訊 
  31.      * @param emp 
  32.      */  
  33.     public void save(Employee emp){  
  34.         if (emp.getId() == null) {  
  35.             emp.setId(employeeId++);  
  36.         }  
  37.         emps.put(emp.getId(), emp);  
  38.     }  
  39.       
  40.     /** 
  41.      * 獲取所有的員工資訊 
  42.      * @return 
  43.      */  
  44.     public Collection<Employee> getAll(){  
  45.         return emps.values();  
  46.     }  
  47.       
  48.     /** 
  49.      * 根據ID獲取員工資訊 
  50.      * @param id 
  51.      * @return 
  52.      */  
  53.     public Employee getEmpById(Integer id){  
  54.         return emps.get(id);  
  55.     }  
  56.       
  57.     /** 
  58.      * 根據ID刪除員工資訊 
  59.      * @param id 
  60.      */  
  61.     public void delEmpById(Integer id){  
  62.         emps.remove(id);  
  63.     }  
  64.       
  65. }  

DepartmentDao.java

[java] view plain copy
  1. package com.ibigsea.springmvc.dao;  
  2.   
  3. import java.util.Collection;  
  4. import java.util.HashMap;  
  5. import java.util.Map;  
  6.   
  7. import org.springframework.stereotype.Component;  
  8.   
  9. import com.ibigsea.springmvc.model.Department;  
  10.   
  11. @Component  
  12. public class DepartmentDao {  
  13.   
  14.     public static Map<Integer, Department> depts = new HashMap<Integer, Department>();  
  15.       
  16.     /** 
  17.      * 初始化部門資訊 
  18.      */  
  19.     static {  
  20.         depts.put(101new Department(101,"JAVA"));  
  21.         depts.put(102new Department(102,".NET"));  
  22.         depts.put(103new Department(103,"PHP"));  
  23.         depts.put(104new Department(104,"C"));  
  24.     }  
  25.       
  26.     /** 
  27.      * 獲取所有的部門資訊 
  28.      * @return 
  29.      */  
  30.     public Collection<Department> getAll(){  
  31.         return depts.values();  
  32.     }  
  33.       
  34.     /** 
  35.      * 根據ID獲取部門資訊 
  36.      * @param id 
  37.      * @return 
  38.      */  
  39.     public Department getDepartmentById(Integer id){  
  40.         return depts.get(id);  
  41.     }  
  42.       
  43. }  

List.jsp

[html] view plain copy
  1. <%@ page language="java" contentType="text/html; charset=UTF-8"  
  2.     pageEncoding="UTF-8"%>  
  3. <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>  
  4. <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">  
  5. <html>  
  6. <head>  
  7. <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">  
  8. <title>員工資訊</title>  
  9. </head>  
  10. <body>  
  11.   
  12.     <c:if test="${ empty emps }">  
  13.         沒有員工資訊  
  14.     </c:if>  
  15.     <c:if test="${ !empty emps }">  
  16.             <table border="1" bordercolor="black" cellspacing="0">  
  17.                 <tr>  
  18.                     <td width="40px">id</td>  
  19.                     <td width="30px">name</td>  
  20.                     <td width="80px">email</td>  
  21.                     <td width="30px">sex</td>  
  22.                     <td width="40px">編輯</td>  
  23.                     <td width="40px">刪除</td>  
  24.                 </tr>  
  25.                 <c:forEach items="${emps }" var="emp">  
  26.                     <tr>  
  27.                         <td>${emp.id }</td>  
  28.                         <td>${emp.name }</td>  
  29.                         <td>${emp.email }</td>  
  30.                         <td>${emp.sex == 0 ? '男' : '女'}</td>  
  31.                         <td><a href="${pageContext.request.contextPath}/restful/edit/${emp.id }">Edit</a></td>  
  32.                         <td><form action="${pageContext.request.contextPath}/restful/delete/${emp.id }" method="post">  
  33.                                 <input type="hidden" name="_method" value="DELETE">  
  34.                                 <input type="submit" value="Delete">  
  35.                             </form>  
  36.                         </td>  
  37.                     </tr>  
  38.                 </c:forEach>  
  39.             </table>  
  40.     </c:if>  
  41.     <br><br>  
  42.     <a href="${pageContext.request.contextPath}/restful/add">新增員工</a>  
  43. </body>  
  44. </html>  

Emp.jsp

[html] view plain copy
  1. <%@ page language="java" contentType="text/html; charset=UTF-8"  
  2.     pageEncoding="UTF-8"%>  
  3. <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>  
  4. <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">  
  5. <html>  
  6. <head>  
  7. <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">  
  8. <title>員工資訊</title>  
  9. </head>  
  10. <body>  
  11.     <form action="${pageContext.request.contextPath}/restful/${action}" method="post">  
  12.         <c:if test="${!empty emp}">  
  13.             <input type="hidden" name="_method" value="PUT">  
  14.             <input type="hidden" name="id" value="${emp.id }"><br/><br/>  
  15.         </c:if>  
  16.         <c:if test="${empty emp}">name : <input type="text" name="name" value="${emp.name }"><br/><br/></c:if>  
  17.         email : <input type="text" name="email" value="${emp.email }"><br/><br/>  
  18.         sex :<input type="radio" name="sex" value="0" <c:if test="${emp.sex == 0}">checked</c:if>>男      
  19.         <input type="radio" name="sex" value="1" <c:if test="${emp.sex == 1}">checked</c:if>><br/><br/>  
  20.         department :<select name="department.id">  
  21.             <c:forEach items="${depts }" var="dept">  
  22.                 <option value="${dept.id }" <c:if test="${emp.department.id == dept.id}">selected</c:if>>${dept.name }</option>  
  23.             </c:forEach>  
  24.         </select>  
  25.         <br><br/>  
  26.         <input type="submit" value="提交">  
  27.     </form>  
  28. </body>  
  29. </html>  

1.5. 靜態資源問題

因為配置了DispatcherServlet並且攔截了所有的請求,所以在新增靜態資源的時候會訪問不到靜態資源,springMVC.xml配置

mvc:default-servlet-handler

將在 SpringMVC 上下文中定義一個DefaultServletHttpRequestHandler,它會對進入 DispatcherServlet 的請求進行篩查,如果發現是沒有經過對映的請求,就將該請求交由 WEB應用伺服器預設的 Servlet 處理,如果不是靜態資源的請求,才由DispatcherServlet 繼續處理

mvc:annotation-driven

會自動註冊

RequestMappingHandlerMapping

RequestMappingHandlerAdapter 

ExceptionHandlerExceptionResolver 三個bean

就能訪問到靜態資源了

1.6. mvc:annotation-drivenmvc:default-servlet-handler

在配置SpringMVC配置檔案時新增mvc:annotation-driven

<mvc:annotation-driven /> 會自動註冊三個Bean

² RequestMappingHandlerMapping

² RequestMappingHandlerAdapter 

² ExceptionHandlerExceptionResolver 

還將提供以下支援:

– 支援使用 ConversionService 例項對錶單引數進行型別轉換

– 支援使用 @NumberFormat @DateTimeFormat註解完成資料型別的格式化

– 支援使用 @Valid 註解對 JavaBean 例項進行 JSR 303 驗證

– 支援使用 @RequestBody 和 @ResponseBody 註解






相關文章