目录
1.2解读@RequestParam(value="name", required=false)
1.2方式 1: 通过 HttpServletRequest 放入 request 域
1.3方式 2: 通过请求的方法参数 Map 放入 request 域,object>
1.4 方式 3: 通过返回 ModelAndView 对象 实现 request 域数据
3.@ModelAttribute 实现 prepare 方法(前置方法)
1. 修改 web.xml 添加 HiddenHttpMethodFilter
- <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>
2. 修改 springDispatcherServlet-servlet.xml
- <mvc:annotation-driven>mvc:annotation-driven>
- <mvc:default-servlet-handler/>
3.rest.jsp前端页面
- <%--
- User:海绵hong
- Date: 2022/10/26
- Time: 19:46
-
- --%>
- <%@ page contentType="text/html;charset=UTF-8" language="java" %>
- <html>
- <head>
- <title>rest title>
- head>
- <body>
- <h3>Rest风格的crud操作案例h3>
- <br><hr>
- <h3>rest风格的url 查询书籍[get]h3>
- <a href="user/book/200">点击查询书籍a>
- <br><hr>
- <h3>rest风格的url 添加书籍[post]h3>
- <form action="user/book" method="post">
- name:<input name="bookName" type="text"><br>
- <input type="submit" value="添加书籍">
- form>
- <br><hr>
- <h3>rest风格的url, 删除一本书h3>
- <a href="user/book/600" id="deleteBook">删除指定id的书a>
- <form action="" method="post" id="hiddenForm">
- <input type="hidden" name="_method"/>
- form>
- <br><hr>
- <h3>rest风格的url 修改书籍[put]~h3>
- <form action="user/book/666" method="post">
- <input type="hidden" name="_method" value="PUT">
- <input type="submit" value="修改书籍~">
- form>
- body>
- html>
- //查询[GET]
- @GetMapping (value = "/book/{id}")
- public String getBook(@PathVariable("id") String id) {
- System.out.println("查询书籍 id=" + id );
- return "success";
- }
- //添加[POST]
- @PostMapping(value = "/book")
- public String addBook(String bookName) {
- System.out.println("添加书籍 bookName== " + bookName);
- return "success";
- }
1. 默认情况下 删除指定id的书 是get 2. 怎么样将 get 请求转成 springmvc 可以识别的 delete 就要考虑HiddenHttpMethodFilter机制
- public static final String DEFAULT_METHOD_PARAM = "_method";
- ---------------------------------------------------
- private static final List
ALLOWED_METHODS = - Collections.unmodifiableList(Arrays.asList(HttpMethod.PUT.name(),
- HttpMethod.DELETE.name(), HttpMethod.PATCH.name()));
- ---------------------------------------------------
- if ("POST".equals(request.getMethod()) && request.getAttribute(WebUtils.ERROR_EXCEPTION_ATTRIBUTE) == null) {
- String paramValue = request.getParameter(this.methodParam);
- if (StringUtils.hasLength(paramValue)) {
- String method = paramValue.toUpperCase(Locale.ENGLISH);
- if (ALLOWED_METHODS.contains(method)) {
- requestToUse = new HttpMethodRequestWrapper(request, method);
- }
- }
- }
3. 上面代码可以看到 HiddenHttpMethodFilter 过滤器可以对以Post方式提交的delete,put,patch进行转换,成springmvc 识别的 RequestMethod.DELETE / RequestMethod.PUT /... 4. 我们需要将 get 删除指定id的书 以post方式提交给后端handler, 这样过滤器还会生效 5. 我们可以同jquery来处理-引入jquery
- <%-- 引入jquery--%>
- <script type="text/javascript" src="script/jquery-3.6.0.min.js">script>
- <script type="text/javascript">
- $(function () { //当页面加载完成后,就执行=> 如果你完全忘记,去回顾我们讲过的jquery
- //给删除超链接绑定一个点击事件
- $("#deleteBook").click(function (){
- //alert("点击。。。。");
- //我们自己定义给提交的行为
- $("#hiddenForm").attr("action", this.href);//将超链接的值赋值给表单hiddenForm
- $(":hidden").val("DELETE");//给它设置一个delete
- $("#hiddenForm").submit();
- return false; //改变点击超链接的行为, 不在提交
- })
- })
- script>
- @PutMapping("/book/{id}")
- public String updateBook(@PathVariable("id") String id) {
- System.out.println("修改书籍 id=" + id);
- return "redirect:/user/success"; //重定向到一个没有指定 method 的 Handler 方法
- }

1. 获取到超链接传递的数据 请求 http://localhost:8080/springmvc/vote/vote01?name=xx
2. @RequestParam 表示会接收提交的参数
3. value="name" 表示提交的参数名是name
4. required=false 表示该参数可以没有, 默认是true,表示必须有这个参数
5. 当我们使用了@RequestParam(value="name", required=false)后就请求的参数名和方法的形参名可以不一致
- @RequestMapping(value = "/vote01")
- public String test01(@RequestParam(value = "name", required = false) String username) {
-
- System.out.println("得到的username= " + username);
- //返回到一个结果
- return "success";
- }
3.之前我们在servlet中使用其他方法来获取,但是在这个里面我们就可以使用@RequestHeader("Http请求头字段")来获取
- /**
- * 需求: 获取http请求头信息, 获取到Accept-Encoding 和 Host
- * 1. 这里涉及到前面讲过的http协议,小伙伴可以进行回顾
- *
- * @RequestHeader("Http请求头字段")
- */
- @RequestMapping(value = "/vote02")
- public String test02(@RequestHeader("Accept-Encoding") String ae,
- @RequestHeader("Host") String host) {
- System.out.println("Accept-Encoding= " + ae);
- System.out.println("Host= " + host);
- //返回到一个结果
- return "success";
- }
结果:
Accept-Encoding(是浏览器发给服务器,声明浏览器支持的编码类型)= gzip, deflate, br
Host= localhost:8080
开发中,如何获取到 javaben 的数据,就是以前的 entity/pojo 对象数据

演示如果获取到提交数据->封装成java对象 @return 说明 1. 方法的形参用对应的类型来指定即可, SpringMVC会自动的进行封装 2. 如果自动的完成封装, 要求提交的数据,参数名和对象的字段名保持一致 3. 如果属性是对象,这里就是仍然是通过 字段名.字段名 比如Master [pet]即提交的数据 参数名 是 pet.id pet.name, 这就是级联操作 4. 如果提交的数据 的参数名和对象的字段名不匹配,则对象的属性值就是null 5. 小伙伴疑惑,怎么就封装成功[底层仍然是反射+注解..]
- package com.hong.web.requestparam.entity;
-
- /**
- * @author 海绵hong
- * @version 1.0
- */
- public class Pet {
- private Integer id;
- private String name;
-
- public Integer getId() {
- return id;
- }
-
- public void setId(Integer id) {
- this.id = id;
- }
-
- public String getName() {
- return name;
- }
-
- public void setName(String name) {
- this.name = name;
- }
-
- @Override
- public String toString() {
- return "Pet{" +
- "id=" + id +
- ", name='" + name + '\'' +
- '}';
- }
- }
- package com.hong.web.requestparam.entity;
-
- /**
- * @author 海绵hong
- * @version 1.0
- */
- public class Master {
- private Integer id;
- private String name;
- private Pet pet;//对象的属性是另外一个对象[涉及级联]
-
- public Integer getId() {
- return id;
- }
-
- public void setId(Integer id) {
- this.id = id;
- }
-
- public String getName() {
- return name;
- }
-
- public void setName(String name) {
- this.name = name;
- }
-
- public Pet getPet() {
- return pet;
- }
-
- public void setPet(Pet pet) {
- this.pet = pet;
- }
-
- @Override
- public String toString() {
- return "Master{" +
- "id=" + id +
- ", name='" + name + '\'' +
- ", pet=" + pet +
- '}';
- }
- }
- @RequestMapping(value = "/vote03")
- public String test03(Master master) {
-
- System.out.println("master=" + master);
- //返回结果
- return "success";
- }
- <h1>添加主人信息h1>
- <form action="vote/vote03" method="post">
- 主人号:<input type="text" name="id"><br>
- 主人名:<input type="text" name="name"><br>
- 宠物号:<input type="text" name="pet.id"><br>
- 宠物名:<input type="text" name="pet.name"><br>
- <input type="submit" value="添加主人和宠物">
- form>


- /**
- * 使用servlet api, 来获取提交的数据
- *
- * @return
- */
- @RequestMapping(value = "/vote04")
- public String test04(HttpServletRequest request,
- HttpServletResponse response,
- HttpSession hs) {
-
- //获取到session
- //servlet原生的方式
- HttpSession session = request.getSession();
- System.out.println("session=" + session);
- //注意:通过参数传入的 hs 和 通request.getSession() 得到的对象是
- //同一个
- System.out.println("hs= " + hs);
-
- String username = request.getParameter("username");
- String pwd = request.getParameter("pwd");
- System.out.println("username= " + username);
- System.out.println("pwd= " + pwd);
- //返回结果
- return "success";
- }
- <h1>演示 servlet api的使用 h1>
- <form action="vote/vote04" method="post">
- 用户名:<input type="text" name="username"><br>
- 密 码:<input type="password" name="pwd"><br>
- <input type="submit" value="添加用户">
- form>

- <%--
- Created by IntelliJ IDEA.
- User: 海绵hong
- Version: 1.0
- Filename: request_parameter
- --%>
- <%@ page contentType="text/html;charset=UTF-8" language="java" %>
- <html>
- <head>
- <title>测试 模型数据title>
- head>
- <body>
- <h1>添加主人信息h1>
- <form action="vote/vote05" method="post">
- 主人号:<input type="text" name="id"><br>
- 主人名:<input type="text" name="name"><br>
- 宠物号:<input type="text" name="pet.id"><br>
- 宠物名:<input type="text" name="pet.name"><br>
- <input type="submit" value="添加主人和宠物">
- form>
-
- <br/><hr/>
- <h1>添加主人信息[测试 Map ]h1>
- <form action="vote/vote06" method="post">
- 主人号:<input type="text" name="id"><br>
- 主人名:<input type="text" name="name"><br>
- 宠物号:<input type="text" name="pet.id"><br>
- 宠物名:<input type="text" name="pet.name"><br>
- <input type="submit" value="添加主人和宠物">
- form>
-
- <br/><hr/>
- <h1>添加主人信息[测试ModelAndView]h1>
- <form action="vote/vote07" method="post">
- 主人号:<input type="text" name="id"><br>
- 主人名:<input type="text" name="name"><br>
- 宠物号:<input type="text" name="pet.id"><br>
- 宠物名:<input type="text" name="pet.name"><br>
- <input type="submit" value="添加主人和宠物">
- form>
-
- body>
- html>
- <%--
- Created by IntelliJ IDEA.
- User: 海绵hong
- Version: 1.0
- Filename: vote05
- --%>
- <%@ page contentType="text/html;charset=UTF-8" language="java" %>
- <html>
- <head>
- <title>vote_ok title>
- head>
- <body>
- <h1>获取的的数据显示页面h1>
- <hr>
- 取出 request域的数据-通过前面讲解的el表达式来获取即可
- <br>
- address: ${requestScope.address}<br>
- 主人名字= ${requestScope.master.name}
- 主人id= ${requestScope.master.id}
- 宠物名字= ${requestScope.master.pet.name}
-
- html>
- /**
- * 解读
- * 1. 演示将提交的数据->springmvc封装到java对象->springmvc 会自动的将其放入到request域
- * 2. 这样我们就可以在跳转到的页面取出数据.
- *
- * @return
- */
- @RequestMapping(value = "/vote05")
- public String test05(Master master, HttpServletRequest request) {
-
- //解读
- //1. springmvc会自动把获取的model模型,放入到request域中,名字就是master
- //2. 也可以手动将master放入到request
- request.setAttribute("address", "beijing");
- //3. 如果我们希望修改master的属性值
- master.setName("nono");//request域中的值也会发生变化
- //4. 分析一下springmvc默认存放对象到request域中,属性名是
- // request域 ("master", master) 属性名是类名/类型名 首字母小写
- //返回到一个结果
- return "vote_ok";
- }
request域 ("master", master) 属性名是类名/类型名 首字母小写
- /**
- * 演示通过Map
设置数据到request域 - *
- * @return
- */
- @RequestMapping(value = "/vote06")
- public String test06(Master master, Map
map) { - System.out.println("------test06-----");
- //解读
- //1. 需求是通过map对象,添加属性到request中
- //2. 原理分析:springmvc会遍历map,然后将map的k-v, 存放到request域
- map.put("address", "beijing...");
- return "vote_ok";
- }
- /**
- * 演示通过返回ModelAndView对象,将数据放入到request域
- * @return
- */
- @RequestMapping(value = "/vote07")
- public ModelAndView test07(Master master) {
-
- System.out.println("----test07----");
- ModelAndView modelAndView = new ModelAndView();
- //放入属性到modelAndView对象
- modelAndView.addObject("address", "shanghai");
- //modelAndView.addObject("master", null);
- //可以把从数据库得到的数据->对象-》放入modelAndView[Service-dao-db]
- //这里指定跳转的视图名称
- modelAndView.setViewName("vote_ok");
- //返回结果
- return modelAndView;
- }
5. 使用注意事项


- <br/><hr/>
- <h1>添加主人信息[测试session]h1>
- <form action="vote/vote08" method="post">
- 主人号:<input type="text" name="id"><br>
- 主人名:<input type="text" name="name"><br>
- 宠物号:<input type="text" name="pet.id"><br>
- 宠物名:<input type="text" name="pet.name"><br>
- <input type="submit" value="添加主人和宠物">
- form>
- <hr>
- 取出 session域的数据 <br>
- address: ${sessionScope.address}<br>
- 主人名字= ${sessionScope.master.name}
- 主人信息= ${sessionScope.master}
- body>
- /**
- * 演示如何将数据设置到session域中
- * @return
- */
- @RequestMapping(value = "/vote08")
- public String test08(Master master, HttpSession httpSession) {
- System.out.println("----test08----");
- //master对象是默认放在request域
- //我们将master对象放入到session域
- httpSession.setAttribute("master", master);
- httpSession.setAttribute("address", "guangzhou");
-
- return "vote_ok";//请求转发
- }
- /**
- * 解读
- * 1. 当Handler的方法被标识 @ModelAttribute,就视为一个前置方法
- * 2. 当调用该Handler的其它的方法时,都会先执行该前置方法
- * 3. 类似我们前面讲解Spring时,AOP的前置通知[底层是AOP机制]
- * 4. prepareModel前置方法,会切入到其它方法前执行..
- */
- @ModelAttribute
- public void prepareModel(){
- System.out.println("prepareModel()-----完成准备工作-----");
- }
配置自定义视图解析器
-
- <bean class="org.springframework.web.servlet.view.BeanNameViewResolver">
- <property name="order" value="99">property>
- bean>
首先我们需要配置一个视图
- <%--
- Created by IntelliJ IDEA.
- User: 海绵hong
- Version: 1.0
- Filename: view
- --%>
- <%@ page contentType="text/html;charset=UTF-8" language="java" %>
- <html>
- <head>
- <title>自定义视图测试title>
- head>
- <body>
- <h1>自定义视图测试h1>
- <a href="goods/buy">点击到自定义视图-a><br/>
- <a href="goods/order">测试在目标方法中指定请求转发或者重定向的页面-a><br/>
- body>
- html>
由这个jsp跳转到handler
- package com.hong.web.viewresolver;
-
- import org.springframework.stereotype.Controller;
- import org.springframework.web.bind.annotation.RequestMapping;
-
- /**
- * @author 海绵hong
- * @version 1.0
- */
-
- @RequestMapping("/goods")
- @Controller
- public class GoodsHandler {
-
- @RequestMapping(value = "/buy")
- public String buy() {
- System.out.println("------buy()-----");
- return "hongView";//待会再填写自定义视图名
- }
-
- }
因为这个handler的重定向,继续跳转到id=hspView的handler自定义视图中
最后指向my_view.jsp
- <%--
- Created by IntelliJ IDEA.
- User: 海绵hong
- Version: 1.0
- Filename: my_view
- --%>
- <%@ page contentType="text/html;charset=UTF-8" language="java" %>
- <html>
- <head>
- <title>my_view页面title>
- head>
- <h1>进入到my_view页面h1>
- <p>是从自定义视图来的..p>
- <body>
-
- body>
- html>
- /**
- * 演示直接指定要请求转发的或者是重定向的页面
- * @return
- */
- @RequestMapping(value = "/order")
- public String order() {
- System.out.println("=======order()=====");
- //请求转发到 /WEB-INF/pages/my_view.jsp
- //下面的 /WEB-INF/pages/my_view.jsp 被解析成 /springmvc/WEB-INF/pages/my_view.jsp
- //return "forward:/WEB-INF/pages/my_view.jsp";
- //return "forward:/aaa/bbb/ok.jsp";
-
- //直接指定要重定向的页面
- //1. 对于重定向来说,不能重定向到 /WEB-INF/ 目录下
- //2. redirect 关键字,表示进行重定向
- //3. /login.jsp 在服务器解析 /springmvc/login.jsp
- return "redirect:/login.jsp";
-
- // /WEB-INF/pages/my_view.jsp 被解析 /springmvc/WEB-INF/pages/my_view.jsp
- //return "redirect:/WEB-INF/pages/my_view.jsp";
- }
直接指定要重定向的页面 1. 对于重定向来说,不能重定向到 /WEB-INF/ 目录下 2. redirect 关键字,表示进行重定向