SpringMVC - RESTful SpringMVC CRUD

SpringMVC - 5

  • RESTful SpringMVC CRUD
    • demo需求
    • 涉及到的一些操作
      • 1. 处理静态资源
    • demo实现
      • 1. SpringMVC配置文件
      • 2. web.xml配置文件
      • 3. Employee和Department类
      • 4. EmployeeDao和DepartmentDao
      • 5. jsp页面编写
        • 1. index.jsp
        • 2. list.jsp
        • 3. input.jsp
      • 6. EmployeeHandler

RESTful SpringMVC CRUD

demo需求

  1. 显示所有员工信息
  2. 添加所有员工信息
    • 显示添加页面:
      • URI:emp
      • 请求方式:GET
      • 显示效果
        [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Q7EPnuWL-1611913301540)(en-resource://database/678:2)]
    • 添加员工信息:
  3. 删除操作
    • URL:emp/{id}
    • 请求方式:DELETE
    • 删除后效果:对应记录从数据表中删除
  4. 修改操作:lastName不可修改!
    • 显示修改页面:
      • URI:emp/{id}
      • 请求方式:GET
      • 显示效果:回显表单。
    • 修改员工信息:
      • URI:emp
      • 请求方式:PUT
      • 显示效果:完成修改,重定向到 list 页面。[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-yuQho02G-1611913301542)(en-resource://database/680:1)]
  • 相关的类:
    • 实体类:Employee、Department
      Employee Department
      id id
      lastName departmentName
      email
      gender
    • Handler:EmployeeHandler
    • Dao:EmployeeDao、DepartmentDao
  • 相关的页面
    • list.jsp
    • input.jsp
    • edit.jsp
      [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-sbdOO0iK-1611913301544)(en-resource://database/678:2)]

涉及到的一些操作

1. 处理静态资源

  • 优雅的REST风格的资源URL不希望带.html.do等后缀
  • 若将DispatcherServlet请求映射配置为/,则SpringMVC将捕获WEB容器的所有请求,包括静态资源的请求,SpringMVC会将他们当成一个普通请求处理,因找不到对应处理器将导致错误
  • 可以在SpringMVC的配置文件中配置的方式解决静态资源的问题:
    • 将在SpringMVC上下文中定义一个DefaultServletHttpRequestHandler,它会对进入DispatcherServlet的请求进行筛查,如果发现是没有经过映射的请求,就将该请求交友WEB应用服务器默认的Servlet处理,如果不是静态资源的请求,才由DispatcherServlet继续处理
    • 一般WEB应用服务器默认的Servlet的名称都是default。若所使用的WEB服务器的默认Servlet名称不是default,则需要通过default-servlet-name属性显式指定

demo实现

1. SpringMVC配置文件


<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd
        http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">

    
    <context:component-scan base-package="com.luckyazrael.springmvc.crud">context:component-scan>

    
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/WEB-INF/views/">property>
        <property name="suffix" value=".jsp">property>
    bean>
    
    <mvc:default-servlet-handler/>
    <mvc:annotation-driven>mvc:annotation-driven>
beans>

2. web.xml配置文件


<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0">
    
    <servlet>
        <servlet-name>springDispatchServletservlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServletservlet-class>
        <init-param>
            <param-name>contextConfigLocationparam-name>
            <param-value>classpath:springmvc.xmlparam-value>
        init-param>
        <load-on-startup>1load-on-startup>
    servlet>
    <servlet-mapping>
        <servlet-name>springDispatchServletservlet-name>
        <url-pattern>/url-pattern>
    servlet-mapping>
    
    
    <filter>
        <filter-name>HiddenHttpMethodFilterfilter-name>
        <filter-class>org.springframework.web.filter.HiddenHttpMethodFilterfilter-class>
    filter>
    <filter-mapping>
        <filter-name>HiddenHttpMethodFilterfilter-name>
        <url-pattern>/*url-pattern>
    filter-mapping>
web-app>

3. Employee和Department类

见上方表格

4. EmployeeDao和DepartmentDao

省略了与数据库交互的内容,重点不在数据库操作,so…从简

@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,"E-AA","[email protected]",1,new Department(101,"D-AA")));
        employees.put(1002,new Employee(1002,"E-BB","[email protected]",1,new Department(102,"D-BB")));
        employees.put(1003,new Employee(1003,"E-CC","[email protected]",0,new Department(103,"D-CC")));
        employees.put(1004,new Employee(1004,"E-DD","[email protected]",0,new Department(104,"D-DD")));
        employees.put(1005,new Employee(1005,"E-EE","[email protected]",1,new Department(105,"D-EE")));
    }

    /**
     * 若新增员工,该员工的id为initId
     */
    private static Integer initId = 1006;

    /**
     * 新增员工信息
     * @param employee
     */
    public void save(Employee employee){
        if (employee.getId() == null){
            employee.setId(initId++);
        }
        employee.setDepartment(departmentDao.getDepartment(employee.getDepartment().getId()));
        employees.put(employee.getId(),employee);
    }
    /**
     * 获取(查询)所有员工信息
     * @return
     */
    public Collection<Employee> getAll(){
        return employees.values();
    }
    /**
     * 根据员工id获取(查询)员工的信息
     * @param id
     * @return
     */
    public Employee get(Integer id){
        return employees.get(id);
    }
    /**
     * 根据员工id删除员工信息
     * @param 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,"D-AA"));
        departments.put(102,new Department(102,"D-BB"));
        departments.put(103,new Department(103,"D-CC"));
        departments.put(104,new Department(104,"D-DD"));
        departments.put(105,new Department(105,"D-EE"));
    }
    /**
     * 获取全部的Departments
     * @return
     */
    public Collection<Department> getDepartments(){
        return departments.values();
    }

    /**
     * 根据id获取对应的Department
     * @param id
     * @return
     */
    public Department getDepartment(Integer id){
        return departments.get(id);
    }
}

5. jsp页面编写

1. index.jsp

<body>
<a href="emps">List All Employeesa>
body>

2. list.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head>
    <title>listtitle>
    <%--
    SpringMVC 处理静态资源:
     1. 为什么会有这样的问题:
     优雅的REST风格的资源URL不希望带 .html 或 .do 等后缀
     若将DispatcherServlet请求映射配置为 / ,
     则SpringMVC将捕获WEB容器的所有请求,包括静态资源的请求,SpringMVC会将他们当成一个普通请求处理,
     因找不到对应处理器将导致错误
     2. 解决:在SpringMVC的配置文件中配置<mvc:default-servlet-handler/>
     --%>
    <script type="text/javascript" src="script/jquery-1.7.2.js">script>
    <script type="text/javascript">
        $(function () {
            $(".delete").click(function () {
                var href = $(this).attr("href")
                $("form").attr("action",href).submit();
                return false;
            });
        })
    script>
head>
<body>

    <form action="" method="post">
        <input type="hidden" name="_method" value="DELETE"/>
    form>
    <c:if test="${empty requestScope.employees }">
        没有任何员工信息。
    c:if>
    <c:if test="${!empty requestScope.employees }">
        <table border="1" cellpadding="10" cellspacing="0">
            <tr>
                <th>IDth>
                <th>LastNameth>
                <th>Emailth>
                <th>Genderth>
                <th>Departmentth>
                <th>Editth>
                <th>Deleteth>
            tr>

            <c:forEach items="${requestScope.employees}" var="emp">
                <tr>
                    <td>${emp.id}td>
                    <td>${emp.lastName}td>
                    <td>${emp.email}td>
                    <td>${emp.gender == 0 ? 'Female':'Male'}td>
                    <td>${emp.department.departmentName}td>
                    <td><a href="emp/${emp.id}">Edita> td>
                    <td><a class="delete" href="emp/${emp.id}">Deletea>td>
                tr>
            c:forEach>
        table>
    c:if>
    <br><br>
    <a href="emp">Add New Employeea>
body>
html>

3. input.jsp

使用Spring的表单标签

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

form标签

  • 一般情况下,通过GET请求获取表单页面,而通过POST请求提交表单页面,因此获取表单页面和提交表单页面的URL是相同的只要满足该最佳条件的契约,form:form 标签就无需通过action属性指定表单提交的URL
  • 可以通过modelAttribute属性指定绑定的模型属性,若没有指定该属性,则默认从request域对象中读取command的表单bean,如果该属性值夜幕存在,则会发生错误。

表单标签

  • SpringMVC提供了多个表单组件标签,如等,用以绑定表单字段的属性值,他们的共有属性如下:
    • path:表单字段,对应html元素的name属性,支持级联属性
    • htmlEscape:是否对表单值的HTML特殊字符进行转换,默认为true
    • cssClass:表单组件对应的CSS样式类名
    • cssErrorClass:表单组件的数据存在错误时,采取的CSS样式
  • form:inputform:passwordform:hiddenform:textarea:对应HTML表单的text、password、hidden、textarea标签
  • form:radiobutton:单选框组件标签,当表单bean对应的属性值和value值相等时,单选框被选中
  • form:radiobuttons:单选框组标签,用于构造多个单选框
    • items:可以使一个List、String[]或Map
    • itemvalue:指定radio的value值。可以是集合中bean的一个属性值
    • itemLabel:指定radio的label值
    • delimiter:多个单选框可以通过delimiter指定分隔符
  • form:checkbox:复选框组件。用于构造单个复选框
  • form:checkboxs:用于构造多个复选框。使用方法同form:radiobuttons标签
  • form:select:用于构造下拉框组件。使用方法同form:radiobuttons标签
  • form:option:下拉框选项组件标签。使用方法同form:radiobuttons标签
  • form:errors:显示表单组件或数据校验所对应的错误
    • :显示表单所有的错误
    • :显示所有以user为前缀的属性对应的错误
    • :显示特定表单对象属性的错误
<%@ page import="java.util.Map" %>
<%@ page import="java.util.HashMap" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head>
    <title>inputtitle>
head>
<body>
    <%--
        1. 为什么要使用SpringMVC的form标签?
            可以更快速的开发出表单页面,而且可以更方便的进行表单值的回显
        2. 注意:可以通过 modelAttribute 属性指定绑定的模型属性,
        若没有指定该属性,则默认从request域对象中读取command的表单bean,
        如果该属性值也不存在,则会发生错误。
    --%>
    <form:form action="${pageContext.request.contextPath}/emp" method="POST" modelAttribute="employee">
        <%-- path属性对应html 表单标签中的name属性值 --%>
        <c:if test="${employee.id == null}">
        LastName:<form:input path="lastName" />
        c:if>
        <c:if test="${employee.id != null}">
            <form:hidden path="id"/>
            <%--对于_method 不能使用form:hidden标签,因为modelAttribute 对应的bean中没有_method 这个属性--%>
            <%-- <form:hidden path="_method" value="PUT" --%>
            <input type="hidden" name="_method" value="PUT"/>
        c:if>
        <br>
        Email:<form:input path="email" /> <br>
        <%
            Map<String,String> genders = new HashMap<>();
            genders.put("0","Female");
            genders.put("1","Male");
            request.setAttribute("genders",genders);
        %>
        Gender:<form:radiobuttons path="gender" items="${genders}"/> <br>
        Department:<form:select path="department.id" items="${departments}" itemLabel="departmentName" itemValue="id"/><br>
        <input type="submit" value="Submit"/>
    form:form>
body>
html>

6. EmployeeHandler

@Controller
public class EmployeeHandler {
    @Autowired
    private EmployeeDao employeeDao;

    @Autowired
    private DepartmentDao departmentDao;

    @ModelAttribute
    public void getEmployee(@RequestParam(value = "id",required = false) Integer id,Map<String,Object> map){
        if (id != null){
            map.put("employee",employeeDao.get(id));
        }
    }

    @RequestMapping(value = "/emp",method = RequestMethod.PUT)
    public String update(Employee employee){
        employeeDao.save(employee);
        return "redirect:/emps";
    }

    @RequestMapping(value = "/emp/{id}",method = RequestMethod.GET)
    public String input(@PathVariable("id") Integer id,Map<String,Object> map){
        map.put("employee",employeeDao.get(id));
        map.put("departments",departmentDao.getDepartments());
        return "input";
    }

    /**
     * 执行删除的操作
     * @param id
     * @return
     */
    @RequestMapping(value = "/emp/{id}",method = RequestMethod.DELETE)
    public String delete(@PathVariable("id") Integer id){
        employeeDao.delete(id);
        return "redirect:/emps";
    }
    /**
     * 执行添加操作并重定向到list页面
     * @param employee
     * @return
     */
    @RequestMapping(value = "/emp",method = RequestMethod.POST)
    public String save(Employee employee){
        employeeDao.save(employee);
        return "redirect:/emps";
    }
    /**
     * 跳转到添加员工信息的操作页面
     * @param map
     * @return
     */
    @RequestMapping(value = "/emp",method = RequestMethod.GET)
    public String input(Map<String,Object> map){
        map.put("departments",departmentDao.getDepartments());
        map.put("employee",new Employee());
        return "input";
    }

    /**
     * 跳转到list页面,并显示所有的员工信息
     * @param map
     * @return
     */
    @RequestMapping("/emps")
    public String list(Map<String,Object> map){
        map.put("employees",employeeDao.getAll());
        return "list";
    }
}

你可能感兴趣的:(笔记,springmvc,java)