Spring全家桶之SpringMVC(三)
Spring MVC单个接收表单提交的数据
单个接收表单提交的参数
在实际开发中通过会在spring MVC的Controller里面接收表单提交过来的参数,这块代码该怎么去编写呢?
示例:
编写一个带有表单的jsp(我这里直接使用了index.jsp):
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>Title</title> </head> <body> <form action="${pageContext.request.contextPath}/regist1.do" method="post"> 姓名:<input type="text" name="username"><br> 年龄:<input type="text" name="age"><br> <input type="submit" value="提交"> </form> </body> </html>
之后创建一个controller来接收这个表单提交的值:
package controller; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.servlet.ModelAndView; @Controller public class HelloSpringMVC { @RequestMapping("/regist1.do") public ModelAndView regist1(String username,int age){ ModelAndView mv = new ModelAndView(); mv.addObject("username",username); mv.addObject("age",age); mv.setViewName("test"); return mv; } }
再创建一个跳转页面test.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> <title>Insert title here</title> </head> <body> 用户名:${username} <br> 年龄:${age} </body> </html>
在上面的controller中,我们在regist1方法后面的参数列表中写上了两个参数username和age,controller方法上的两个参数必须与表单中input中的name一致,这样spring MVC会自动为其赋值,通过这种方式就可以在controller中获取表单提价的数据了。
下面我们分析一下表单提交参数的流程:
首先再index.jsp页面的<input>中输入数据点击提交按钮之后,会跳转到表单action指定的url上,我们在controller方法上有两个参数去分别接收相应的数据(index.jsp中input标签的name属性中的参数一定要与controller方法上参数名相同,否则controller方法中无法接收到数据)。接收到之后我们再通过ModelAndView的addObject()方法将从前台接收username和age属性传递到test.jsp中,这样我们就可以将index.jsp中输入的数据通过controller请求传递到test.jsp页面了。
整个流程需要注意的两点:
1、input标签name属性名要与controller方法上参数名一致
2、form表单action属性对应的是controller的RequestMapping,若不对应则无法进行跳转。
此时你可能会发现一个问题,在之前我们写的controller中的方法参数列表里面我们都写上了request和response,而这里却没有写,其实这不会影响spring mvc的工作,也就是说在controller的方法里面,我们可以写多个参数,也可以一个都不写,不过spring mvc只会自动为以下五个参数进行自动赋值:
- HttpServletRequest
- HttpServletResponse
- HttpSession
- 请求携带的参数
- 用于承载数据的Model
当前示例其实就是spring mvc将请求携带参数进行赋值,这样子我就可以直接获取表单提交的数据了。其他的以后在介绍。
获取请求参数乱码
在上面的示例中,倘若你输入了中文,那很有可能出现乱码问题,我们可以使用spring MVC为开发者提供的CharacterEncodingFilter来解决乱码问题,这个其实就是一个过滤器。我们需要在web.xml文件中进行配置,最好将其设置在其他过滤器之前,因为过滤器是按照web.xml中的顺序执行的:
<!--字符编码过滤器--> <filter> <filter-name>characterEncodingFilter</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> <!--强制指定字符编码,即如果在request中指定了字符编码,那么也会为其强制指定当前设置的字符编码--> <init-param> <param-name>forceEncoding</param-name> <param-value>true</param-value> </init-param> </filter> <filter-mapping> <filter-name>characterEncodingFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
这里可以通过springmvc的源码中看到forceEncoding如果设置为true的话,那么不论你是否在request中设置了字符编码,spring mvc都会强制将其字符编码设置为我们在web.xml文件中写的字符编码。
参数名不一致的情况
参数名不一致的情况
在实际开发中有可能会有这样的问题,就是表单中input的name和spring mvc方法中的参数名不一致,这时可以使用@RequestParam注解来解决这个问题,这个注解中有三个属性:
- value:指定请求参数的名称,即表单中input的name值。
- name:同value,两者只能使用一个
- required:指定该参数是否是必须传入的,boolean类型。若为 true,则表示请求中所携带的参数中必须包含当前参数。若为 false,则表示有没有均可。
- defaultValue:指定当前参数的默认值。如果请求中没有该参数,则当前方法参数将取该默认值。
在之前的示例基础上进行修改:
index.jsp表单中添加一个sex:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<form action="${pageContext.request.contextPath}/regist1.do" method="post">
姓名:<input type="text" name="username"><br>
年龄:<input type="text" name="age"><br>
性别:<input type="text" name="sex"><br>
<input type="submit" value="提交">
</form>
</body>
</html>
在controller的方法中的参数名与表单中的参数名不一致,使用@RequestParam:
@Controller
public class HelloSpringMVC {
@RequestMapping("/regist1.do")
public ModelAndView regist1(@RequestParam(name = "username") String t_username,@RequestParam(name="age",defaultValue = "18") int t_age,@RequestParam(required = true) String sex){
ModelAndView mv = new ModelAndView();
mv.addObject("username",t_username);
mv.addObject("age",t_age);
mv.addObject("sex",sex);
mv.setViewName("test");
return mv;
}
}
name :t_username和t_age参数名与表单中name属性名不一致,所以使用@RequestParam的name属性(属性名与表单中的保持一致)。
defaultValue:如果我们age什么都不输入,controller就会根据defaultValue属性设置的值去自动赋值。
required:如果我们设置为true,则sex这一栏在index.jsp中我们必须输入值,如果不输入,此时系统会报出400的错误,因为请求参数中没有sex。
使用对象接收表单参数
使用对象来接收表单提交的参数
在之前的接收表单提交参数的示例中有个问题,倘若表单中的参数较多的话,需要在controller的方法里面把这些参数都写上,这样就不太方便了,我们可以定义一个javabean,将表单中的参数都写到javabean的属性里面,然后将这个bean作为参数写到controller的方法中。
示例:
定义一个Student类,里面的属性名跟表单的name保持一致
package bean; public class Student { private String username; private int age; public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } }
定义Controller,在方法中将Student对象作为参数传入:
package controller; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import bean.Student; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.servlet.ModelAndView; @Controller public class HelloSpringMVC { @RequestMapping("/regist2.do") public ModelAndView regist2(Student student) throws Exception{ ModelAndView mv = new ModelAndView(); mv.addObject("username", student.getUsername()); mv.addObject("age", student.getAge()); mv.setViewName("result"); return mv; } }
index2.jsp前台页面
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>Title</title> </head> <body> <form action="${pageContext.request.contextPath}/regist2.do" method="post"> 姓名:<input type="text" name="username"><br> 年龄:<input type="text" name="age"><br> <input type="submit" value="提交"> </form> </body> </html>
还需要一个待跳转的jsp接收username和age比较简单这里就不再写了,只要与controller的setViewName对应即可。
通过这种方式,我们可以更方便的接收表单提交的数据了。
对象属性参数的接收
当请求中的参数是一个对象属性中的属性时,我们可以在表单中的name中写上对象属性.属性的方式进行处理。
定义一个School类:
package bean; public class School { private String schoolName; private String address; public String getSchoolName() { return schoolName; } public void setSchoolName(String schoolName) { this.schoolName = schoolName; } public String getAddress() { return address; } public void setAddress(String address) { this.address = address; } }
在Student类上将School对象属性添加上去:
package bean; public class Student { private String username; private int age; private School school; public School getSchool() { return school; } public void setSchool(School school) { this.school = school; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } }
修改index2.jsp:
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>Title</title> </head> <body> <form action="${pageContext.request.contextPath}/regist3.do" method="post"> 姓名:<input type="text" name="username"><br> 年龄:<input type="text" name="age"><br> 学校名:<input type="text" name="school.schoolName"><br> 地址:<input type="text" name="school.address"><br> <input type="submit" value="提交"> </form> </body> </html>
修改Controller类:
package controller; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import bean.Student; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.servlet.ModelAndView; @Controller public class HelloSpringMVC { @RequestMapping("/regist3.do") public ModelAndView regist3(Student student) throws Exception{ ModelAndView mv = new ModelAndView(); mv.addObject("username", student.getUsername()); mv.addObject("age", student.getAge()); mv.addObject("schoolName", student.getSchool().getSchoolName()); mv.addObject("address", student.getSchool().getAddress()); mv.setViewName("result"); return mv; } }
result.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>Title</title> </head> <body> 用户名:${name} <br> 年龄:${age} <br> 密码:${password} <br> 学校名称:${schoolName} <br> 学校地址:${address} </body> </html>
这样我们就完成了对象属性参数的接收。