一、参数绑定
参数绑定过程:当用户在页面促发某种请求时,一般会将一些参数带到后台。在SpringMVC中可以通过参数绑定,将客户端请求的数据绑定到Controller处理器方法的形参上。
二、准备
- 注意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/beans
http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.0.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd">
<!-- 扫描com.mr.controller包 -->
<context:component-scan base-package="com.mr.controller"></context:component-scan>
<bean id = "irViewResolver"
class = "org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name = "prefix" value = "/WEB-INF/page"/>
<property name = "suffix" value = ".jsp"/>
</bean>
</beans>
- 导入jar包
这一步还是比较容易忽略的。如果不导入jar包,导入包的时候不会有提示,并且会报红线。
注意:在使用@Controller时,导入的包是org.springframework.stereotype.Controller;与之相对应的是我们直接采用实现Controller接口时,导入的包是import org.springframework.web.servlet.mvc.Controller;
三、简单类型参数绑定
- 无注解参数绑定
index.jsp
<%@ page language="java" import="java.sql.*" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<a href = "usersController/test?uId=123">无注解参数绑定</a>
</body>
</html>
需要注意的是:此时的index.jsp必须放在webContent的目录下面,而不能放在WEB-INF下面的page目录下面,因为这个页面一开始是不能直接访问的,会报一个404错误。
然后又会报一个500错误,下面这个500错误的解决方案是:重新引入新的jar包。
但是引入完新的jar包后,又会报一个新的500错误,于是我决定用直接的SpringMVC项目的环境了。
换了一个环境之后就可以能够实现在控制台输出uId的值了,但是仍然有一个报错页面。
我猜测是因为控制器处理之后没有返回给浏览器一个页面的缘故,而是直接就在控制台输出了。
- 使用注解参数绑定
在使用无注解参数绑定中,由于在index.jsp页面中传参时的uId=123与控制器中的形参uId同名,因此是无注解的;但是如果这两者不同名,那么此时应该采用带有注解方式的绑定。
@RequestMapping("/testRequestParam")
public String testRequestParam(@RequestParam(value="id")Integer u_id){
System.out.println(u_id);
return "another";
}
<a href = "usersController/testRequestParam?id=456">使用注解参数绑定</a>
通过观察我们可以发现,虽然在控制器的方法中u_id与超链接传过去的id的名字不同,但是我们在u_id的前面加入了注解@RequestParam(value="id")就将这两个参数关联起来了。
- 使用默认值绑定
在Controller方法的形参中,如果有一些参数可能为空,但是又希望它们为空时有一个默认值,此时可以使用@RequestParam注解的defaultValue属性来指定某些参数的默认值。
@RequestMapping("/testdefaultValue")
public String testdefaultValue(@RequestParam(value="id", defaultValue="1")Integer u_id)
{
System.out.println(u_id);
return "another";
}
<a href = "usersController/testdefaultValue?id1=456">使用默认值绑定</a>
因为我们的超链接的传参变为了id1,不再是之前的id了,但是我们的控制器中仍然将id和u_id关联在一起,也就是说我们的id1虽然传过去了,但是没有参数对它进行接收;同样的,由于没有id这个实参的存在,u_id是一个空值,这时会采用默认值的设置,于是控制台输出1。
四、url地址栏传递参数与绑定
有时候运行页面的时候会出现这样的404错误。
可能你的代码其实根本就没有错误,如果此时你的tomcat处于启动状态的话,你可以把它停掉,然后再重新启动,可能就可以访问到资源了。至少我刚刚是这样处理的,并且也成功了。
因为http是无状态的协议,也就是说我们的这个Uid在经过第二次跳转的时候,如果你没有把它存储下面,那么到第三个页面的时候,浏览器就不会记得还有Uid这个变量了,更何况它的值呢?
五、SpringMVC接受表单数据
关键代码:
@Controller
public class ProductController {
@RequestMapping("/addProduct")
public ModelAndView addProduct(Product product) throws Exception{
ModelAndView mav = new ModelAndView("showProduct");
return mav;
}
}
在控制器方法中,尽管我们没有显式的看到获取到从addProduct.jsp传递过来的name属性和price属性,但是由于product中有name和price这两个属性,且属性名是一致的,因此控制器在我们看不见的地方默默的为它们赋值了,并且将这个product塞到了mav的身上。相当于我们之前手动的敲这一段代码:mav.addObject("product", product)。
这就是为什么我们可以直接在showProduct.jsp中用EL表达式取出这个值的原因。
六、注册案例
这个注册案例本质上和上面的那个接受表单数据没有区别,下面这个要复杂一点的地方在于需要接受多个同名的属性。
接受多个同名属性的处理:
public String getHobbys() {
hobbys = "";
for(int i = 0; i < hobby.length; i ++ )
{
hobbys += hobby[i] + " ";
}
return hobbys;
}
在接受参数的时候,主要是hobby[]数组在接受,只不过为了后面的展示,被拼接成了一个字符串而已。
七、练习——简单计算器
- 加
- 减
- 乘
- 除
calculate.jsp
<%@ page language="java" import="java.sql.*" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<h3>简单计算器</h3>
<form action = "calculate" method = "post">
第一个数:<input type = "text" name = "firstNum"/><br/><br/>
操作数:
<select name = "op">
<option>+</option>
<option>-</option>
<option>*</option>
<option>/</option>
</select><br/><br/>
第二个数:<input type = "text" name = "secondNum"/><br/><br/>
<input type = "submit" value = "计算"/>
</form>
</body>
</html>
CalculateController
package controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;
import pojo.Computed;
@Controller
public class CalculateController {
@RequestMapping("/calculate")
public ModelAndView finalAnswer(Computed cmp)
{
ModelAndView mav = new ModelAndView();
if(cmp.getOp().equals("+")){
cmp.setAns(cmp.getFirstNum() + cmp.getSecondNum());
}else if(cmp.getOp().equals("-")){
cmp.setAns(cmp.getFirstNum() - cmp.getSecondNum());
}else if(cmp.getOp().equals("*")){
cmp.setAns(cmp.getFirstNum() * cmp.getSecondNum());
}else{
cmp.setAns(cmp.getFirstNum() / cmp.getSecondNum());
}
mav.addObject("cmp", cmp);
mav.setViewName("showRes");
return mav;
}
}
Computed
package pojo;
public class Computed {
private float firstNum;
private String op;
private float secondNum;
private float ans;
public float getFirstNum() {
return firstNum;
}
public void setFirstNum(float firstNum) {
this.firstNum = firstNum;
}
public String getOp() {
return op;
}
public void setOp(String op) {
this.op = op;
}
public float getSecondNum() {
return secondNum;
}
public void setSecondNum(float secondNum) {
this.secondNum = secondNum;
}
public float getAns() {
return ans;
}
public void setAns(float ans) {
this.ans = ans;
}
}
showRes.jsp
<%@ page language="java" import="java.sql.*" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8" isELIgnored="false"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
您选择的运算符是:${cmp.getOp()}<br/>
您计算的结果是:${cmp.getAns()}
</body>
</html>