Spring 学习总结笔记【十、SpringMVC数据响应与请求】

往期文章:

Spring 学习总结笔记【一、快速入门】
Spring 学习总结笔记【二、IoC-控制反转】
Spring 学习总结笔记【三、注解开发】
Spring 学习总结笔记【四、整合Junit】
Spring 学习总结笔记【五、配置数据源】
Spring 学习总结笔记【六、整合Mybatis】
Spring 学习总结笔记【七、AOP面向切面编程】
Spring 学习总结笔记【八、集成Web环境】
Spring 学习总结笔记【九、SpringMVC快速入门】

目录

  • 一、SpringMVC的数据请求
    • 1. 获得普通参数
      • 1. Get请求
      • 2. Post请求
      • 3. Post请求乱码处理
      • 4. 参数绑定注解@RequestParam
    • 2. 获得POJO类型参数
      • 1. Get请求
      • 2. Post请求
    • 3. 获得数组类型的参数
      • 1. Get请求
      • 2. Post请求
    • 4. 获得集合类型参数
      • 1. 简单集合类型参数获取
        • 1. Get请求
        • 2. Post请求
      • 2. 对象集合类型参数获取
  • 二、json数据传递参数
    • 1. 传递简单数据
      • 1. Get请求
      • 2. Post请求
    • 2. 传递POJO类型数据
      • 1. Get请求
      • 2. Post请求
    • 3. 传递对象集合类型数据
      • 1. Get请求
      • 2. Post请求
  • 三、日期类型参数传递
    • 1. 使用 @DateTimeFormat注解
    • 2. 自定义类型转换器
  • 四、SpringMVC的数据响应
    • 1. 页面跳转
      • 1. 页面跳转-返回字符串形式
      • 2. 页面跳转-返回ModelAndView形式
    • 2. 回显数据
      • 1. 回显数据-直接返回字符串
      • 2. 回显数据-回显json数据
      • 3. 回显数据-返回对象或集合
  • 五、RESTful风格参数的获取
    • 1. @PathVariable映射占位符
  • 六、获得Servlet相关API
  • 七、获得请求头消息
      • 1. @RequestHeader
      • 2. @CookieValue
  • 八、@RequestBody、@RequestParam、@PathVariable区别

一、SpringMVC的数据请求

  • 客户端请求参数的格式是:name=value&age=value2……
  • 服务器端要获得请求的参数,有时还需要进行数据的封装,SpringMVC可以接受的参数类型:
    ① 普通参数
    ② POJO类型参数 (实体bean)
    ③ 数组类型参数
    ④ 集合类型参数

1. 获得普通参数

Controller中的业务方法的参数名称要与请求参数的name一致,参数值会自动映射匹配。并且能自动做类型 转换;自动的类型转换是指从String向其他类型的转换。

@RequestMapping("/t1")
@ResponseBody // 表示不进行页面跳转 回写的数据为空
public void test1(String username, int age){
	System.out.println("username = " + username);
	// SpringMVC框架会自动将获取到的string类型的age转换为int类型的age
	System.out.println("age = " + age); 
}

1. Get请求

Spring 学习总结笔记【十、SpringMVC数据响应与请求】_第1张图片
Spring 学习总结笔记【十、SpringMVC数据响应与请求】_第2张图片


2. Post请求

Spring 学习总结笔记【十、SpringMVC数据响应与请求】_第3张图片
Spring 学习总结笔记【十、SpringMVC数据响应与请求】_第4张图片

  • Get请求普通传参:url地址传参,地址参数名与形参变量名相同,定义形参即可接受参数。
  • Post请求普通传参:form表单传参,表单参数名与形参变量名相同,定义形参即可接受参数。

3. Post请求乱码处理

可使用两种解决方法:
① 若Sprign基于xml配置,可在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>

② 若Spring基于注解开发,则可在SpringMVC核心配置类重写getServletFilters()方法:

public class ServletContainersInitConfig extends AbstractAnnotationConfigDispatcherServletInitializer {
	// Post请求乱码处理
	@Override
	protected Filter[] getServletFilters() {
		CharacterEncodingFilter filter = new CharacterEncodingFilter();
		filter.setEncoding("UTF-8");
		return new Filter[]{filter};
	}
}

4. 参数绑定注解@RequestParam

当请求的参数名称与Controller的业务方法参数名称不一致时,就需要通过@RequestParam注解显示的绑定 。

@RequestMapping("/t1")
public void test1(@RequestParam(value = "name",required = false,defaultValue = "tyt") String username, int age){
	System.out.println("username = " + username);
	System.out.println("age = " + age); 
}

Spring 学习总结笔记【十、SpringMVC数据响应与请求】_第5张图片Spring 学习总结笔记【十、SpringMVC数据响应与请求】_第6张图片

@RequestParam注解的三个属性:

  • value:请求参数名称
  • required :默认值为true, 表示是否必须要携带该参数
  • defaultValue:默认值,当设置了默认值那么required就会失效

2. 获得POJO类型参数

客户端发送的数据到达服务端之后,SpringMVC要将这些参数封装到一个实体类当中。原先我们要将请求参数封装到实体当中是怎样做的?通过getParamterMap获取参数map集合,然后通过beanUtils进行实体封装。SpringMVC框架封装了对实体封装的技术,我们只需要保证:

Controller中的业务方法的POJO参数的属性名与请求参数的name一致,参数值会自动映射匹配。

创建一个实体类User

package com.tyt.domain;

/**
 * @ClassName User
 * @Author 划水艺术家
 * @Date 2022/7/17 17:07
 * @Version 1.0
 **/
public class User {

	private  String name;
	private Integer age;
	private String sex;

	public User(){
	
	}
	
	public User(String name, Integer age, String sex) {
		this.name = name;
		this.age = age;
		this.sex = sex;
	}
	
	@Override
	public String toString() {
	return "User{" +
		   "name='" + name + '\'' +
		   ", age=" + age +
		   ", sex='" + sex + '\'' +
		   '}';
	}
	
	public String getName() {
		return name;
	}
	
	public void setName(String name) {
		this.name = name;
	}
	
	public Integer getAge() {
		return age;
	}
	
	public void setAge(Integer age) {
		this.age = age;
	}
	
	public String getSex() {
		return sex;
	}
	
	public void setSex(String sex) {
		this.sex = sex;
	}
}
@RequestMapping("/t2")
@ResponseBody // 表示不进行页面跳转 回写的数据为空
public void test2(User user) {
	System.out.println("user = " + user);
}

1. Get请求

Spring 学习总结笔记【十、SpringMVC数据响应与请求】_第7张图片在这里插入图片描述


2. Post请求

Spring 学习总结笔记【十、SpringMVC数据响应与请求】_第8张图片
在这里插入图片描述


3. 获得数组类型的参数

Controller中的业务方法数组名称与请求参数的name一致,参数值会自动映射匹配。

@RequestMapping("/t3")
@ResponseBody
public void test3(String[] array){
	System.out.println(Arrays.toString(array));
}

1. Get请求

Spring 学习总结笔记【十、SpringMVC数据响应与请求】_第9张图片

在这里插入图片描述


2. Post请求

Spring 学习总结笔记【十、SpringMVC数据响应与请求】_第10张图片在这里插入图片描述


4. 获得集合类型参数

1. 简单集合类型参数获取

简单类型:例如IntegerString等。

  • 请求参数名与形参集合对象名相同且请求参数为多个,@RequestParam注解绑定参数关系
@RequestMapping("/t4")
@ResponseBody
public void test4(@RequestParam List<String> list){
	System.out.println("list = " + list);
}
1. Get请求

Spring 学习总结笔记【十、SpringMVC数据响应与请求】_第11张图片
在这里插入图片描述


2. Post请求

Spring 学习总结笔记【十、SpringMVC数据响应与请求】_第12张图片
Spring 学习总结笔记【十、SpringMVC数据响应与请求】_第13张图片


2. 对象集合类型参数获取

对象集合不支持直接获取,可使用json数据传输。

二、json数据传递参数

使用json作为传输数据格式时,需要引入相关坐标。

<dependency>
	<groupId>com.fasterxml.jackson.coregroupId>
	<artifactId>jackson-databindartifactId>
	<version>2.12.1version>
dependency>
  • 若使用注解开发,则在SpringMVC配置类中加上注解@EnableWebMvc
@ComponentScan("com.tyt.controller")
@EnableWebMvc // 根据类型匹配对应的类型转换器
public class SpringMvcConfig {

}
  • 若基于xml配置开发,则在spring-mvc配置文件配置处理器适配器:
<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>
  • 当使用ajax或Postman提交时,必须指定Content-Typeapplication/json形式,在方法参数位置使用@RequestBody接收集合数据。
  • 当使用ajax或Postman提交时,必须指定Content-Typeapplication/json形式,在方法参数位置使用@RequestBody接收集合数据。
  • 当使用ajax或Postman提交时,必须指定Content-Typeapplication/json形式,在方法参数位置使用@RequestBody接收集合数据。

1. 传递简单数据

@RequestMapping(value = "/t5")
@ResponseBody
public void test5(@RequestBody List<String> list){
	System.out.println("list = " + list);
}

1. Get请求

Spring 学习总结笔记【十、SpringMVC数据响应与请求】_第14张图片
在这里插入图片描述


2. Post请求

Spring 学习总结笔记【十、SpringMVC数据响应与请求】_第15张图片
在这里插入图片描述


2. 传递POJO类型数据

@RequestMapping("/t6")
@ResponseBody 
public void test6(@RequestBody User user) {
	System.out.println("user = " + user);
}

1. Get请求

Spring 学习总结笔记【十、SpringMVC数据响应与请求】_第16张图片
在这里插入图片描述


2. Post请求

Spring 学习总结笔记【十、SpringMVC数据响应与请求】_第17张图片在这里插入图片描述


3. 传递对象集合类型数据

@RequestMapping(value = "/t7")
@ResponseBody
public void test7(@RequestBody List<User> userList){
	System.out.println("userList = " + userList);
}

1. Get请求

Spring 学习总结笔记【十、SpringMVC数据响应与请求】_第18张图片

在这里插入图片描述


2. Post请求

Spring 学习总结笔记【十、SpringMVC数据响应与请求】_第19张图片在这里插入图片描述

三、日期类型参数传递

  • 日期类型数据基于系统不同格式也不尽相同
    2013-03-20
    2013/03/20
    03/20/2013

1. 使用 @DateTimeFormat注解

  • 使用 @DateTimeFormat注解,根据不同日期格式设置不同的接受方式
@RequestMapping("/t8")
@ResponseBody
public void test8(Date date,
				@DateTimeFormat(pattern = "yyyy-mm-dd") Date date1,
				@DateTimeFormat(pattern = "yyyy-mm-dd hh:mm:ss") Date date2){
	System.out.println("date = " + date);
	System.out.println("date1 = " + date1);
	System.out.println("date2 = " + date2);
}

Spring 学习总结笔记【十、SpringMVC数据响应与请求】_第20张图片
Spring 学习总结笔记【十、SpringMVC数据响应与请求】_第21张图片


2. 自定义类型转换器

自定义类型转换器步骤:
① 定义转换器类实现Converter接口
② 声明引用转换器

① 定义转换器类实现Converter接口

package com.tyt.convert;

public class DateConverter implements Converter<String, Date> {
	public Date convert(String source) {
		// 将日期字符串转换成日期对象并返回
		SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
		Date date = null;
		try {
			date = simpleDateFormat.parse(source);
		} catch (ParseException e) {
			e.printStackTrace();
		}
		return date;
	}
}

若Spring基于xml配置
② 在配置文件中声明并引用转换器


<bean id="myConvert" class="org.springframework.context.support.ConversionServiceFactoryBean">
	<property name="converters" >
		<list>
			<bean class="com.tyt.convert.DateConverter"/>
		list>
	property>
bean>

<mvc:annotation-driven conversion-service="myConvert"/>

若Spring基于注解开发
② 定义类,注册转换器

@ControllerAdvice
public class DateConvertRegister {
	
	@Autowired
	private DateConverter dateConverter;

	@InitBinder
	public void dateBinder(WebDataBinder dataBinder){
		//1.获取转换服务对象
		ConversionService conversionService = dataBinder.getConversionService();
		//2.判断conversionService是否为GenericConversionService类型
		if(conversionService instanceof GenericConversionService){
			//3.强转
			GenericConversionService genericConversionService = (GenericConversionService)conversionService;
			//4.添加类型转换器
			genericConversionService.addConverter(dateConverter);
		}
	}
}

四、SpringMVC的数据响应

响应方式分为两种方式:

  • 页面跳转
    ① 直接返回字符串
    ② 通过ModelAndView对象返回
  • 回显数据
    ① 直接返回字符串
    ② 返回对象或集合

1. 页面跳转

1. 页面跳转-返回字符串形式

直接返回字符串:此种方式会将返回的字符串与视图解析器的前后缀拼接后跳转。

若基于xml配置


<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
	<property name="prefix" value="/WEB-INF/views/"/>
	<property name="suffix" value=".jsp"/>
bean>

若基于注解开发

@ComponentScan("com.tyt.controller")
@EnableWebMvc // 根据类型匹配对应的类型转换器
public class SpringMvcConfig{
	
	/**
	* 视图解析器
	*/
	@Bean(name="tnternalResourceViewResolver")
	public ViewResolver initViewResolver(){
		InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
		viewResolver.setPrefix("/WEB-INF/jsp/");
		viewResolver.setSuffix(".jsp"); 
		return viewResolver;
	}
}

Spring 学习总结笔记【十、SpringMVC数据响应与请求】_第22张图片


2. 页面跳转-返回ModelAndView形式

index.jsp代码:

<html>
	<body>
		<h2>Hello World!h2>
		<h1>${username}h1>
	body>
html>

① 设置视图、模型

// 设置当前操作访问路径
@RequestMapping("/test")
public ModelAndView test(){
	/*
	* model:模型,封装数据
	* view:视图,展示数据
	*/
	System.out.println("返回 modelAndView...");
	ModelAndView modelAndView = new ModelAndView();
	// 设置视图名称
	modelAndView.setViewName("index");
	// 设置模型数据
	modelAndView.addObject("username", "tyt");
	return modelAndView;
}

Spring 学习总结笔记【十、SpringMVC数据响应与请求】_第23张图片


② 在Controller中方法形参上直接声明ModelAndView,无需在方法中自己创建,在方法中直接使用该对象设置 视图,同样可以跳转页面

@RequestMapping("/test2")
public ModelAndView test2(ModelAndView modelAndView){
	modelAndView.addObject("username","tyt");
	modelAndView.setViewName("index");
	return modelAndView;
}

SpringMVC对方法的参数可以进行相应的注入,当解析该方法时发现需要一个ModelAndView 那么SpringMVC就会提供一个ModelAndView。


③ 只设置模型model ,返回字符串

@RequestMapping("/test3")
public String test3(Model model){
	// 设置模型
	model.addAttribute("username","tyt");
	// 返回逻辑视图名称
	return "index";
}

④ 在Controller方法的形参上可以直接使用原生的HttpServeltRequest对象,只需声明即可

@RequestMapping("/test4")
public String test4(HttpServletRequest request){
	request.setAttribute("username","tyt");
	// 返回逻辑视图名称
	return "index";
}

2. 回显数据

1. 回显数据-直接返回字符串

  • 通过SpringMVC框架注入的response对象,使用response.getWriter().print("") 回写数据,此时不需要视图跳转,业务方法返回值为void
  • 将需要回写的字符串直接返回,但此时需要通过@ResponseBody注解告知SpringMVC框架,方法返回的字符串不是跳转是直接在http响应体中返回
@RequestMapping("/test5")
// 设置当前操作返回值类型
public void  test5(HttpServletResponse response) throws IOException {
	response.getWriter().println("hello world");
}
@RequestMapping("/test6")
// 使用该注解 告知SpringMVC返回的字符串直接在响应体返回
@ResponseBody 
public String test6() {
	return "hello world";
}

2. 回显数据-回显json数据

@RequestMapping(value = "/test7")
@ResponseBody
public String test7() {
		// 引号需要进行转义
    return "{\"username\":\"tyt\",\"age\":20}";  
}

手动拼接json格式字符串的方式很麻烦,开发中往往要将复杂的Java对象转换成json格式的字符串,我们可以使用json转换工具fastjson进行转换。
导入fastjson相关坐标

<dependency>
	<groupId>com.alibabagroupId>
	<artifactId>fastjsonartifactId>
	<version>1.2.62version>
dependency>
// produces="text/html;charset=utf-8" 解决返回中文乱码问题
@RequestMapping(value = "/test8",produces="text/html;charset=utf-8")
@ResponseBody
public String  test8(HttpServletResponse response){
	User user = new User("tyt", 20, "男");
	// 将对象转换为 JSON 字符串
	String json = JSON.toJSONString(user);
	// 将 JSON 字符串转换为对象
	User user1 = JSON.parseObject(json, User.class);
	return json;
}

Spring 学习总结笔记【十、SpringMVC数据响应与请求】_第24张图片


3. 回显数据-返回对象或集合

@RequestMapping(value = "/test9")
@ResponseBody
public User  test9(HttpServletResponse response){
	User user = new User("tyt", 20, "男");
	return user;
}

通过SpringMVC帮助我们对对象或集合进行json字符串的转换并回写,为处理器适配器配置消息转换参数,指定使用jackson进行对象或集合的转换,因此需要做出以下配置:
① 导入 jackson 坐标

<dependency>
	<groupId>com.fasterxml.jackson.coregroupId>
	<artifactId>jackson-databindartifactId>
	<version>2.12.1version>
dependency>

② 有三种方法:

  • 方法一:在spring-mvc.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>
  • 方法二:在spring-mvc.xml文件中配置SpringMVC的注解驱动

<mvc:annotation-driven />

前提是要引入mvc的命名空间和约束路径
Spring 学习总结笔记【十、SpringMVC数据响应与请求】_第25张图片

  • 方法三:直接在UserController加上 @EnableWebMvc注解

@Controller
@EnableWebMvc // 根据类型匹配对应的类型转换器
public class UserController {

	@RequestMapping(value = "/test9")
	@ResponseBody
	public User  test9(HttpServletResponse response){
		User user = new User("tyt", 20, "男");
		return user;
	}
}

Spring 学习总结笔记【十、SpringMVC数据响应与请求】_第26张图片


五、RESTful风格参数的获取

Restful是一种软件架构风格、设计风格,而不是标准,只是提供了一组设计原则和约束条件。主要用于客户端和服务器交互类的软件,基于这个风格设计的软件可以更简洁,更有层次,更易于实现缓存机制等。


Restful风格的请求是使用“url+请求方式”表示一次请求目的,HTTP 协议里面四个表示操作方式的动词如下:

  • GET:用于获取资源
  • POST:用于新建资源
  • PUT:用于更新资源
  • DELETE:用于删除资源

  • 传统风格资源描述形式
    http://localhost/user/getById?id=1
    http://localhost/user/saveUser
  • REST风格描述形式
    http://localhost/user/1
    http://localhost/user
  • 优点:
    ① 隐藏资源的访问行为,无法通过地址得知对资源是何种操作
    ② 书写简化

Spring 学习总结笔记【十、SpringMVC数据响应与请求】_第27张图片

REST风格描述模块的名称通常使用复数,也就是加s的格式描述,表示此类资源,而非单个资源,例如:books、users…


1. @PathVariable映射占位符

上述url地址 http://localhost/user/1中的1就是要获得的请求参数,在SpringMVC中可以使用占位符进行参数绑定。地 址/user/1可以写成/user/{id},占位符{id}对应的就是1的值。在业务方法中我们可以使用@PathVariable注解进行占位符的匹配获取工作。

@RequestMapping("/t9/{id}")
@ResponseBody
public void test9(@PathVariable(value = "id") Integer id){
	System.out.println("id = " +id);
}

六、获得Servlet相关API

SpringMVC支持使用原始ServletAPI对象作为控制器方法的参数进行注入,常用的对象如下:

  • HttpServletRequest
  • HttpServletResponse
  • HttpSession
@RequestMapping("/t10")
public void test10(HttpServletRequest request, HttpServletResponse response, HttpSession session){
	System.out.println(request);
	System.out.println(response);
	System.out.println(session);
}


七、获得请求头消息

1. @RequestHeader

使用@RequestHeader可以获得请求头信息,相当于JavaWebz中的的request.getHeader(name)
@RequestHeader注解的属性如下:

  • value:请求头的名称
  • required:是否必须携带此请求头
@RequestMapping("/t10")
public void test10(@RequestHeader(value = "User-Agent",required = false) String userAgent){
	System.out.println(userAgent);
}

2. @CookieValue

使用@CookieValue可以获得指定Cookie的值。
@CookieValue注解的属性如下:

  • value:指定cookie的名称
  • required:是否必须携带此cookie
@RequestMapping("/t11")
public void test11(@CookieValue(value = "JSESSIONID") String jsessionID){
	System.out.println(jsessionID);
}

八、@RequestBody、@RequestParam、@PathVariable区别

  • 区别
    @RequestBody用于接受json数据【application/json】
    @RequestParam用于接受url地址传参,表单传参【application/x-www-form-urlencoded】
    @PathVariable用于接受路径参数,映射url绑定的占位符

  • 应用
    后期开发中,请求参数超过1个,以json格式数据为主,@RequestBody应用较广
    如果发送非json格式数据,选用@RequestParam接受请求参数
    采用RESTful进行开发,当参数数量较少,可以采用@PathVariable接受请求路径变量,通常用于传递id值

下期文章:
Spring 学习总结笔记【十一、SpringMVC拦截器】

你可能感兴趣的:(Spring,spring,后端,java,web)