我们都知道,表单中请求参数都是基于key=value的。 SpringMVC绑定请求参数的过程是通过把表单提交请求参数,作为控制器中方法参数进行绑定的。
我们在表单中的参数名称必须和控制器中方法的形参名称保持一致。(严格区分大小写)
index.jsp文件
<form method="post" action="param/test">
姓名:<input type="text" name="name"><br>
密码:<input type="text" name="password"><br>
年龄:<input type="text" name="age"><br>
<input type="submit" value="提交">
</form>
Controller类
@Controller
@RequestMapping("/param")
public class ParamController {
@RequestMapping("/test")
public String ParamTest(String name, User user){
System.out.println(name + ‘\t‘ + user);
return "success";
}
}
User类
public class User implements Serializable {
String password;
Integer age;
@Override
public String toString() {
return "User{" +
"password=‘" + password + ‘\‘‘ +
", age=" + age +
‘}‘;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
}
这里直接使用实体类的时候,表单中的name命名可以当作基本类型,但是当实体类中使用其他实体类,要使用如下命名方式
中文释义为简单的java对象,其实就是Java bean,好像是为了避免和EJB混淆所创造的简称
要求表单中参数名称和POJO类的属性名称保持一致。并且控制器方法的参数类型是POJO类型。例如:name.firstname
用于这里的实体类都要实现Serializable接口
index.jsp
<form method="post" action="param/test">
姓:<input type="text" name="name.firstname"><br>
名:<input type="text" name="name.secondname"><br>
密码:<input type="text" name="password"><br>
年龄:<input type="text" name="age"><br>
<input type="submit" value="提交">
</form>
Controller类
@Controller
@RequestMapping("/param")
public class ParamController {
@RequestMapping("/test")
public String ParamTest(User user){
System.out.println(user);
return "success";
}
}
User类
public class User implements Serializable {
String password;
Name name;//自定义类型JavaBean
Integer age;
@Override
public String toString() {
return "User{" +
"password=‘" + password + ‘\‘‘ +
", name=" + name +
", age=" + age +
‘}‘;
}
public Name getName() {
return name;
}
public void setName(Name name) {
this.name = name;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
}
Name类
public class Name implements Serializable {
@Override
public String toString() {
return "Name{" +
"firstname=‘" + firstname + ‘\‘‘ +
", secondname=‘" + secondname + ‘\‘‘ +
‘}‘;
}
private String firstname, secondname;
public String getFirstname() {
return firstname;
}
public void setFirstname(String firstname) {
this.firstname = firstname;
}
public String getSecondname() {
return secondname;
}
public void setSecondname(String secondname) {
this.secondname = secondname;
}
}
index.jsp
<form method="post" action="param/test">
姓一:<input type="text" name="nameList[0].firstname"><br>
名一:<input type="text" name="nameList[0].secondname"><br>
姓二:<input type="text" name="nameList[1].firstname"><br>
名二:<input type="text" name="nameList[1].secondname"><br>
姓三:<input type="text" name="nameMap[‘one‘].firstname"><br>
名三:<input type="text" name="nameMap[‘one‘].secondname"><br>
密码:<input type="text" name="password"><br>
年龄:<input type="text" name="age"><br>
<input type="submit" value="提交">
</form>
Controller类同上
User类
public class User implements Serializable {
String password;
Integer age;
List<Name> nameList;
Map<String, Name> nameMap;
@Override
public String toString() {
return "User{" +
"password=‘" + password + ‘\‘‘ +
", age=" + age +
", nameList=" + nameList +
", nameMap=" + nameMap +
‘}‘;
}
public List<Name> getNameList() {
return nameList;
}
public void setNameList(List<Name> nameList) {
this.nameList = nameList;
}
public Map<String, Name> getNameMap() {
return nameMap;
}
public void setNameMap(Map<String, Name> nameMap) {
this.nameMap = nameMap;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
}
Name类同上
在web.xml中配置Spring提供的过滤器类:
<!-- 配置过滤器,解决中文乱码的问题 -->
<filter>
<filter-name>characterEncodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filterclass>
<!-- 指定字符集 -->
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>characterEncodingFilter</filter-name>
<!--/*代表拦截所有-->
<url-pattern>/*</url-pattern>
</filter-mapping>
任何变量从jsp传到控制器用的都是字符串,当其到控制器时,Spring有自定义的类型转换器将其转换为特定的类型的变量,当有些变量无法通过Spring自定义类型转换器转换类型时,我们可以自己定义一个类型转换器来帮助转换。
例如Data类,默认日期格式为1999/10/1,当我们输入1999-10-1时则会发生错误,Spring自定义类型转换器无法转换,此时我们自己定义一个类型转换器,来讲1999-10-1格式的日期字符串转换成Data类。
自定义的类型转换器类需要继承一个Converter接口,要看清楚是Spring核心包中的Converter接口:
类中的两个泛型S和T分别写要从类型S转换到类型T
public class StringToData implements Converter<String, Date>{
@Override
public Date convert(String source) {
if (source==null){
throw new RuntimeException("值空");
}
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
try {
return dateFormat.parse(source);
}catch (Exception e){
throw new RuntimeException("错误");
}
}
}
在resources中的xml配置文件中配置自定义类型转换器,就是你配置视图解析器的那个配置文件。
<bean id="conversionServiceFactoryBean"
class="org.springframework.context.support.ConversionServiceFactoryBean">
<property name="converters">
<set>
<bean class="com.utils.StringToData"></bean>
</set>
</property>
</bean>
<!--配置spring开启注解mvc的支持-->
<mvc:annotation-driven conversion-service="conversionServiceFactoryBean"></mvc:annotation-driven>
这里还要修改开启注解mvc的支持,因为在开启注解mvc的支持时是默认开启了处理器映射器、处理器适配器、视图解析器三大组件,而现在想用类型转换器,则必须在这里配置开启。
作用:把请求中的指定名称的参数传递给控制器中的形参赋值
属性:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<a href="anno/testRp?name=haha">testRequestParam</a>
</body>
</html>
@Controller
@RequestMapping("anno")
public class AnnoController {
@RequestMapping("/testRp")
public String testRp(@RequestParam(value = "name", required = false) String username){
if (username==null)
System.out.println("无用户名");
else
System.out.println(username);
return "success";
}
}
在这个例子中我们把required改为false,则当没有参数传递给username时它为null。当使用RequestParam时则必须按照它的value在jsp页面命名,不能像请求参数绑定中命名成相同的名字。例如在这个例子中,jsp页面想要传递参数给控制器中的username,就必须给控制器传递一个名为name的参数,而不能传递一个名为username的参数。
作用:用于获取请求体的内容,直接使用得到是key=value&key=value...结构的数据。(注意:get方法不可以,因为get没有请求体,它把参数都封装到地址栏了)
属性:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<form method="post" action="anno/testRequestBody">
用户名:<input type="text" name="username"><br>
密码:<input type="text" name="password"><br>
年龄:<input type="text" name="age"><br>
<input type="submit" value="提交">
</form>
</body>
</html>
@Controller
@RequestMapping("anno")
public class AnnoController {
@RequestMapping("/testRequestBody")
public String testRequestBody(@RequestBody String body){
System.out.println(body);
return "success";
}
}
在本例中的请求体输出示例:username=int64Saturday&password=111&age=111
作用:用于绑定url中的占位符。例如:请求url中 /delete/{id},这个{id}就是url占位符。
url支持占位符是spring3.0之后加入的。是springmvc支持rest风格URL的一个重要标志。
那么什么时rest风格的URL呢,一般rest风格都称为restful风格,它其实就是一种规范,区别于我们平时普通的url,见下图
(图中的FindById()方法少写了个参数id)从图中可看出普通的url每个方法都会对应一个地址,但是restful风格的url相同类下的每个方法地址都是相同的。restful风格的url是通过http协议的四种方法来寻找要执行的方法,即:
但是当遇到相同的方法时,如上图的FindAll()方法和FindById(id)方法,它会通过不同的参数来寻找特定的方法,有些类似函数的重载。上图中的{id}是占位符,当我们想调用FindById(id)方法时,参数id=10,此时的url应该为:/user/10
但是form表单只支持GET和POST方法,而DELETE、PUT等方法并不支持,Spring3.0添加了一个过滤器能帮我们模拟这些方法,但是配置比较麻烦,不如其他的一些类实现容易,这里就不赘述了,想了解的可以自行百度。
属性:
<body>
<form method="post" action="anno/10">
用户名:<input type="text" name="username"><br>
密码:<input type="text" name="password"><br>
年龄:<input type="text" name="age"><br>
<input type="submit" value="提交">
</form>
</body>
@Controller
@RequestMapping("anno")
public class AnnoController {
@RequestMapping("/{sid}")
public String testPathVaribale(@PathVariable(value = "sid") String id){
System.out.println(id);
return "success";
}
}
最后控制台输出结果为10。
作用:用于获取请求消息头。http请求头有很多种,详情见百度百科:http请求头
属性:
注: 在实际开发中一般不怎么用。
<a href="anno/testRequestHeader">testRequestHeader</a>
@RequestMapping("/testRequestHeader")
public String testRequestHeader(@RequestHeader(value = "Accept") String header){
System.out.println(header);
return "success";
}
作用:用于把指定 cookie 名称的值传入控制器方法参数。
属性:
注: 在实际开发中一般不怎么用。
<a href="anno/testCookieValue">testRequestHeader</a>
@RequestMapping("/testCookieValue")
public String testCookieValue(@CookieValue(value = "JSESSIONID") String cookieValue){
System.out.println(cookieValue);
return "success";
}
作用:该注解是 SpringMVC4.3 版本以后新加入的。它可以用于修饰方法和参数。
属性:
应用场景:
当表单提交数据不是完整的实体类数据时,保证没有提交数据的字段使用数据库对象原来的数据。
<form method="post" action="anno/testModelAttribute">
用户名:<input type="text" name="username"><br>
密码:<input type="text" name="password"><br>
年龄:<input type="text" name="age"><br>
<input type="submit" value="提交">
</form>
@RequestMapping("/testModelAttribute")
public String testModelAttribute (User user){
System.out.println("testModelAttribute执行了..." + user.getUsername());
return "success";
}
@ModelAttribute
public void showUser(){
System.out.println("showUser执行了...");
}
最后控制台输出结果为:
showUser执行了...
testModelAttribute执行了...int64Saturday
有返回值,表单中没有输入age的文本框,如果不进行配置,则age为null
<form method="post" action="anno/testModelAttribute">
用户名:<input type="text" name="username"><br>
密码:<input type="text" name="password"><br>
<input type="submit" value="提交">
</form>
@RequestMapping("/testModelAttribute")
public String testModelAttribute (User user){
System.out.println("testModelAttribute执行了...");
System.out.println(user);
return "success";
}
@ModelAttribute
public User showUser(String username){
User user = new User();
//模拟数据库查询
user.setAge(10);
user.setPassword("111");
user.setUsername(username);
System.out.println("showUser执行了...");
return user;
}
无返回值,没有返回值时,需要方法提供一个map结构,将User对象存入map中,然后在控制器方法中用ModelAttribute修饰形参从map中取出该对象。
同上
@ModelAttribute
public void showUser(String username, Map<String, User> map){
User user = new User();
//模拟数据库查询
user.setAge(10);
user.setPassword("111");
user.setUsername(username);
map.put("user", user);
System.out.println("showUser执行了...");
}
作用:用于多次执行控制器方法间的参数共享,作用于类上。
属性:
<a href="anno/testSaveSessionAttribute">SaveSessionAttribute</a><br>
<a href="anno/testGetSessionAttribute">GetSessionAttribute</a><br>
<a href="anno/testDeleteSessionAttribute">DeleteSessionAttribute</a>
@Controller
@RequestMapping("anno")
@SessionAttributes(value = {"username", "password"})
public class AnnoController {
@RequestMapping("/testSaveSessionAttribute")
public String testSaveSessionAttribute (Model model){
System.out.println("向session中保存了数据");
model.addAttribute("username", "root");
model.addAttribute("password", "1234");
return "success";
}
@RequestMapping("/testGetSessionAttribute")
public String testGetSessionAttribute (ModelMap modelMap){
System.out.println("从session中获取了数据");
String username = (String)modelMap.get("username");
String password = (String)modelMap.get("password");
System.out.println("username:" + username + "\tpassword:" + password);
return "success";
}
@RequestMapping("/testDeleteSessionAttribute")
public String testDeleteSessionAttribute (SessionStatus sessionStatus){
System.out.println("从session中删除了数据");
//设置完成,就是这些操作做完了,它会帮你把session中的数据清除
sessionStatus.setComplete();
return "success";
}
}
超链接点击步骤:存值->取值->删除->取值
控制台输出:
向session中保存了数据
从session中获取了数据
username:root password:1234
从session中删除了数据
从session中获取了数据
username:null password:null
SpringMVC--二、SpringMVC请求参数绑定和常用注解
原文:https://www.cnblogs.com/zhangzeff/p/14442470.html