参数绑定以及灵活的数据响应也是spring-mvc的一大特色。
参数绑定能让开发人员省去封装的步骤,直接从前端页面获取想要的数据。如前端页面的参数和后端实体类的属性一样,则可以直接返回实体类对象。
灵活的数据响应同样将页面的跳转和所携带的数据进行封装,通过视图解析器解析后返回视图,简化了开发。可以自由的选择返回类型,可以是对象,可以是json类型。
spring-mvc在Controller类的方法上声明数据类型的形参,可以直接调用形参,如果是pojo类也可以直接封装,这都得益于独特的spring-mvc的类型转换器,他可以从请求中获取传递的参数,通过比对pojo类型中的属性,如果字段对应的话,则自动封装进pojo类对象中。
从浏览器通过get请求传来的键值对的数据,可以直接根据参数类型直接进行接收,要注意前端传入的参数名和方法形参上的参数名要一致,如果不一致需要使用@RequestParam注解接收指定的数据
@ResponseBody
@RequestMapping("/test") //指定一个请求路径
public void test(@RequestParam("username") String name){
System.out.println(name);
}
请求路径: http://localhost:8080/test?username=lisi
控制台打印
接收两个参数也是相同的,只要形参和前端数据的键值相同,就可以不用指定@RequestParam()
@ResponseBody
@RequestMapping("/test") //指定一个请求路径
public void test(String name, int age){
System.out.println(name);
System.out.println(age);
}
请求路径: http://localhost:8080/test?name=lisi&age=18
控制台输出
当前端使用post请求发送对象数据,如果前端传来的数据名pojo类中的属性名相同,spring-mvc会将数据自动封装到pojo类的属性中,如果传入的有pojo对象和其他参数,要注意如果其他参数与对象中的属性名一样时,两个都会被赋值。
@ResponseBody
@RequestMapping("/test") //指定一个请求路径
public void test(User user, String name) {
// 同时接受实体类和一个姓名
System.out.println(user);
System.out.println(name);
}
User类
package com.dyh.pojo;
public class User {
private String name;
private int age;
@Override
public String toString() {
return "User{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
接收前端传入的数组,直接在方法参数上定义和前端传入的数组名一样即可。
@ResponseBody
@RequestMapping("/test") //指定一个请求路径
public void test(String[] names) {
System.out.println(Arrays.toString(names));
}
后端方法参数列表中直接用List接收的话,必须前端传的是json类型的数据,并且后端参数前要加@RequestBody注解,声明接收的是字符串类型。在pom.xml中要加入jackson依赖
<dependency>
<groupId>com.fasterxml.jackson.coregroupId>
<artifactId>jackson-databindartifactId>
<version>2.9.8version>
dependency>
后端控制器
@ResponseBody
@RequestMapping("/test") //指定一个请求路径
public void test(@RequestBody List users) {
System.out.println(users);
}
请求体
运行结果
还有一种方法是封装一个VO类,将list集合封装进去
VO类
package com.dyh.pojo;
import java.util.List;
public class VO {
private List<User> userList;
@Override
public String toString() {
return "VO{" +
"userList=" + userList +
'}';
}
public List<User> getUserList() {
return userList;
}
public void setUserList(List<User> userList) {
this.userList = userList;
}
}
在postman中使用form表单进行数据提交,但是这个提交方式比较特别,在现实开发中很少这样使用,在此只是模拟。
后端控制器
@ResponseBody
@RequestMapping("/test") //指定一个请求路径
public void test(VO vo) {
System.out.println(vo);
}
同时后端控制器的方法参数列表上不但可以直接接收前端传的数据,同时也可以获得传统的servlet的相关API,同样可以使用原始的方式接收参数或者获取域对象向里面赋值。
@ResponseBody
@RequestMapping("/test") //指定一个请求路径
public void test(HttpServletRequest request, HttpServletResponse response, HttpSession session) {
System.out.println(request);
System.out.println(response);
System.out.println(session);
}
SpringMVC 默认已经提供了一些常用的类型转换器,例如客户端提交的字符串转换成int型进行参数设置。
但不是所有的数据类型都提供了转换器,没有提供的就需要自定义转换器,例如:日期类型的数据就需要自定义转换器。
public class DateConverter implements Converter<String, Date> {
public Date convert(String dateStr) {
//将日期字符串转换成日期对象
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
Date date = null;
try {
date = format.parse(dateStr);
} catch (ParseException e) {
e.printStackTrace();
}
return date;
}
}
配置里要加入以下配置,用来配置类型转换器
<bean id="conversionService" class="org.springframework.context.support.ConversionServiceFactoryBean">
<property name="converters">
<list>
<bean class="com.itheima.converter.DateConverter">bean>
list>
property>
bean>
<mvc:annotation-driven conversion-service="conversionService"/>
post请求是会出现乱码问题的,为了避免乱码问题,可以使用编码过滤器进行过滤,spring提供了一个编码过滤器CharacterEncodingFilter,只需要在web.xml中配置就能达到过滤字符编码问题
<filter>
<filter-name>CharacterEncodingFilterfilter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilterfilter-class>
<init-param>
<param-name>encodingparam-name>
<param-value>UTF-8param-value>
init-param>
filter>
<filter-mapping>
<filter-name>CharacterEncodingFilterfilter-name>
<url-pattern>/*url-pattern>
filter-mapping>
视图解析器用来解析数据,拿到数据渲染页面,同时我们可以指定一些属性用来简化我们的开发。
简化跳转路径
配置视图解析器
配置默认跳转的前缀和后缀,可以直接写页面名称
<mvc:view-resolvers>
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="suffix" value=".jsp"/>
<property name="prefix" value="/pages/"/>
bean>
mvc:view-resolvers>
在配置完视图解析器的情况下,返回字符串会默认是跳转到和字符串匹配的页面
除默认直接用return "test";
以外,转发可以使用return "forward:/pages/test.jsp";
重定向可以使用return "redirect:/pages/test.jsp"
注意:当使用return "forward:/pages/test.jsp";
或者return "redirect:/pages/test.jsp";
的时候,视图解析器不生效,必须从根目录开始指定路径
后端控制器(形式1)
@RequestMapping("/test") //指定一个请求路径
public String test() {
return "test";
}
后端控制器(形式2)
@RequestMapping("/test") //指定一个请求路径
public String test() {
return "forward:/pages/test.jsp";
}
后端控制器(形式3)
@RequestMapping("/test") //指定一个请求路径
public String test() {
return "redirect:/pages/test.jsp";
}
返回json数据必须在方法上增加@ResponseBody注解,声明返回值不再是跳转页面而是字符串类型,然后可以手动拼接json字符串返回或者利用第三放jar包jackson转换为json数据。
spring内部也集成了jackson的json转换功能,有两种配置方法
xml配置
<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter">
<property name="messageConverters">
<list>
<bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter"/>
list>
property>
bean>
或者使用
这样返回的无论是集合,数组,pojo类,都会自动转换为json字符串返回。
@RequestMapping("/test") //指定一个请求路径
@ResponseBody
public User test() {
User user = new User();
user.setName("zhangsan");
user.setAge(15);
return user;
}
ModleAndView用于封装回应的数据和返回的视图名,最后方法返回modleAndView对象,视图解析器将会自动解析并返回给view展示给用户。
@RequestMapping("/test") //指定一个请求路径
public ModelAndView test(ModelAndView modelAndView) {
User user = new User();
user.setName("zhangsan");
user.setAge(15);
modelAndView.addObject("user",user);
modelAndView.setViewName("test");
return modelAndView;
}
还有第二种转发形式,使用Model装入要响应的数据,使用return转发页面。
@RequestMapping("/test") //指定一个请求路径
public String test(Model model) {
User user = new User();
user.setName("zhangsan");
user.setAge(15);
model.addAttribute("user",user);
return "test";
}
这种方法同样可以达到上面的效果,只是展示的形式不一样,用哪种形式还凭个人爱好。