Chapter 7 comprehensive case
7.1 restrl? Crud? Requirements
7.1.1 display all employee information
- URI: emps
- Request method: GET
- Display effect
7.1.2 add operation - go to add page
- Show add page:
- URI: emp
- Request method: GET
- Display effect
7.1.3 add operation - add employee
- Add employee information:
- URI: emp
- Request method: POST
- Display effect: finish adding and redirect to the list page.
7.1.4 delete
- URL: emp/{id}
- Request method: DELETE
- Effect after deletion: delete the corresponding record from the data table
7.1.5 modify - go to modify page
- URI: emp/{id}
- Request method: GET
- Display effect: echo the form.
7.1.6 modify - modify employee
- URI: emp
- Request mode: PUT
- Display effect: finish the modification and redirect to the list page.
7.1.7 related categories
Service layer is omitted for teaching convenience
- Entity class: Employee, Department
- Handler: EmployeeHandler
- Dao: EmployeeDao,DepartmentDao
7.1.8 relevant pages
- list.jsp
- input.jsp
- edit.jsp
7.2 build development environment
- Copy jar package
com.springsource.net.sf.cglib-2.2.0.jar com.springsource.org.aopalliance-1.0.0.jar com.springsource.org.aspectj.weaver-1.6.8.RELEASE.jar spring-aop-4.0.0.RELEASE.jar spring-aspects-4.0.0.RELEASE.jar commons-logging-1.1.3.jar spring-beans-4.0.0.RELEASE.jar spring-context-4.0.0.RELEASE.jar spring-core-4.0.0.RELEASE.jar spring-expression-4.0.0.RELEASE.jar spring-jdbc-4.0.0.RELEASE.jar spring-orm-4.0.0.RELEASE.jar spring-tx-4.0.0.RELEASE.jar spring-web-4.0.0.RELEASE.jar spring-webmvc-4.0.0.RELEASE.jar
- Create configuration file: add context,mvc,beans namespace to springmvc.xml.
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:mvc="http://www.springframework.org/schema/mvc" xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd"> <!-- To configure a scanned package: com.atguigu.springmvc.crud --> <context:component-scan base-package="com.atguigu.springmvc"/> <!-- Configure view resolver: forward by default --> <bean id="internalResourceViewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="prefix" value="/WEB-INF/views/"/> <property name="suffix" value=".jsp"></property> </bean> </beans>
- Configure core controller: web.xml
<servlet> <servlet-name>springDispatcherServlet</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:springmvc.xml</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>springDispatcherServlet</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping>
- Convert a POST request to a PUT or DELETE request
<filter> <filter-name>HiddenHttpMethodFilter</filter-name> <filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class> </filter> <filter-mapping> <filter-name>HiddenHttpMethodFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
- Create related pages
/WEB-INF/views/list.jsp index.jsp
- Add entity class
- Increase DAO class
@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", "aa@163.com", 1, new Department(101, "D-AA"))); employees.put(1002, new Employee(1002, "E-BB", "bb@163.com", 1, new Department(102, "D-BB"))); employees.put(1003, new Employee(1003, "E-CC", "cc@163.com", 0, new Department(103, "D-CC"))); employees.put(1004, new Employee(1004, "E-DD", "dd@163.com", 0, new Department(104, "D-DD"))); employees.put(1005, new Employee(1005, "E-EE", "ee@163.com", 1, new Department(105, "D-EE"))); } private static Integer initId = 1006; public void save(Employee employee){ if(employee.getId() == null){ employee.setId(initId++); } 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 LinkedHashMap<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")); } public Collection<Department> getDepartments(){ return departments.values(); } public Department getDepartment(Integer id){ return departments.get(id); } }
7.3 display all employee information
- Add page link
<a href="empList">To Employee List</a>
- Add processor
@Controller public class EmployeeHandler { @Autowired private EmployeeDao employeeDao ; @RequestMapping("/empList") public String empList(Map<String,Object> map){ map.put("empList", employeeDao.getAll()); //Store in request domain by default return "list"; } }
- For tags not traversed in spring MVC, you need to use jstl tags for collection traversal to add jstl tag library jar package
<%@ 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> <c:if test="${empty requestScope.empList }"> Sorry, no employees found! </c:if> <c:if test="${!empty requestScope.empList }"> <table border="1" cellpadding="10" cellspacing="0"> <tr> <td>EmpId</td> <td>LastName</td> <td>Gender</td> <td>Email</td> <td>DepartmentName</td> <td>Edit</td> <td>Delete</td> </tr> <c:forEach items="${requestScope.empList }" var="emp"> <tr> <td>${emp.id }</td> <td>${emp.lastName }</td> <td>${emp.gender==0?"Female":"Male" }</td> <td>${emp.email }</td> <td>${emp.department.departmentName }</td> <td><a href="">Edit</a></td> <td><a href="">Delete</a></td> </tr> </c:forEach> </table> </c:if> </body> </html>
7.4 add restul CRUD
- Add connection to list.jsp
<a href="empInput">Add Employee</a>
- Add processor method
@RequestMapping(value="/empInput",method= RequestMethod.GET) public String empInput(Map<String,Object> map){ map.put("deptList", departmentDao.getDepartments()); //Troubleshooting error: java.lang.IllegalStateException: Neither BindingResult nor plain target object for bean name 'command' available as request attribute Employee employee = new Employee(); //map.put("command", employee); map.put("employee", employee); return "add"; }
- Show add page
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" import="java.util.*"%> <%@ 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> </head> <body> <!-- 1.Why use SpringMVC Of form Label ① Rapid development ② Form echo display 2.Can pass modelAttribute Specifies the model properties of the binding, //If this property is not specified, the bean of the form that looks up the command from the request field by default //If the property also does not exist, an error occurs. --> <form:form action="empAdd" method="POST" modelAttribute="employee"> LastName : <form:input path="lastName"/><br><br> Email : <form:input path="email"/><br><br> <% Map<String,String> map = new HashMap<String,String>(); map.put("1", "Male"); map.put("0","Female"); request.setAttribute("genders", map); %> Gender : <br><form:radiobuttons path="gender" items="${genders }" delimiter="<br>"/><br><br> DeptName : <form:select path="department.id" items="${deptList }" itemLabel="departmentName" itemValue="id"></form:select><br><br> <input type="submit" value="Submit"><br><br> </form:form> </body> </html>
- When the form information is displayed, an error will be reported:
HTTP Status 500 - type Exception report message description The server encountered an internal error () that prevented it from fulfilling this request. exception org.apache.jasper.JasperException: An exception occurred processing JSP page /WEB-INF/views/add.jsp at line 18 15: ② Form echo display 16: --> 17: <form:form action="empAdd" method="POST"> 18: LastName : <form:input path="lastName"/> 19: Email : <form:input path="email"/> 20: <% 21: Map<String,String> map = new HashMap<String,String>(); Stacktrace: org.apache.jasper.servlet.JspServletWrapper.handleJspException(JspServletWrapper.java:505) org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:410) org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:337) org.apache.jasper.servlet.JspServlet.service(JspServlet.java:266) javax.servlet.http.HttpServlet.service(HttpServlet.java:803) org.springframework.web.servlet.view.InternalResourceView.renderMergedOutputModel(InternalResourceView.java:209) org.springframework.web.servlet.view.AbstractView.render(AbstractView.java:266) org.springframework.web.servlet.DispatcherServlet.render(DispatcherServlet.java:1225) org.springframework.web.servlet.DispatcherServlet.processDispatchResult(DispatcherServlet.java:1012) org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:959) org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:876) org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:931) org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:822) javax.servlet.http.HttpServlet.service(HttpServlet.java:690) org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:807) javax.servlet.http.HttpServlet.service(HttpServlet.java:803) org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:77) org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:108) root cause java.lang.IllegalStateException: Neither BindingResult nor plain target object for bean name 'command' available as request attribute org.springframework.web.servlet.support.BindStatus.<init>(BindStatus.java:141)
7.5 using Spring's form tags
- Through the form tag of spring MVC, the attributes in the model data can be bound with HTML form elements, so that the form data can be edited more easily and the form value can be echoed
- form tags
- In general, GET request is used to GET the form page, and POST request is used to submit the form page, so the URL of getting the form page and submitting the form page is the same.
- As long as the contract meets the best conditions,form:form The tag does not need to specify the URL of the form submission through the action attribute
- You can specify the bound model attribute through the modelAttribute attribute. If you do not specify this attribute, the command's form bean will be read from the request domain object by default. If the attribute value does not exist, an error will occur.
- Spring MVC provides multiple form component tags, such as form:input/,form:select/ To bind the property values of form fields, their common properties are as follows:
- path: form field, corresponding to the name attribute of html element, supporting cascade attribute
- htmlEscape: whether to convert the HTML special characters of the form value. The default value is true
- cssClass: CSS style class name corresponding to form component
- cssErrorClass: CSS style adopted when data of form component is wrong
- form:input, form:password, form:hidden, form:textarea: text, password, hidden, textarea tags corresponding to HTML forms
- form:radiobutton: radio box component label. When the attribute value of the form bean is equal to the value value, the radio box is selected
- form:radiobuttons: radio box group label, used to construct multiple radio boxes
- items: can be a List, String [] or Map
- itemValue: Specifies the value value of radio. Can be a property value of a bean in a collection
- itemLabel: Specifies the label value of radio
- Delimiter: multiple radio boxes can be specified with delimiter
- form:checkbox: a checkbox component. Use to construct a single check box
- form:checkboxs: used to construct multiple checkboxes. Use the same way as form:radiobuttons label
- form:select: used to construct the drop-down box component. Use the same way as form:radiobuttons label
- form:option: drop-down box option component label. Use the same way as form:radiobuttons label
- form:errors: display errors corresponding to form components or data validation
- < form: errors path = "*" / >
- < form: errors path = "user *" / >
- < form: errors path = "username" / >: display errors for specific form object properties
7.6 add employee experiment code
- form
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" import="java.util.*"%> <%@ 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> </head> <body> <!-- 1.Why use SpringMVC Of form Label ① Rapid development ② Form echo display 2.Can pass modelAttribute Specifies the model properties of the binding, //If this property is not specified, the bean of the form that looks up the command from the request field by default //If the property also does not exist, an error occurs. --> <form:form action="empAdd" method="POST" modelAttribute="employee"> LastName : <form:input path="lastName" /><br><br> Email : <form:input path="email" /><br><br> <% Map<String,String> map = new HashMap<String,String>(); map.put("1", "Male"); map.put("0","Female"); request.setAttribute("genders", map); %> Gender : <br><form:radiobuttons path="gender" items="${genders }" delimiter="<br>"/><br><br> DeptName : <form:select path="department.id" items="${deptList }" itemLabel="departmentName" itemValue="id"></form:select><br><br> <input type="submit" value="Submit"><br><br> </form:form> </body> </html>
- Controller method
@Controller public class EmployeeHandler { @RequestMapping(value="/empAdd",method=RequestMethod.POST) public String empAdd(Employee employee){ employeeDao.save(employee); return "redirect:/empList"; } }
7.7 delete & process static resources
7.7.1 delete experiment code
- Page link
<td><a href="/empDelete/${emp.id }">Delete</a></td>
- Controller method
@RequestMapping(value="/empDelete/{id}" ,method=RequestMethod.DELETE) public String empDelete(@PathVariable("id") Integer id){ employeeDao.delete(id); return "redirect:/empList"; }
7.7.2 HiddenHttpMethodFilter
The request is initiated and cannot be executed, because the delete request must be converted to the delete request through the post request with the help of: HiddenHttpMethodFilter filter
7.7.3 need to use jQuery to transform request mode
- Add jQuery library file
/scripts/jquery-1.9.1.min.js
- jQuery library file does not work
Warning: No mapping found for HTTP request with URI [/SpringMVC 03 RESTFul CRUD/scripts/jquery-1.9.1.min.js] in DispatcherServlet with name'springDispatcherServlet'
3. Solution: Spring MVC deals with static resources
① Why is there such a problem
Elegant REST style resource URL s do not want to have suffixes such as. html or. Do. If the dispatcher servlet request mapping is configured as /, then spring MVC will capture all requests of WEB containers, including static resource requests. Spring MVC will treat them as a common request, because it will cause an error if no corresponding processor is found.
② Solution: configure in the configuration file of spring MVC mvc:default-servlet-handler/
4. After configuration, the original request is not easy to use
Need to configure < MVC: annotation driven / >
7.7.4 about < MVC: default servlet handler / > function
<!-- < MVC: default servlet handler / > a DefaultServletHttpRequestHandler will be defined in the context of spring MVC, It will screen the requests entering the dispatcher servlet. If it is found that the requests are unmapped, The request will be submitted to the default Servlet of the WEB application server for processing. If it is not a static resource request, the dispatcher Servlet will continue to process it In general, the default Servlet name of WEB application server is default. If the default Servlet name of the WEB server you are using is not default, you need to explicitly specify it through the default Servlet name attribute Reference: Catalina · home / config / web.xml <servlet> <servlet-name>default</servlet-name> <servlet-class>org.apache.catalina.servlets.DefaultServlet</servlet-class> <init-param> <param-name>debug</param-name> <param-value>0</param-value> </init-param> <init-param> <param-name>listings</param-name> <param-value>false</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> The default value of the tag attribute default servlet name is "default", which can be omitted. <mvc:default-servlet-handler/> --> <mvc:default-servlet-handler default-servlet-name="default"/>
7.7.5 converting to DELETE request through jQuery
<td><a class="delete" href="empDelete/${emp.id }">Delete</a></td>
<form action="" method="post"> <input type="hidden" name="_method" value="DELETE"/> </form>
<script type="text/javascript" src="scripts/jquery-1.9.1.min.js"></script> <script type="text/javascript"> $(function(){ $(".delete").click(function(){ var href = $(this).attr("href"); $("form").attr("action",href).submit(); return false ; }); }); </script>
7.7.6 delete operation flow diagram
7.8 modify
7.8.1 query employee object according to id and echo the form
- Page link
<td><a href="empEdit/${emp.id }">Edit</a></td>
- Controller method
//Modify employee - form echo @RequestMapping(value="/empEdit/{id}",method=RequestMethod.GET) public String empEdit(@PathVariable("id") Integer id, Map<String,Object> map){ map.put("employee", employeeDao.get(id)); map.put("deptList",departmentDao.getDepartments()); return "edit"; }
- Modify page
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" import="java.util.*"%> <%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %> <%@ 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> <!-- 1.Why use SpringMVC Of form Label ① Rapid development ② Form echo display 2.Can pass modelAttribute Specifies the model properties of the binding, //If this property is not specified, the bean of the form that looks up the command from the request field by default //If the property also does not exist, an error occurs. //To modify the function, you need to add an absolute path. The relative path will report an error. The path is not correct --> <form:form action="${pageContext.request.contextPath }/empUpdate" method="POST" modelAttribute="employee"> <%-- LastName : <form:input path="lastName" /><br><br> --%> <form:hidden path="id"/> <input type="hidden" name="_method" value="PUT"> <%-- Don't use it here form:hidden Tag, otherwise an error will be reported. <form:hidden path="_method" value="PUT"/> Spring No value Properties, while,path The specified value does not exist in the model object(_method),So an error will be reported during echo. org.springframework.beans.NotReadablePropertyException: Invalid property '_method' of bean class [com.atguigu.springmvc.crud.entities.Employee]: Bean property '_method' is not readable or has an invalid getter method: Does the return type of the getter match the parameter type of the setter? --%> Email : <form:input path="email" /><br><br> <% Map<String,String> map = new HashMap<String,String>(); map.put("1", "Male"); map.put("0","Female"); request.setAttribute("genders", map); %> Gender : <br><form:radiobuttons path="gender" items="${genders }" delimiter="<br>"/><br><br> DeptName : <form:select path="department.id" items="${deptList }" itemLabel="departmentName" itemValue="id"></form:select><br><br> <input type="submit" value="Submit"><br><br> </form:form> </body> </html>
7.8.2 submit form and modify data
- Controller method
@RequestMapping(value="/empUpdate",method=RequestMethod.PUT) public String empUpdate(Employee employee){ employeeDao.save(employee); return "redirect:/empList"; }