🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
[TOC] # 接受表单数据 ## 步骤 1 : 先运行,看到效果,再学习 先将完整的项目(向老师要相关资料),配置运行起来,确认可用之后,再学习做了哪些步骤以达到这样的效果。 访问页面提交数据 `http://localhost:8080/springmvc/addProduct.jsp` ## 步骤 2 : 模仿和排错 在确保可运行项目能够正确无误地运行之后,再严格照着教程的步骤,对代码模仿一遍。 模仿过程难免代码有出入,导致无法得到期望的运行结果,此时此刻通过比较**正确答案** ( 可运行项目 ) 和自己的代码,来定位问题所在。 采用这种方式,**学习有效果,排错有效率**,可以较为明显地提升学习速度,跨过学习路上的各个槛。 ## 步骤 3 : 效果 这是通过页面增加产品名称和价格后,Spring MVC接受到参数,并显示出来 ![](https://box.kancloud.cn/f9d142bc1125c26eae0acf64ad535935_761x232.png) ## 步骤 4 : pojo 实体类Product ~~~ package com.dodoke.pojo; public class Product { private int id; private String name; private float price; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public float getPrice() { return price; } public void setPrice(float price) { this.price = price; } } ~~~ ## 步骤 5 : addProduct.jsp 在WebContent目录下 (不是在WEB-INF下)增加商品的页面addProduct.jsp(用于提交数据) ~~~ <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!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> <form action="addProduct"> 产品名称:<input type="text" name="name" value=""><br> 产品价格:<input type="text" name="price" value=""><br> <input type="submit" value="增加商品"> </form> </body> </html> ~~~ ## 步骤 6 : ProductController 控制器ProductController,准备一个add方法映射/addProduct路径 为add方法准备一个Product 参数,用于接收注入 最后跳转到showProduct页面显示用户提交的数据 注: addProduct.jsp 提交的name和price会自动注入到参数 product里(自动绑定) 注: 参数product会默认被当做值加入到ModelAndView 中,相当于: `mav.addObject("product",product);` ~~~ package com.dodoke.controller; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.servlet.ModelAndView; import com.dodoke.pojo.Product; @Controller public class ProductController { @RequestMapping("/addProduct") public ModelAndView add(Product product) throws Exception { ModelAndView mav = new ModelAndView("showProduct"); return mav; } } ~~~ ## 步骤 7 : showProduct.jsp 在WEB-INF/page 目录下创建 showProduct.jsp 用 EL 表达式显示用户提交的名称和价格 ~~~ <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!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> 产品名称:${product.name } 产品价格:${product.price } </body> </html> ~~~ ## 步骤 8 : 测试 访问页面 `http://localhost:8080/springmvc/addProduct.jsp` 提交数据,显示结果 ![](https://box.kancloud.cn/f9d142bc1125c26eae0acf64ad535935_761x232.png) > 整体流程总结: > `http://localhost:8080/springMVC/addProduct.jsp` --> addProduct.jsp --> form提交到"addProduct"对应的ProductController.add(Product product) --> ModelAndView mav = new ModelAndView("showProduct") --> 跳转到showProduct.jsp ## 常见问题 1. ${product} 从何而来? >不是参数名称,而是参数类型的小写吧 比如参数写的是Product xxx,其实是把Product小写成product后默认放在mav里。 > 详细解释: > add()方法的【参数类型】会自动转小驼峰并加入到 ModelAndView 中作为 addObject() 的【第一个参数】,相当于 addObject("theFirstParam", product); > > 综上:addObject 里第一个参数是根据 add() 的参数类型自动转成小驼峰命名,第二个参数是 add() 的参数名。 > 区分命名,举个极端的栗子就明白了, ~~~ // bean 部分代码 public class MyFuckingProduct {...}   // controller 部分代码 public ModelAndView add(MyFuckingProduct 随便写我写中文应该没人发现吧) {...}   // jsp 部分代码 ${myFuckingProduct.name}   // controller 中相当于 mav.addObject("myFuckingProduct", 随便写我写中文应该没人发现吧); ~~~ > 大家注意 add() 方法的参数,参数名是什么根本不用管,瞎写一通 fhdhdfai2u3y,没有关系,因为默认的 addObject()方法第一个参数只跟你的参数类型有关系,第二个参数就是你瞎写的参数名。 > 相当于:addObject("myFuckingProduct", 随便写我写中文应该没人发现吧); > 然后 EL 表达式写什么就很明了了。 2. 下列代码,是否可以自己定义addObject()? ~~~ public ModelAndView add(Product product) throws Exception { ModelAndView mav = new ModelAndView("showProduct"); return mav; } ~~~ > 可以,mav.addObject("product",product);省略了。如果你想改参数也可以,加上这个mv.addObject("pro",pro); 第一个product相当于键值对的键,第二个product就是你的对象。 在show页面 你就应该写 pro.属性了。 2. 请问在接收到两个参数后,控制器是怎么把名称和价格注入到product对象中的,好像没看到注解什么的,是默认会注入的吗? > springmvc的工作模式是这样的,当他发现页面传递过来有参数name的时候,同时检测到参数的Product这个类,有setName方法,那么就会把参数name的值,注入到这个product对象里去了。默认是按属性名匹配的。 3. 为add增加一个Product类型的参数是不是就是“注入”的应用呢?学到这个地方总感觉怪怪的,为什么要通过参数注入呢?直接在方法内部实例化这个对象不就得了? > 在方法参数上注入,那么在方法里就可以直接使用该对象了。 而不需要向servlet那样,自己手动去实例化一个对象,手动获取request.getParameter("name"),手动设置在实例上。 > 这恰恰就是springmvc提高效率的地方,开发人员只需要关注在业务代码上面,其他的都交给框架做掉了。 4. @RequestMapping("/addProduct") 作用 >这里面的"/addProduct"是匹配请求路径,你的form表单提交时候你的action是addProduct,那么提交就会生成 /addProduct 这个请求的url,然后被你的requestMapping("/addProduct")匹配到,它就执行这个方法。