springmvc实现数据获取-列表显示-重定向等
三大框架
- web前端部分:
主要成员:html,css,js(前三者负责页面样式),servlet(主要负责传输“指令”)
框架:springmvc - 业务层:
特点:复杂度高,并发量大,业务层次多,正确率要求高
主要成员:domain,service
框架:EJB、Spring - 持久化层:负责数据存储
主要成员:dao
框架:mybatis、“冬眠”等 - 上述三者结合,即——SSM
表单页面注意事项
- 表单中标签的“name”全部都要修改为和Java实体中定义的相同
- 重定向
return "redirect:/路径"即可
表单提交方式
- GET提交
使用地址栏访问时即为GET提交
GET提交传递的信息量较小
使用GetMapping(“映射地址”)来指定控制器 - POST提交
表单提交一般使用POST提交
POST提交能承受传递的信息量更大
使用PostMapping(“映射地址”)来指定控制器 - PUT提交
修改(更新)操作一般使用PUT提交
PUT提交无法直接通过设置表单标签属性来指定PUT提交方式
须在web.xml文件中配置spring隐藏方法过滤器
并在网页文件中添加隐藏input标签,且name为_method
,value为PUT
使用PutMapping(“映射地址”)来指定控制器 - DELETE提交
删除操纵一般使用DELETE提交PUT提交无法直接通过设置表单标签属性来指定PUT提交方式
与PUT提交类似,DELETE提交也无法通过直接设置表单标签属性来指定DELETE提交
须在web.xml文件中配置spring隐藏方法过滤器
并在网页文件中添加隐藏input标签,且name为_method
,value为DELETE
使用DeleteMapping(“映射地址”)来指定控制器 - 即使映射地址相同,也可以通过设定不同“允许接受的提交方式”来指定不同时刻需要启动的方法
控制器
- 通过相应注解获取映射地址中的指定数值(路径变量)
- 通过Model.addAttribute(name, object),将数据注入到网页中
- 通过返回字符串(网页文件名)(由视图解析器负责解析并返回相应视图)
- 通过返回字符串(redirect:/路径)实现重定向
例子
注:省略mybaits配置以及部分代码
-
web.xml
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" version="3.1"> <display-name>HdrSpringWork</display-name> <!-- springmvc提供了一个servlet,能够拦截所有的请求,也就是说所有的请求都经过它 其映射方式类似于 /* -> dispatcherServlet --> <servlet> <servlet-name>dispatcher</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:spring/dispatcher-servlet.xml</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <filter> <filter-name>EncodingFilter</filter-name> <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class> <init-param> <param-name>encoding</param-name> <param-value>utf-8</param-value> </init-param> </filter> <filter-mapping> <filter-name>EncodingFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <filter> <filter-name>HiddenHttpMethodFiler</filter-name> <filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class> </filter> <filter-mapping> <filter-name>HiddenHttpMethodFiler</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <servlet-mapping> <servlet-name>dispatcher</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping> <welcome-file-list> <welcome-file>index.html</welcome-file> <welcome-file>index.htm</welcome-file> <welcome-file>index.jsp</welcome-file> <welcome-file>default.html</welcome-file> <welcome-file>default.htm</welcome-file> <welcome-file>default.jsp</welcome-file> </welcome-file-list> </web-app>
-
spring配置文件(dispatcher-servlet.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:mvc="http://www.springframework.org/schema/mvc" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.3.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.3.xsd"> <!-- 本文件指定了springmvc需要处理的内容的处理机制,如果不是springmvc处理的,则一律放行 --> <!-- springmvc的配置是用注解就可以了,十分方便 --> <mvc:annotation-driven></mvc:annotation-driven> <!-- 控制器部件扫描 (springmvc中servlet已经被controller这个概念封装掉了) 我们必须让springmvc知道其控制器所在的位置,以便加载控制器 包含基本包下头的子包 --> <context:component-scan base-package="mju.edu.hairdryerwork.controller"></context:component-scan> <!-- 该视图解析器能够获取controller方法返回的视图信息,形成一个完整的页面路径 --> <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="prefix" value="/WEB-INF/views/"></property> </bean> <mvc:default-servlet-handler/> <!-- 静态资源 --> <mvc:resources location="/resources/" mapping="/resources/**"></mvc:resources> </beans>
-
网页页面
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %> <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <link rel="stylesheet" href="/hdrwork/resources/vendor/bootstrap-4.5.3-dist/css/bootstrap.min.css"> <script type="text/javascript" src="/hdrwork/resources/vendor/jquery-3.5.1/jquery-3.5.1.js"></script> <script type="text/javascript" src="/hdrwork/resources/vendor/popper.js/popper.min.js"></script> <script type="text/javascript" src="/hdrwork/resources/vendor/bootstrap-4.5.3-dist/js/bootstrap.js"></script> <title>电吹风信息列表</title> </head> <script type="text/javascript"> var hdrType; // function createHdr() { // location.href = "/hdrwork/hdrInfo?task=toInput"; // } function createHdr() { document.forms['createHdrFrm'].submit(); $('createHdrModal').modal('show'); } function showRemoveDlg(hdrtype) { hdrType = hdrtype $("#msg").text("是否确认删除型号--" + hdrtype + "--电吹风"); $("#removeHdrModal").modal('show'); } function removeHdr() { //location.href = "/hdrwork/hdrInfo?task=removeHdr&hdrtype=" + hdrType; $("#hairdryerType").val(hdrType); document.forms['removeHdrFrm'].action += "/" + hdrType; //alert("document.forms['removeHdrFrm'].action"); document.forms['removeHdrFrm'].submit(); } function tupdateHdr(hdrtype) { // location.href = "/hdrwork/hdrInfo?task=preUpdateHdr&hdrtype=" + hdrtype; // location.href = "/hdrwork/hdr/perUpdate?hdrtype=" + hdrtype; location.href = "/hdrwork/hdr/perUpdate/" + hdrtype; } function updateHdr(btn) { // 通过console.log打印测试信息到控制台 // 获取一次按钮的父节点后, 查找到td(单元格标签), 再次获取父节点, 查找到tr(单元格行标签) // children代表的是子节点集合, 是一个数组 // console.log(btn.parentNode.parentNode.children[0].innerText); // 将数组赋值给变量element var elements = btn.parentNode.parentNode.children; // 将表单以id为抓取凭据抓取 并赋值给变量frm var frm = document.forms['upHdrFrm']; // 以表单中的元素的name为依据, 填写相应元素的value值 $("#upHdrLabel").text("电风吹型号:" + elements[0].innerText); frm.hairdryerType.value = elements[0].innerText; frm.hairdryerPower.value = elements[1].innerText; frm.hairdryerPrice.value = elements[2].innerText; hairdryerType = elements[0].innerText; frm.action += "/" + hairdryerType; //alert("frm.action"); $("#updateHdrModal").modal("show"); } /* function updateHdr(hdrtype, hdrpower, hdrprice) { $("#upHdrLabel").text("电风吹型号:" + hdrtype); $("#upHdrType").val(hdrtype); $("#upHdrPower").val(hdrpower); $("#upHdrPrice").val(hdrprice); $("#updateHdrModal").modal("show"); } */ function regUpdate() { document.forms['upHdrFrm'].submit(); $("#updateHdrModal").modal("hidden"); } </script> <body> <div class="container"> <!-- my-5表示上下保持五个边距,margin y轴 --> <h3 class="my-3">电吹风信息列表</h3> <div class="my-2 text-right"> <!-- <button type="submit" class="btn btn-primary" οnclick="createHdr()">新增电风吹型号</button> --> <button type="submit" class="btn btn-primary" data-toggle="modal" data-target="#createHdrModal">新增电风吹型号</button> </div> <table class="table"> <thead> <tr> <th scope="col">电风吹型号</th> <th scope="col">功率</th> <th scope="col">价格</th> <th scope="col">操作</th> </tr> </thead> <tbody> <c:forEach var="hdr" items="${hdrList}"> <tr> <th scope="row">${hdr.hairdryerType}</th> <td>${hdr.hairdryerPower}</td> <td>${hdr.hairdryerPrice}</td> <td> <!-- <button class="btn btn-primary" οnclick="tupdateHdr('${hdr.hairdryerType}')">修改</button> --> <!-- <button class="btn btn-primary" --> <!-- οnclick="updateHdr('${hdr.hairdryerType}', ${hdr.hairdryerPower}, ${hdr.hairdryerPrice})">修改</button> --> <!-- 通过this将this所在的标签返回值function --> <button class="btn btn-primary" οnclick="updateHdr(this);">修改</button> <button class="btn btn-danger" οnclick="showRemoveDlg('${hdr.hairdryerType}')">删除</button> </td> </tr> </c:forEach> </tbody> </table> </div> <!-- 删除学生信息模态窗口 --> <div class="modal fade" tabindex="-1" id="removeHdrModal"> <div class="modal-dialog"> <div class="modal-content"> <div class="modal-header"> <h5 class="modal-title">操作提示</h5> <button type="button" class="close" data-dismiss="modal" aria-label="Close"> <span aria-hidden="true">×</span> </button> </div> <div class="modal-body"> <p id="msg"></p> </div> <div class="modal-footer"> <form action="/hdrwork/hairdryers" method="post" id="removeHdrFrm"> <input type="hidden" name="_method" value="delete"> <button type="button" class="btn btn-secondary" data-dismiss="modal">取消</button> <button type="button" class="btn btn-primary" οnclick="removeHdr()">确认删除</button> </form> </div> </div> </div> </div> <!-- 新增电吹风模态窗口 --> <div class="modal fade" tabindex="-1" id="createHdrModal"> <div class="modal-dialog"> <div class="modal-content"> <div class="modal-header"> <h5 class="modal-title">新增电吹风</h5> <button type="button" class="close" data-dismiss="modal" aria-label="Close"> <span aria-hidden="true">×</span> </button> </div> <div class="modal-body"> <div class="container"> <h3 class="my-5">电吹风信息记录</h3> <form name="createHdrFrm" class="col-md-6" action="/hdrwork/hairdryers" method="POST"> <div class="form-group"> <label for="">电吹风型号</label> <input type="text" class="form-control" name="hairdryerType"> </div> <div class="form-group"> <label for="">功率</label> <input type="text" class="form-control" name="hairdryerPower"> </div> <div class="form-group"> <label for="">价格</label> <input type="text" class="form-control" name="hairdryerPrice"> </div> </form> </div> </div> <div class="modal-footer"> <button type="button" class="btn btn-secondary" data-dismiss="modal">取消</button> <button type="button" class="btn btn-primary" οnclick="createHdr()">确认添加</button> </div> </div> </div> </div> <!-- 修改电吹风信息模态窗口 --> <div class="modal fade" tabindex="-1" id="updateHdrModal"> <div class="modal-dialog"> <div class="modal-content"> <div class="modal-header"> <h5 class="modal-title">操作提示</h5> <button type="button" class="close" data-dismiss="modal" aria-label="Close"> <span aria-hidden="true">×</span> </button> </div> <div class="modal-body"> <div class="container"> <h3 class="my-5">电吹风信息修改</h3> <form id="upHdrFrm" class="col-md-6" action="/hdrwork/hairdryers" method="POST"> <input type="hidden" name="_method" value="put"> <div class="form-group"> <label for="" name="upHdrLabel" id="upHdrLabel"></label> <input type="hidden" class="form-control" name="hairdryerType" id="upHdrType"> </div> <div class="form-group"> <label for="">功率</label> <input type="text" class="form-control" name="hairdryerPower" id="upHdrPower"> </div> <div class="form-group"> <label for="">价格</label> <input type="text" class="form-control" name="hairdryerPrice" id="upHdrPrice"> </div> </form> </div> </div> <div class="modal-footer"> <button type="button" class="btn btn-secondary" data-dismiss="modal">取消</button> <button type="button" class="btn btn-primary" οnclick="regUpdate()">确认修改</button> </div> </div> </div> </div> </body> </html>
-
控制器
/** * */ package mju.edu.hairdryerwork.controller; import java.util.List; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.DeleteMapping; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.PutMapping; import org.springframework.web.bind.annotation.RequestMapping; import mju.edu.hairdryerwork.domain.Hairdryer; import mju.edu.hairdryerwork.service.HairdryerService; import mju.edu.hairdryerwork.service.HairdryerServiceImpl; /** * @author XKF * */ @Controller public class HairdryerController { @RequestMapping("/hdr/to_index") public String test() throws Exception{ System.out.println("避免首页进入信息录入界面(html)中文乱码进行转跳"); return "redirect:/hdr/input"; } @RequestMapping("/hdr/input") public String toInput() throws Exception{ System.out.println("input!"); //返回一个视图,他的名字叫input_hairdryer return "input_hairdryer.html"; } @PostMapping("/hairdryers") public String createHdr(Hairdryer hdr) throws Exception{ // System.out.println(hdr); System.out.println("save!"); HairdryerService hdrService = new HairdryerServiceImpl(); hdrService.addHairdryer(hdr); return "redirect:/hairdryers"; } @GetMapping("/hairdryers") public String loadHdrs(Model model) throws Exception{ System.out.println("loads!"); HairdryerService hdrService = new HairdryerServiceImpl(); List<Hairdryer> hdrList = hdrService.searchHairdryer(); //以key-value的形式保存到模型,其实是保存到request范围中 model.addAttribute("hdrList", hdrList); return "list_hairdryer.jsp"; } @DeleteMapping("/hairdryers/{hdrType}") public String removeHdr(@PathVariable String hdrType) throws Exception{ System.out.println("remove!"); HairdryerService hdrService = new HairdryerServiceImpl(); hdrService.removeHairdryer(hdrType); return "redirect:/hairdryers"; } // @GetMapping("/hdr/perUpdate") // public String perUpdateHdr(@RequestParam("hdrtype") String hdrType, Model model) throws Exception{ // System.out.println("preUpdate!"); // HairdryerService hdrService = new HairdryerServiceImpl(); // Hairdryer hdr = hdrService.preUpdateHdr(hdrType); // model.addAttribute("hdr", hdr); // return "update_hairdryer.jsp"; // } @GetMapping("/hdr/perUpdate/{hdrtype}") public String perUpdateHdr(@PathVariable("hdrtype") String hdrType, Model model) throws Exception{ System.out.println("preUpdate!"); HairdryerService hdrService = new HairdryerServiceImpl(); Hairdryer hdr = hdrService.preUpdateHdr(hdrType); model.addAttribute("hdr", hdr); return "update_hairdryer.jsp"; } @PutMapping("/hairdryers/{hairdryerType}") public String updateHdr(Hairdryer hdr,@PathVariable String hairdryerType) throws Exception{ System.out.println("update!"); HairdryerService hdrService = new HairdryerServiceImpl(); hdrService.updateHdr(hdr); return "redirect:/hairdryers"; } }