SpringMVC的请求与响应【第二章】

  • ​🤪个人主页i笨笨i
  • 🐽版权:本文由【i笨笨i】原创,需要转载联系博主
  • 🎉欢迎关注、点赞、收藏(一键三连)和订阅专栏哦!
  • 一个系列哟
  • 初识SpringMVC【第一章】

三、请求与响应

3.1、请求映射路径

//BookController类
@Controller
public class BookController {
    @RequestMapping("/save")
    @ResponseBody
    public String save(){
        System.out.println("book save ...");
        return "{'module':'book save'}";
    }
}

//UserController类
@Controller
public class UserController {

    @RequestMapping("/save")
    @ResponseBody
    public String save(){
        System.out.println("user save ...");
        return "{'module':'user save'}";
    }

    @RequestMapping("/delete")
    @ResponseBody
    public String delete(){
        System.out.println("user delete ...");
        return "{'module':'user delete'}";
    }

}

​ 我们可以发现BookController类和UserController类都有@RequestMapping("/save")/save路径,即路径重复。

❓团队多人开发,每个人设置不同的请求路径,冲突问题如何解决?

解决方法:设置模块名作为请求路径前缀

//BookController类
@Controller
@RequestMapping("/book")
public class BookController {
    
    @RequestMapping("/save")
    @ResponseBody
    public String save(){
        System.out.println("book save ...");
        return "{'module':'book save'}";
    }
}

//UserController类
@Controller
@RequestMapping("/user")
public class UserController {

    @RequestMapping("/save")
    @ResponseBody
    public String save(){
        System.out.println("user save ...");
        return "{'module':'user save'}";
    }

    @RequestMapping("/delete")
    @ResponseBody
    public String delete(){
        System.out.println("user delete ...");
        return "{'module':'user delete'}";
    }
    //statement....
}
3.1.1、@RequestMapping注解

名称:@RequestMapping

类型:方法注解,类注解

位置:SpringMVC控制器 方法/类 定义上方

作用:设置当前控制器方法请求访问路径,如果设置在类上统一设置当前控制器方法请求访问路径前缀

属性:value(默认):请求访问路径或访问路径前缀

  • 范例
@Controller
@RequestMapping("/book")
public class BookController {
    @RequestMapping("/save")
    @ResponseBody
    public String save(){
        System.out.println("book save ...");
        return "{'module':'book save'}";
    }
}
3.1.2、请求方式
3.1.2.1、Get请求
  • 普通参数:URL地址传参,地址参数名与形参变量名相同,定义形参即可介绍参数。

@Controller
public class UserController {
    @RequestMapping("/commonParam")
    @ResponseBody
    public String commonParam(String name,int age){
        System.out.println("普通参数传递 name ==> " + name+":"+age);
        return "{'module':'common param'}";
    }
}
3.1.2.2、Post请求
  • 普通参数:form表单post请求传参,表单参数名与形参变量名相同,定义形参即可接收参数

@Controller
public class UserController {
    @RequestMapping("/commonParam")
    @ResponseBody
    public String commonParam(String name,int age){
        System.out.println("普通参数传递 name ==> " + name+":"+age);
        return "{'module':'common param'}";
    }
}
3.1.2.3、请求中文乱码处理

❓GET方式解决中文乱码问题

直接设置Tomcat目录下conf/server.xml找到标签,加入URIEncoding=“UTF-8”。

    <Connector port="8080" protocol="HTTP/1.1"
               connectionTimeout="20000"
               redirectPort="8443" 
               URIEncoding="UTF-8"/>

❓POST方式解决中文乱码问题

  • 为web容器添加过滤器并指定字符集,Spring-web包中提供了专用的字符过滤器
public class ServletContainersInitConfig extends AbstractAnnotationConfigDispatcherServletInitializer {
    //其他方法省略

    //乱码处理(配字符编码过滤器)
    @Override
    protected Filter[] getServletFilters() {
        CharacterEncodingFilter filter = new CharacterEncodingFilter();
        filter.setEncoding("UTF-8");
        return new Filter[]{filter};
    }
}
  • 配置web.xml文件进行设置
<!-- 配置编码过滤器CharacterEncodingFilter,解决中文乱码问题 -->
<filter>
    <filter-name>characterEncodingFilter</filter-name>
    <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
    <!-- 设置CharacterEncodingFilter类中 encoding属性-->
    <init-param>
        <param-name>encoding</param-name>
        <param-value>UTF-8</param-value>
    </init-param>

    <!--设置CharacterEncodingFilter的forceRequestEncoding和forceResponseEncoding属性(是boolean类型),
    setForceEncoding方法可以同时设置两个属性。
    -->
    <init-param>
        <param-name>forceEncoding</param-name>
        <param-value>true</param-value>
    </init-param>
</filter>
<!-- 拦截哪些请求进行过滤 -->
<filter-mapping>
    <filter-name>characterEncodingFilter</filter-name>
    <!-- 拦截规则
    <servlet-name>具体指定哪个servlet(已配置的servlet)
    <url-pattern>根据URL请求进行匹配
    -->
    <servlet-name>springmvc</servlet-name>
</filter-mapping>
3.1.3、静态资源的访问

当页面中包含静态资源的时候我们能够正确的获取到吗?

3.1.3.1、存在问题

❓项目不能访问静态资源原因:配置DisapatcherServlet<url-pattern>/</url-pattern>servlet容器启动的配置类内设置拦截路径 /,DispatcherServlet 会将向静态资源的获取请求,例如.css、.js、.jpg、.png等资源的获取请求,当作是一个普通的 Controller 请求。中央调度器会调用处理器映射器为其查找相应的处理器。当然也是找不到的,所以在这种情况下,所有的静态资源获取请求也均会报 404 错误。

解决方式:

  1. 使用<mvc:default-servlet-handler />并声明注解驱动
  2. 使用<mvc:resources />并声明注解驱动(推荐

Snipaste_2022-08-26_14-42-57

3.1.3.2、基于SpringMVC的XML配置文件
  1. 使用<mvc:default-servlet-handler />并声明注解驱动
  2. 使用<mvc:resources />并声明注解驱动(推荐

注意事项:

mvc的命名空间的开启,xmlns:mvc的开启以及xsi:schemaLocation添加的内容。

<?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.xsd
       http://www.springframework.org/schema/context
       https://www.springframework.org/schema/context/spring-context.xsd
       http://www.springframework.org/schema/mvc
       https://www.springframework.org/schema/mvc/spring-mvc.xsd">

    <context:component-scan base-package="com.item"/>

    <!-- 配置访问静态资源 -->
    <mvc:annotation-driven/>

<!--
方式二:
    将映射的地址直接指向静态资源文件夹,SpringMVC将不会将此映射作为handler。
    mapping="/images/**" 表示需要映射的URL地址
    /images/**表示将images包下的所以路径所以资源映射到location

    location="/images/"  表示映射到哪个位置,
    /images/表示映射到images包下
-->
    <mvc:resources mapping="/images/**" location="/images/"/>

<!--
方式一:
    当SpringMVC 没有映射到某一个请求的时候,就会默认servlet处理
    <mvc:default-servlet-handler/>
-->
</beans>
3.1.3.3、基于SpringMVC的纯注解驱动【拦截器】

静态资源在web目录下images包下的01.png文件

Snipaste_2022-08-26_15-17-22

  • 配置WebMvcConfigurationSupport类的实现类。(SpringMvcSupport)

在SpringMVC的配置类中加入@EnableWebMvc相当于XML方式中的<mvc:annotation-driven />,@ComponentScan注解扫描此类使其加载,添加拦截器使用addResourceHandlers方法将=="/images/**"请求路径映射到/images/==目录下。

@Configuration
public class SpringMvcSupport extends WebMvcConfigurationSupport {
    @Override
    protected void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/images/**").addResourceLocations("/images/");
    }
}

3.2、请求参数

  • 参数种类
    • 普通参数
    • POJO类型参数
    • 嵌套POJO类型参数
    • 数组类型参数
    • 集合类型参数
3.2.1、普通参数

URL地址传参,地址参数名与形参变量名相同,定义形参即可接收参数

//普通参数:请求参数名和形参不同
@RequestMapping("/commonParam")
@ResponseBody
public String commonParamDifferentName(String name, int age){
	System.out.println("名字:"+userName+",年龄:"+age);
	return "{'module':'common param different name'}";
}

URL地址传参,请求参数名与形参变量名不同,使用@RequestParam注解绑定关系

//普通参数:请求参数名和形参不同
@RequestMapping("/commonParamDifferentName")
@ResponseBody
public String commonParamDifferentName(
    		@RequestParam("name") String userName, int age){
	System.out.println("名字:"+userName+",年龄:"+age);
	return "{'module':'common param different name'}";
}
3.2.1.1、从GET请求路径上获取参数

​ 在形参前使用@PathVariable注解,在@RequestMapping注解映射的路径上有占位符并且有名称,在@PathVariable注解里填写从路径上读取数据的名称,并且赋值给被注解的内容。

@RequestMapping("/user/{id}")
@ResponseBody
public String path01(@PathVariable("id") Integer id){
    System.out.println(id);
    return "{'module':'path'}";
}
3.2.1.2、@RequestParam注解

名称:@RequestParam

类型:形参注解

位置:SpringMVC控制器方法形参定义前面

作用:绑定请求参数与处理器方法形参间的关系

参数:

  • required:是否为必传参数
  • defaultValue:参数默认值(重命名)
  • 范例
//普通参数:请求参数名和形参不同
@RequestMapping("/commonParamDifferentName")
@ResponseBody
public String commonParamDifferentName(
    		@RequestParam("name") String userName, int age){
	System.out.println("名字:"+userName+",年龄:"+age);
	return "{'module':'common param different name'}";
}
3.2.2、POJO类型参数

POJO参数:请求参数名与形参对象属性名相同,定义POJO类型形参即可接收

  • 请求参数与POJO类的属性名相同,则会自动封装成User对象

//POJO参数
@RequestMapping("/pojoParam")
@ResponseBody
public String pojoParam(User user) {
	System.out.println("pojo参数:"+user);
	return "{'module':'pojo param'}";
}
3.2.3、嵌套POJO类型参数
  • 嵌套POJO参数:POJO对象中包含POJO对象
public class User {
    private String name;
    private int age;
    private Address address;//引用类型
}

public class Address {
    private String province;
    private String city;
}

嵌套POJO参数:请求参数名与形参对象属性名相同,按照对象层次结构关系即可接收嵌套POJO属性参数。

//嵌套POJO
@RequestMapping("/pojoContainPojoParam")
@ResponseBody
public String pojoContainPojoParam(User user) {
	System.out.println("嵌套pojo:"+user);
	return "{'module':'pojo contain pojo param'}";
}
3.2.4、数组类型参数

请求参数名与形参对象属性名相同且请求参数多个,定义数组类型形参即可接收参数。相同的key则会向同一个数组里放。

//数组参数
@RequestMapping("/arrayParam")
@ResponseBody
public String arrayParam(String[] likes) {
	System.out.println("数组参数:"+ Arrays.toString(likes));
	return "{'module':'array param'}";
}
3.2.5、集合类型参数

集合保存普通参数:请求参数名与形参集合对象名相同且请求参数为多个,@RequestParam绑定参数关系。必须再集合参数前加上@RequestParam注解,不然框架会认为likes是POJO对象,向其中注入属性而不是直接放入。

//集合参数
@RequestMapping("/listParam")
@ResponseBody
public String listParam(@RequestParam List<String> likes){
	System.out.println("集合参数:"+likes);
	return "{'module':'list param'}";
}

3.3、日期类型参数传递

  • 日期类型数据基于系统不同格式也不尽相同

    • 2088-08-18
    • 2088/08/18(Date类的标准格式)
    • 08/18/2088
  • 接收形参时,根据不同的日期格式设置不同的接收方法

@RequestMapping("/dataParam")
@ResponseBody
public String dataParam(Date date,
		@DateTimeFormat(pattern = "yyyy-MM-dd") Date date1,
		@DateTimeFormat(pattern = "yyyy/MM/dd HH:mm:ss") Date date2) {
	System.out.println("dataParam:"+date);
	System.out.println("dataParam(yyyy-MM-dd):"+date1);
	System.out.println("dataParam(yyyy/MM-dd HH:mm:ss):"+date2);
	return "{'module':'data param'}";
}
3.3.1、@DateTimeFormat注解

名称:@DateTimeFormat

类型:形参注解

位置:SpringMVC控制器方法形参前面

作用:设定日期时间型数据格式

属性:pattern:日期时间格式字符串

  • 范例
@RequestMapping("/dataParam")
@ResponseBody
public String dataParam(Date date,
		@DateTimeFormat(pattern = "yyyy-MM-dd") Date date1,
		@DateTimeFormat(pattern = "yyyy/MM/dd HH:mm:ss") Date date2) {
	System.out.println("dataParam:"+date);
	System.out.println("dataParam(yyyy-MM-dd):"+date1);
	System.out.println("dataParam(yyyy/MM-dd HH:mm:ss):"+date2);
	return "{'module':'data param'}";
}
3.3.2、类型转换器(Converter)
  • Converter接口
package org.springframework.core.convert.converter;
import org.springframework.lang.Nullable;

@FunctionalInterface
public interface Converter<S, T> {
    @Nullable
    T convert(S var1);
}

请求参数年龄数据(String->String)

日期格式转换(String->Date)

有些转换功能不是默认开启,需要加上@EnableWebMvc注解。(根据类型匹配对应的类型转换器)

3.4、响应json数据

  • 传递json数据
    • json数组
    • json对象(POJO)
    • json数组(POJO)

1️⃣添加json数据转换相关坐标

<dependency>
	<groupId>com.fasterxml.jackson.core</groupId>
	<artifactId>jackson-databind</artifactId>
	<version>2.9.0</version>
</dependency>

2️⃣设置发送json数据(请求body中添加json数据)

选择Body,点击raw,再选JSON即可。

3️⃣开启自动转换json数据支持

@Configuration
@ComponentScan("com.item.controller")
@EnableWebMvc
public class SpringMvcConfig {
}

注意事项:@EnableWebMvc注解功能强大,盖注解整合了多个功能,此处仅使用其中一部分功能,即json数据进行自动转换。

4️⃣设置接收json数据

@RequestMapping("/listParamForJson")
@ResponseBody
public String listParamForJson(@RequestBody List<String> likes) {
	System.out.println("集合参数:json格式"+likes);
	return "{'module':'list common for json param'}";
}

以下三种方式发送数据:

  • json数组

@RequestMapping("/listParamForJson")
@ResponseBody
public String listParamForJson(@RequestBody List<String> likes) {
	System.out.println("集合参数:json格式"+likes);
	return "{'module':'list common for json param'}";
}
  • POJO参数:json数据与形参对象属性名相同,定义POJO类型形参即可接收参数

@RequestMapping("/pojoParamForJson")
@ResponseBody
public String pojoParamForJson(@RequestBody User user) {
	System.out.println("pojoParamForJson:"+user);
	return "{'module':'pojo for json param'}";
}
  • POJO集合参数:json数组数据与集合泛型属性名相同,定义List类型形参即可接收参数

@RequestMapping("/listPojoParamForJson")
@ResponseBody
public String listPojoParamForJson(@RequestBody List<User> list){
	System.out.println("listPojoParamForJson:"+list);
	return "{'module':'lis pojo for json param'}";
}
3.4.1、@EnableWebMvc注解

名称:@EnableWebMvc

类型:配置类注解

位置:SpringMVC配置类定义上方

作用:开启SpringMVC多项辅助功能

  • 范例
@Configuration
@ComponentScan("com.item.controller")
@EnableWebMvc
public class SpringMvcConfig {
}
3.4.2、@RequestBody注解

名称:@EnableWebMvc

类型:形参注解

位置:SpringMVC控制器方法形参定义前面

作用:将请求中请求体所包含的数据传递给请求参数,此注解一个处理器方法只能使用一次。

@RequestMapping("/listPojoParamForJson")
@ResponseBody
public String listPojoParamForJson(@RequestBody List<User> list){
	System.out.println("listPojoParamForJson:"+list);
	return "{'module':'lis pojo for json param'}";
}
3.4.3、@RequestBody与@RequestParam区别
  • 区别

    • @RequestBody用于接收json数据【application/json】
    • @RequestParam用于接收URL地址传参,表单传参【application/x-www-form-urlencoded】
  • 应用

    • 后期开发中,发送json格式数据为主,@RequestBody应用较广

    • 如果发送非json格式数据,选用@RequestParam接收请求参数

      3.5、响应

  • 响应页面

  • 响应数据

    • 文本数据
    • JSON数据
3.5.1、响应页面
  • 页面
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
	<h2>Hello Spring MVC!</h2>
</body>
</html>
  • 代码(Controller代码)
@RequestMapping("/toJumpPage")
public String toJumpPage(){
System.out.println("跳转页面");
return "page.jsp";
}

方法默认返回字符串,这个字符串代表需要访问的页面。

3.5.2、响应文本数据

Snipaste_2022-08-22_11-59-17

@RequestMapping("/toText")
@ResponseBody
public String toText(){
	System.out.println("返回纯文本数据");
	return "response text";
}

此处要加上@ResponseBody注解,否则认为返回字符串是页面的名称。

3.5.3、响应json数据(对象转json)

Snipaste_2022-08-22_12-00-22

@RequestMapping("/toJsonPOJO")
@ResponseBody
public User toJsonPOJO(){
    //jackson-databind坐标帮忙转成json
    System.out.println("返回json对象数据");
    User user = new User();
    user.setName("itcast");
    user.setAge(15);
    return user;
}

jackson-databind坐标帮忙转成json。此处要加上@ResponseBody注解,否则认为返回字符串是页面的名称。

3.5.4、响应json数据(对象集合转json数组)

Snipaste_2022-08-22_12-00-57

@RequestMapping("/toJsonList")
@ResponseBody
public List<User> toJsonList(){
    System.out.println("返回json集合数据");
    User user1 = new User();
    user1.setName("哈哈");
    user1.setAge(15);
    User user2 = new User();
    user2.setName("啊啊");
    user2.setAge(20);
    
    List<User> userList = new ArrayList<>();
    userList.add(user1);
    userList.add(user2);
    return userList;
}

此处要加上@ResponseBody注解,否则认为返回字符串是页面的名称。

3.5.5、@ResponseBody注解

名称:@ResponseBody

类型:方法注解

位置:SpringMVC控制器方法定义上方

作用:

  • 设置当前控制器方法响应内容为当前返回值,无需解析
  • 设置当前控制器返回值作为响应体(此处是这个)
  • 范例
@RequestMapping("/save")
@ResponseBody
public String save(){
	System.out.println("返回纯文本数据");
	return "{'info':'springmvc'}";
}
3.5.6、类型转换器(HttpMessageConverter)

HttpMessageConverter此接口的子类实现了json转换为HTTP消息。框中的是具体实现类。

Snipaste_2022-08-22_11-58-02

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值