SpringMVC中请求与响应

一、请求映射路径

当进行请求路径命名时,对于重名方法怎么解决路径冲突

创建一个Web的Maven项目,在pom.xml中添加相关依赖

<?xml version="1.0" encoding="UTF-8"?>

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>

  <groupId>org.example</groupId>
  <artifactId>SpringMVC_03</artifactId>
  <version>1.0-SNAPSHOT</version>
  <packaging>war</packaging>

  <name>SpringMVC_03 Maven Webapp</name>
  <!-- FIXME change it to the project's website -->
  <url>http://www.example.com</url>

  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <maven.compiler.source>16</maven.compiler.source>
    <maven.compiler.target>16</maven.compiler.target>
  </properties>

  <dependencies>
    <dependency>
      <groupId>javax.servlet</groupId>
      <artifactId>javax.servlet-api</artifactId>
      <version>3.1.0</version>
      <scope>provided</scope>
    </dependency>

    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-webmvc</artifactId>
      <version>5.3.0</version>
    </dependency>
  </dependencies>

  <build>
    <plugins>
      <plugin>
        <groupId>org.apache.tomcat.maven</groupId>
        <artifactId>tomcat7-maven-plugin</artifactId>
        <version>2.1</version>
        <configuration>
          <port>80</port>
          <path>/</path>
        </configuration>
      </plugin>
    </plugins>
  </build>
</project>

创建相应配置类

SpringMVCConfig

@Configuration
@ComponentScan("com.controller")
public class SpringMVCConfig {
}

ServletContrainerInitConfig

public class ServletContainersInitConfig extends AbstractAnnotationConfigDispatcherServletInitializer {
    @Override
    protected Class<?>[] getRootConfigClasses() {
        return new Class[0];
    }

    @Override
    protected Class<?>[] getServletConfigClasses() {
        return new Class[]{SpringMVCConfig.class};
    }

    @Override
    protected String[] getServletMappings() {
        return new String[]{"/"};
    }
}

创建两个控制类

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

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

删除WEB-INF下的web.xml文件,配置tomcat可见SpringMVC入门

项目结构如下

启动tomcat服务器,后台会如下错误

因为此时UserController有一个save方法,BookController也有一个save方法,访问路径都是http://localhost/save

对于这个问题,我们可以为不同模块设置模块名作为请求路径前置

对于Book模块的save,将其访问路径设置为http://localhost/book/save

对于User模块的save,将其访问路径设置http://localhost/user/save

  • 方法一、修改每个方法上的路径配置

UserController

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

BookController

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

此时便不存在路径重复的问题,但这种方法所有方法前面都要修改,耦合度太高,一般开发时采用下面一种方法

  • 方法二、在类上添加@RequestMapping注解

 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'}";
    }
}

BookController

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

在使用此种方法时,前端发送请求的时候,要和两个注解的value值相加匹配才能访问到

二、请求参数 

对于请求参数的传递和接收是和请求方式有关系的,比较常见的请求方式有两种,GET请求和POST请求

1.环境准备

创建一个web的Maven项目,在pom.xml中添加相关依赖

<?xml version="1.0" encoding="UTF-8"?>

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>

  <groupId>SpringMVC_05</groupId>
  <artifactId>SpringMVC_05</artifactId>
  <version>1.0-SNAPSHOT</version>
  <packaging>war</packaging>

  <name>SpringMVC_05 Maven Webapp</name>
  <!-- FIXME change it to the project's website -->
  <url>http://www.example.com</url>

  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <maven.compiler.source>16</maven.compiler.source>
    <maven.compiler.target>16</maven.compiler.target>
  </properties>

  <dependencies>
    <dependency>
      <groupId>javax.servlet</groupId>
      <artifactId>javax.servlet-api</artifactId>
      <version>3.1.0</version>
      <scope>provided</scope>
    </dependency>

    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-webmvc</artifactId>
      <version>5.3.0</version>
    </dependency>
  </dependencies>

  <build>
    <plugins>
      <plugin>
        <groupId>org.apache.tomcat.maven</groupId>
        <artifactId>tomcat7-maven-plugin</artifactId>
        <version>2.1</version>
        <configuration>
          <port>80</port>
          <path>/</path>
        </configuration>
      </plugin>
    </plugins>
  </build>
</project>

创建相应配置类

SpringMVCConfig

@Configuration
@ComponentScan("com.controller")
public class SpringMVCConfig {
}

ServletContainersInitConfig

public class ServletContainersInitConfig extends AbstractAnnotationConfigDispatcherServletInitializer {
    @Override
    protected Class<?>[] getRootConfigClasses() {
        return new Class[0];
    }

    @Override
    protected Class<?>[] getServletConfigClasses() {
        return new Class[]{SpringMVCConfig.class};
    }

    @Override
    protected String[] getServletMappings() {
        return new String[]{"/"};
    }
}

编写UserController

@Controller
public class UserController {
    @RequestMapping("/commonParam")
    @ResponseBody
    public String commonParam() {
        return "{'module':'commonParam'}";
    }
}

编写模型类

Address

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

    public String getProvince() {
        return province;
    }

    public void setProvince(String province) {
        this.province = province;
    }

    public String getCity() {
        return city;
    }

    public void setCity(String city) {
        this.city = city;
    }

    @Override
    public String toString() {
        return "Address{" +
                "province='" + province + '\'' +
                ", city='" + city + '\'' +
                '}';
    }
}

User

public class User {
    private String name;
    private int age;

    private Address address;

    public Address getAddress() {
        return address;
    }

    public void setAddress(Address address) {
        this.address = address;
    }

    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;
    }

    @Override
    public String toString() {
        return "User{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", province=" + address.getProvince() +
                ", city=" + address.getCity() +
                '}';
    }
}

项目结构如下

与上文同样删除web.xml,配置tomcat

2.GET发送参数

在UserController中设置接收参数

    @RequestMapping("/commonParam")
    @ResponseBody
    public String commonParam(@RequestParam("name") String username, int age) {
        System.out.println("普通参数传递 name -->" + username);
        System.out.println("普通参数传递 age -->" + age);
        return "{'module':'commonParam'}";
    }

@RequestParam解决前端传输参数名与后端定义的参数名不一致问题,否则需保持前端参数名和后端接收的形参名一致

启动tomcat服务器 

在apifox中发送请求与参数

此时控制台输出

name值产生了中文乱码,可通过修改pom.xml来解决GET请求中文乱码的问题

  <build>
    <plugins>
      <plugin>
        <groupId>org.apache.tomcat.maven</groupId>
        <artifactId>tomcat7-maven-plugin</artifactId>
        <version>2.1</version>
        <configuration>
          <port>80</port>
          <path>/</path>
          <!--解决发送get请求时中文乱码的问题-->
          <uriEncoding>UTF-8</uriEncoding>
        </configuration>
      </plugin>
    </plugins>
  </build>
<uriEncoding>设置访问路径编解码字符集

重启服务器,再次发送相同请求

此时控制台输出

2.POST发送参数

与上文UserController配置相同,启动服务器,在apifox中发送请求与参数

此时控制台输出

此时POST请求依旧产生中文乱码问题,可以通过配置过滤器解决 

在ServletContainersInitConfig配置类中添加如下方法

    //乱码处理
    protected Filter[] getServletFilters(){
        CharacterEncodingFilter filter = new CharacterEncodingFilter();
        filter.setEncoding("UTF-8");
        return new Filter[]{filter};
    }

此时重启服务器,发送相同数据

控制台输出如下

3.POJO数据类型参数

在UserController中添加接收POJO类型参数方法

请求参数与形参对象中的属性对应即可完成参数传递

    @RequestMapping("/pojoParam")
    @ResponseBody
    public String pojoParam(User user){
        System.out.println("pojo参数传递 user --> " + user.toString());
        return "{'module':'pojo param'}";
    }

由于User的toString方法为了更直观展现,使用了Address中的get,set方法,所以前端传参如未传address参数,则会报无address的错误

启动服务器,在apifox发送请求与参数

注意请求参数KEY的名称要与POJO中的属性名称一致,否则无法封装  

此时控制台输出

4.数组类型参数

在UserController中添加接收数组类型参数方法

    @RequestMapping("/arrayParam")
    @ResponseBody
    public String arrayParam(String[] likes){
        System.out.println("数组参数传递 likes --> " + Arrays.toString(likes));
        return "{'module':'array param'}";
    }

对于数组参数,只需请求参数名与形参对象属性名相同且请求参数为多个,定义数组类型即可接收参数

启动服务器,在apifox中发送请求与参数

此时控制台输出

5.集合类型参数

在UserController中添加接收集合类型参数方法

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

与接收数组类型相同,需保证请求参数名与形参对象属性名相同且请求参数为多个,即可接收数据

注意使用集合类型接收数据时,需使用@RequestParam注解绑定参数关系,如不使用@RequestParam注解,则在传输数据时会报错java.lang.IllegalStateException: No primary or single public constructor found for interface java.util.List - and no default constructor found either,这是因为SpringMVC将List看做是一个POJO对象来处理,将其创建一个对象并准备把前端的数据封装到对象中,但是List是一个接口无法创建对象,所以报错。

同名请求参数用@RequestParam注解映射到对应名称的集合对象中作为数据

启动服务器,在apifox中发送请求与参数

此时控制台输出

6.JSON数据传输参数

对于JSON数据类型,我们常见的有三种

  • JSON普通数组        ["value1","value2","values3",...]
  • JSON对象               {"key1":"value1","key2":"value2",...}
  • JSON对象数组        [{"key1":"value1",...},{"key2":"value2",...}]

以下将展示如何接收上述三种类型JSON数据

对于JSON数据,SpringMVC默认使用的是jackson来处理json的转换,所以需要在pom.xml添加jackson依赖

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

同时需在SpringMVC的配置类中开启SpringMVC的注解支持,这里面就包含了将JSON转换成对象的功能

@Configuration
@ComponentScan("com.controller")
//开启json数据类型自动转换
@EnableWebMvc
public class SpringMVCConfig {
}
  • JSON普通数组数据

在UserController中添加接收JSON普通数组类型参数方法

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

使用@RequestBody注解将外部传递的json数组数据映射到形参的集合对象中作为数据

启动服务器,在apifox中发送请求与参数

此时控制台输出

  • JSON对象数据

在UserController中添加接收JSON对象类型参数方法

    @RequestMapping("/listParamForJsonOb")
    @ResponseBody
    public String listParamForJSonOb(@RequestBody User user){
        System.out.println("list common(json)参数传递 likes --> " + user);
        return "{'module':'list common for jsonOb param'}";
    }

启动服务器,在apifox中发送请求与参数

此时控制台输出

  • JSON对象数组数据

在UserController中添加接收JSON对象数组类型参数方法

    @RequestMapping("/listParamForJsonObs")
    @ResponseBody
    public String listParamForJSonObs(@RequestBody List<User> list){
        System.out.println("集合参数传递 likes --> " + list);
        return "{'module':'list common for jsonObs param'}";
    }

启动服务器,在apifox中发送请求与参数

此时控制台输出

@RequestParam与@RequestBody的区别

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

7.日期类型参数

对于日期类型,我们有不同的输入方式

  • 1949/10/01
  • 1949-10-01
  • 10/01/1949
  • ......

对于这些日期格式,SpringMVC如何实现接收这些日期类型数据

在UserController类中添加方法,将参数设置为日期类型

    @RequestMapping("/dateParam")
    @ResponseBody
    public String dateParam(Date date,
                            @DateTimeFormat(pattern = "yyyy-MM-dd") Date date1,
                            @DateTimeFormat(pattern = "MM-dd-yyyy") Date date2,
                            @DateTimeFormat(pattern = "yyyy/MM/dd HH:mm:ss") Date date3) {
        System.out.println("日期参数传递 date " + date);
        System.out.println("日期参数传递 date1 " + date1);
        System.out.println("日期参数传递 date2 " + date2);
        System.out.println("日期参数传递 date3 " + date3);
        return "{'module':'date param'}";
    }

@DateTimeFormat:设定日期时间型数据格式 

启动服务器,在apifox中发送请求与参数

此时控制台输出

三、响应

对于响应,在SpringMVC接收到请求和数据后,将其转发给Service,或直接进行了一些处理,处理完之后,将结果返回给前端,主要包括响应页面与响应数据两部分

1.环境准备

创建一个web的Maven项目,在pom.xml中添加相关依赖

<?xml version="1.0" encoding="UTF-8"?>

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>

  <groupId>SpringMVC_06</groupId>
  <artifactId>SpringMVC_06</artifactId>
  <version>1.0-SNAPSHOT</version>
  <packaging>war</packaging>

  <name>SpringMVC_06 Maven Webapp</name>
  <!-- FIXME change it to the project's website -->
  <url>http://www.example.com</url>

  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <maven.compiler.source>16</maven.compiler.source>
    <maven.compiler.target>16</maven.compiler.target>
  </properties>

  <dependencies>
    <dependency>
      <groupId>javax.servlet</groupId>
      <artifactId>javax.servlet-api</artifactId>
      <version>3.1.0</version>
      <scope>provided</scope>
    </dependency>

    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-webmvc</artifactId>
      <version>5.3.0</version>
    </dependency>

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

  <build>
    <plugins>
      <plugin>
        <groupId>org.apache.tomcat.maven</groupId>
        <artifactId>tomcat7-maven-plugin</artifactId>
        <version>2.1</version>
        <configuration>
          <port>80</port>
          <path>/</path>
          <uriEncoding>UTF-8</uriEncoding>
        </configuration>
      </plugin>
    </plugins>
  </build>
</project>

创建相应的配置类

SpringMVCConfig

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

ServletContainersInitConfig

public class ServletContainersInitConfig extends AbstractAnnotationConfigDispatcherServletInitializer {
    @Override
    protected Class<?>[] getRootConfigClasses() {
        return new Class[0];
    }

    @Override
    protected Class<?>[] getServletConfigClasses() {
        return new Class[]{SpringMVCConfig.class};
    }

    @Override
    protected String[] getServletMappings() {
        return new String[]{"/"};
    }

    //乱码处理
    protected Filter[] getServletFilters(){
        CharacterEncodingFilter filter = new CharacterEncodingFilter();
        filter.setEncoding("UTF-8");
        return new Filter[]{filter};
    }
}

编写模型类User

public class User {
    private String name;
    private int 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;
    }

    @Override
    public String toString() {
        return "User{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}

编写UserController

@Controller
public class Usercontroller {

}

更改index.xml中输出内容

<html>
<body>
<h2>Hello SpringMVC!</h2>
</body>
</html>

与上文同样删除web.xml,配置tomcat

最终结构如下

2.响应页面

在UserController中添加跳转页面方法

@Controller
public class Usercontroller {
    @RequestMapping("/toJumpPage")
    public String toJumpPage(){
        System.out.println("跳转页面");
        return "index.jsp";
    }
}

此处不能添加@ResponseBody,如果加入了该注入,会直接将page.jsp当字符串返回前端

方法需要返回String 

启动服务器,在浏览器中访问http://localhost/toJumpPage

此时控制台输出

3.返回文本数据

在UserController中添加返回文本数据方法

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

重启服务器,在浏览器中访问http://localhost/toText

此时控制台输出

4.响应JSON数据

(1)、响应POJO对象

在UserController中添加响应POJO对象方法

    @RequestMapping("/toJsonPOJO")
    @ResponseBody
    public User toJsonPOJO(){
        System.out.println("返回json对象数据");
        User user = new User();
        user.setName("wangerhhh");
        user.setAge(21);
        return user;
    }

重启服务器,在浏览器中访问http://localhost/toJsonPOJO

此时控制台输出

(2)、响应POJO对象集合

在UserController中添加响应POJO对象集合方法

    @RequestMapping("/toJsonList")
    @ResponseBody
    public List<User> toJsonList(){
        System.out.println("返回json集合数据");
        User user1 = new User();
        user1.setName("王大");
        user1.setAge(22);

        User user2 = new User();
        user2.setName("王二");
        user2.setAge(21);

        List<User> userList = new ArrayList<User>();
        userList.add(user1);
        userList.add(user2);

        return userList;
    }

重启服务器,在浏览器中访问http://localhost/toJsonList

此时控制台输出

@ResponseBody:设置当前控制器返回值作为响应体

该注解可以写在类上或者方法上,写在类上就是该类下的所有方法都有@ResponseBody功能

当方法上有@ResponseBody注解后

  • 方法的返回值为字符串,会将其作为文本内容直接响应给前端
  • 方法的返回值为对象,会将对象转换成JSON响应给前端

对于类型转换,SpringMVC内部是通过Converter接口的实现类完成的

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值