第八章 RESTRUL_CRUD
map迭代器代码
https://www.cnblogs.com/zhaoguhong/p/7074597.html?utm_source=itdadao&utm_medium=referral
增删改查 CURD的URL地址 /资源/资源标识
C:create
R:retrieve
U:update
D:delete
/emp/1 GET:查询id为1的员工
/emp/1 PUT:更新id为1的员工
/emp/1 DELETE:删除id为1的员工
/emp POST:新增员工
实验代码 下面代码将在基础上修改
Book的代码
public class Book { private String bookName; private String id; }
web.xml的配置
<!-- The front controller of this Spring Web application, responsible for handling all application requests --> <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> <!-- Map all requests to the DispatcherServlet for handling --> <servlet-mapping> <servlet-name>springDispatcherServlet</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping> <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>
springmvc.xml的配置
<context:component-scan base-package="com.project"/> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="prefix" value="/WEB-INF/jsp/"></property> <property name="suffix" value=".jsp"></property> </bean>
效果
BookDao的代码
@Repository public class BookDao { private static HashMap<Integer,Book> hm = new HashMap<Integer,Book>(); static { hm.put(1,new Book("1","西瓜书")); hm.put(2,new Book("2","java编程思想")); hm.put(3,new Book("3","算法导论")); hm.put(4,new Book("4","算法")); } public List<Book> getAll() { List<Book> ls = new ArrayList<Book>(); for (Entry<Integer, Book> entry : hm.entrySet()) { ls.add(entry.getValue()); } return ls; } public Book getBookById(Integer id) { return hm.get(id); } public void deleteBookById(Integer id) { hm.remove(id); } public void updateBookById(Integer id,String bookName) { hm.get(id).setBookName(bookName); } public void addBook(String bookName,Integer Id) { Book book = new Book(Id+"",bookName); hm.put(Id, book); } }
Controller的代码
第一版本 @Controller public class MyController { @Autowired private BookDao bookDao; @RequestMapping(value="/book",method=RequestMethod.GET) public String getAllBookHandle(Model mv) { System.out.println("getAllBookHandle..."); mv.addAttribute("bookList", bookDao.getAll()); return "restfulTest"; } @RequestMapping(value="/book",method=RequestMethod.GET) public String getBookById(@PathVariable("bid") Integer id,Model mv) { mv.addAttribute("bookList", bookDao.getBookById(id)); System.out.println("getBookById..."+id); return "restfulTest"; } @RequestMapping(value="/book/",method=RequestMethod.PUT) public String updateBookById(@PathVariable("bid") Integer id,Book book) { bookDao.updateBookById(id, book.getBookName()); System.out.println("updateBookById..."+id); return "restfulTest"; } @RequestMapping(value="/book",method=RequestMethod.DELETE) public String deleteBookById(@PathVariable("bid") Integer id) { System.out.println("deleteBookById..."+id); return "restfulTest"; } @RequestMapping(value="/book",method=RequestMethod.POST) public String setBook(Book book) { System.out.println("setBook..."); return "restfulTest"; } }
hello.jsp页面 第一版本
《%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" isErrorPage="true"%> 《%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %> 《body> 《h1>hello页面《/h1> 获取所有的书本 《a href="book">所有的书本《/a> 《br> 添加书本 《form action="/book" method="post"> 书的Id:《input type="text" name="id"/> 书的名称:《input type="text" name="bookName"/> 《input type="submit" value="提交"/> 《/form> 《br> 修改某id的书本信息 《form action="/book" method="post"> 《input name="_method" value="put" type="hidden"> 书的Id:《input type="text" name="id"/> 书的名称:《input type="text" name="bookName"/> 《input type="submit" value="提交"/> 《/form> 《br> 查找某id的书本 《form action="/book" method="GET"> 书的Id:《input type="text" name="id"/> 书的名称:《input type="text" name="bookName"/> 《input type="submit" value="提交"/> 《/form> 《br> 删除某id的书本 《form action="/book" method="post"> 《input name="_method" value="delete" type="hidden"> 书的Id:《input type="text" name="id"/> 《input type="submit" value="提交"/> 《/form> 《br>
restful接收数据页面
《body> 《table> 《tr> 《th>bookId《/th> 《th>bookName《/th> 《/tr> 《c:forEach items="${bookList}" var="book">《!-- ${requestScope.bookList} --> 《tr> 《td>${book.id}《/td> 《td>${book.bookName}《/td> 《td>Edit《/td> 《td>Delete《/td> 《/tr> 《/c:forEach> 《/table> 《/body>
采用SpringMVC表单标签
- 为什么使用SpringMVC的form标签
快速开发
表单回显 - 可以通过modelAttribute指定绑定的模型属性,
若没有指定该属性,则默认从request域中查找command的表单的bean
如果该属性也不存在,那么,则会发生错误。
使用spring的表单标签
通过 SpringMVC 的表单标签可以实现将模型数据中的属性和 HTML 表单元素相绑定,以实现表单数据更便捷编辑和表单值的回显
form 标签
- 一般情况下,通过 GET 请求获取表单页面,而通过 POST 请求提交表单页面,因此获取表单页面和提交表单页面的 URL 是相同的。
- 只要满足该最佳条件的契约,《form:form> 标签就无需通过 action 属性指定表单提交的 URL
- 可以通过 modelAttribute 属性指定绑定的模型属性,若没有指定该属性,则默认从 request 域对象中读取 command 的表单 bean,如果该属性值也不存在,则会发生错误。
《!-- path就是原来html-input的name项,需要写path path: 1. 当作原生的name项 2.自动登陆隐含模型中某个对象对应的属性值 --> 《form:form action=""> 书名:《form:input path="bookName"/> 书id:《form:input path="id"/> 单选按钮 男:《form:radiobutton path="sex" value="1"/> 女:《form:radiobutton path="sex" value="0"/> 下拉列表《!-- 如department[id,departmentName] items="":指定要遍历的集合:自动遍历,遍历处的每一个元素是一个department对象 itemLabel="属性名":指定遍历出的这个对象的哪个属性是作为opyion标签的值 itemValue="属性名":指定刚才遍历出来的这个对象的哪个属性作为要提交的value值 --> dept:《form:select path="department.id" items="${depts}" itemLabel="departmentName" itemValue="id"/> 《input type="submit" value="提交"/> 《/form:form>
SpringMVC 提供了多个表单组件标签,如 《form:input/>、《form:select/> 等,用以绑定表单字段的属性值,它们的共有属性如下:
- path:表单字段,对应 html 元素的 name 属性,支持级联属性
- htmlEscape:是否对表单值的 HTML 特殊字符进行转换,默认值为 true
- cssClass:表单组件对应的 CSS 样式类名
- cssErrorClass:表单组件的数据存在错误时,采取的 CSS 样式
form:input、form:password、form:hidden、form: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:显示表单组件或数据校验所对应的错误
- 《form:errors path= “*” /> :显示表单所有的错误
- 《form:errors path= “user*” /> :显示所有以 user 为前缀的属性对应的错误
- 《form:errors path= “username” /> :显示特定表单对象属性的错误
运行出错
出错一:在含有spring的表单标签 直接运行jsp页面 就会报错
出错二:通过请求访问jsp页面 但报错command
用了表单便签的页面可能会报这个错误
原因:
SpringMVC认为,表单数据中的每一项最终都要回显的
path指定的是一个属性,这个属性是从隐含模型(请求域中取出的某个对象中的属性);
path指定的每一个属性,请求域中必须有一个对象,拥有这个属性;这个对象就是请求域中的command
《form:form action=""> 书名:《form:input path="bookName"/> 书id:《form:input path="id"/> 《input type="submit" value="提交"/> 《/form:form> @RequestMapping("/hello") -> hello.jsp页面 public String toHelloJsp(Model model) { model.addAttribute("command",new Book("123", "java"));-->回显到页面 return "hello"; }
能不能修改别去command找:modelAttribute="studentModel"
- 以前我们表单标签会从请求域中获取一个command对象;把这个对象中的每一个属性对应的显示出来
- 可以告诉springMvc不要去取command的值,用modelAttribute指定的值来取代,如studentModel,每一个属性都得有不然会报错 如加了author
添加后效果
修改信息步骤:先点击修改 然后回显当行数据【查出要修改的信息,放到请求域中】,来到修改页面
发送到目标页面的问题 处理不好 后面改为return "redirect:/book";
效果
但是出现了 没传就为null 可以弄一个input hidden标签【但是在F12里面可以看到并修改隐藏于的信息 将一些null值通过modelAttribute来解决】
所以要用modelAttribute
@ModelAttribute//提前插一步 任何方法前都会运行 //路径变量@PathVariable public void myModelAttribute(@RequestParam(value="id",required = false) Integer id ,Model model) {//请求参数带id if(id!=null) {//最重要的一步 System.out.println("@ModelAttribute:ID"+id); Book book = bookDao.getBookById(id); model.addAttribute("book",book); } }
删除
《td> 《form:form action="${ctp}/book/${book.id}" method="post"> 《input type="hidden" name="_method" value="DELETE"/> 《input type="submit" value="删除"/> 《/form:form> 《/td> /** * 利用id删除书本 */ @RequestMapping(value="/book/{bid}",method=RequestMethod.DELETE) public String deleteBookById(@PathVariable("bid") Integer id) { bookDao.deleteBookById(id); System.out.println("deleteBookById..."+id); return "redirect:/book"; }
利用jq来帮忙提交表单
《script src="http://code.jquery.com/jquery-latest.js"/>
HiddenHttpMethodFilter过滤器在RestFul中的作用
发起请求,无法执行,因为delete请求必须通过post请求转换为delete请求,借助:HiddenHttpMethodFilter过滤器
JQuery404了
默认前端控制器是拦截所有资源(除过jsp)、js文件就404:要js文件的请求是交给tomcat处理《mvc:default-servlet-handler/>【告诉springmvc 自己映射的请求就自己处理,不能处理的请求直接交给tomcat】
《script src="http://code.jquery.com/jquery-latest.js"/> 这样引用就没有出现问题 但是文件导入就会出现问题 《script src="/js/jquery-1.9.1.min.js"/> 注解 <mvc:default-servlet-handler/> 静态资源 <mvc:annotation-driven/> 动态资源
开启第一个注解后
第二个注解没有打开book这些请求
两个注解都开启
需要使用jQuery来转换请求方式
解决办法,SpringMVC 处理静态资源
SpringMVC 处理静态资源:
- 为什么会有这样的问题:
优雅的 REST 风格的资源URL 不希望带 .html 或 .do 等后缀
若将 DispatcherServlet 请求映射配置为 /,
则 Spring MVC 将捕获 WEB 容器的所有请求, 包括静态资源的请求, SpringMVC 会将他们当成一个普通请求处理,
因找不到对应处理器将导致错误。 - 解决: 在 SpringMVC 的配置文件中配置 《mvc:default-servlet-handler/>
配置后,原来的请求又不好使了
需要配置《mvc:annotation-driven />
关于《mvc:default-servlet-handler/>作用
<!-- <mvc:default-servlet-handler/> 将在 SpringMVC 上下文中定义一个 DefaultServletHttpRequestHandler, 它会对进入 DispatcherServlet 的请求进行筛查,如果发现是没有经过映射的请求, 就将该请求交由 WEB 应用服务器默认的 Servlet 处理,如果不是静态资源的请求,才由 DispatcherServlet 继续处理 一般 WEB 应用服务器默认的 Servlet 的名称都是 default。 若所使用的 WEB 服务器的默认 Servlet 名称不是 default,则需要通过 default-servlet-name 属性显式指定 参考: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> 该标签属性default-servlet-name默认值是"default",可以省略。 <mvc:default-servlet-handler/> --> <mvc:default-servlet-handler default-servlet-name="default"/>
通过jQuery转换为DELETE请求
《td>《a href="empDelete/${emp.id }" class="delete">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>
RESTRUL_CRUD_修改操作