SpringMVC的返回值和参数类型

Posted 你这家伙

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了SpringMVC的返回值和参数类型相关的知识,希望对你有一定的参考价值。

传统的基于Spring Framework的web开发需要大量的 xml 配置,在有SpringBoot以后,Web开发的效
率得到了很大的提升,几乎大部分配置可以使用默认约定的规则。我们基于SpringBoot的项目来进行
SpringMVC的学习

概述

SpringMVC框架围绕 DispatcherServlet(前端控制器) 这个核心展开, DispatcherServlet 是SpringMVC框架的总导演、总策划,它负责截获请求并将其分派给相应的处理器处理。

MVC设计模式介绍
MVC(Model View Controller)是软件工程中的一种软件模式,他把软件系统分为模型、视图、控制器三个基本部分

Model(模型):是应用程序中用于处理应用程序数据逻辑的部分(通常模型对象负责在数据库中存储数据)
View(视图):是应用程序处理数据显示的部分(通常视图是依据模型数据创建)
Controller(控制器):是应用程序中处理用户交互的部分(通常负责从视图读取数据,控制用户输入,并向模型发送数据)

SpringMVC的使用

如:先在 src/main/resources/static 目录中,创建index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>首页</title>
    <script src="index.js"
            type="application/javascript">

    </script>
</head>
<body>

<h1>hello world!!!</h1>
</body>
</html>
  1. @Controller的使用和RequestMapping的使用

@Controller
解标注是一个类的Web控制器,其和Component注解等价,只不过在Web层使用,便于区分类的作用

@ReqestMapping
在对SpringMVC进行配置的时候,需要指定请求与处理方法之间的映射关系,这时候就需要使用
@RequestMapping注解。该注解可以在控制器类的级别和其方法级别上使用

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;

@Controller
@RequestMapping("/user")
public class UserController 
    
    @RequestMapping("/login")
    public String wb()
        return "redirect:/index.html";
    

也可以单独只在方法上使用@RequestMapping

@Controller
public class UserController 

    @RequestMapping("/login")
    public String wb()
        return "redirect:/index.html";
    

注意:@RequestMapping注解能够处理的HTTP请求方法有: GET, HEAD, POST, PUT, PATCH, DELETE, OPTIONS, TRACE
为了能够将一个请求映射到一个特定的HTTP方法,你需要在@RequestMapping中使用method参数声
明HTTP请求所使用的方法类型。如下示例,在 UserController 中添加请求映射方法

@Controller
public class UserController 

    @RequestMapping(value = "/login",method = RequestMethod.GET)
    public String wb()
        return "redirect:/index.html";
    


控制器方法的返回

String返回类型

  1. 返回 URI 资源路径的字符串,可以使用 redirect:/服务路径 表示重定向到某个路径,forward:/服务路径 表示转发到某个路径,如果前边不写默认就是转发(可参考上面的例子)。
  2. @RequestMapping结合@ResponseBody,返回的字符串会作为响应体内容。此时响应的Content-Type为 text/plain 普通文本。
    @RequestMapping("/login2")
    @ResponseBody
    public String test()
        return "你好,世界";
    

返回普通的Java类型

  • 返回类型为Object,一般使用带Getter,Setter方法的模型类
  • 结合@ResponseBody使用,表示将对象序列化后的数据放在响应体返回
  • 在SpringBoot中默认响应的Content-Type为 application/json
  • 非字符串对象会自动序列化为 json 字符串
    @RequestMapping("/login3")
    @ResponseBody
    public Object test1()
        Map<String,Object> map = new HashMap<>();
        map.put("1","李逵");
        map.put("2",123);
        map.put("3","abc");
        return map;
    

组合注解

可以使用组合注解来完成同时定义多个注解的效果,如:@RestController,@GetMapping,@PostMapping

如:当我们查看@RestController的源码的时候,发现他的注解里面又@Controller、@ResponseBody等的时候,我们就可以直接使用@RestController,这时候就无需再加上@Controller、@ResponseBody等注解,因为它里面已经包含了
如,查看@RestController源码注解

控制器方法支持的参数类型

@PathVariable参数

一般的 URI 服务路径都是固定的,SpringMVC提供了 restful 风格可以变化的 URI

    @GetMapping("/name1/username1/name2/username2")
    @ResponseBody
    public Object test(@PathVariable String username1,@PathVariable String username2)
        Map<String,Object> map = new HashMap<>();
        map.put("1","黑旋风"+username1);
        map.put("2","及时雨"+username2);
        return map;
    

注意:这里要注解标识@ResponseBody

  • 是将服务路径 URI 中的部分定义为变量,之后在方法参数中获取该路径变量
  • 请求 localhost:8080/name1/李逵/name2/宋江 显示的页面内容为 “1”: “黑旋风李逵”,“2”: "及时雨宋江)
  • 变量已经定义为String,但是传入李逵和宋江这两个虽然不是字符串输入,但是会自动转换为字符串
  • 变量名username1和username2要和URI中的定义名称一样

@RequestParam参数

当请求数据要绑定到某个简单对象时,可以使用@RequestParam

  • URL 中的请求数据queryString
  • 请求头,Content-Type为表单默认提交的格式 application/x-www-form-urlencoded ,请求体中的数据
  • 请求头,Content-Type为 multipart/form-data ,请求体中的数据。 form-data 可以提交文本数据,也可以提交二进制文件
  • 以上简单对象包括:基本数据类型、包装类型、MultipartFile(接收二进制文件)

示例1:

    @PostMapping("/param2")
    public Object param2(@RequestParam(required = false) Integer count)
        Map<String, Integer> map = new HashMap<>();
        map.put("count", count);
        return map;
    

注意:

  • 这里的(required = false)为非必须写的,只不过加上它之后,就指定这个count为非必须输入
  • 以上代码使用包装类型 Integer ,如果使用 int ,不传入键为 count 的请求数据就会报错,因为null 无法转换为 int。(必填的请求数据可以使用基本数据类型,可以不传的参数,都要使用包装类型。)

示例二:
通过 post 请求,使用 form-data 提交一个键为 file 的二进制文件,需要注意整个请求数据大小不能超过10m,单个文件大小不超过1m。(这是 SpringBoot 的默认设置,修改需要通过
src/main/resources/application.properties 文件配置)

    @PostMapping("/param3")
    public Object param3(@RequestParam MultipartFile file) throws IOException 
        Map<String, String> map = new HashMap<>();
        map.put("文件名", file.getName()+", "+file.getOriginalFilename());
        map.put("文件类型", file.getContentType());
        map.put("文件大小", file.getSize()/1024+"KB");
        map.put("文件内容(二进制转字符串)", new String(file.getBytes()));
        return map;
    
POJO对象(Plain Ordinary Java Object):简单的Java对象,实际就是属性提供了Getter,Setter方法的普通对象

使用 java 对象和使用@RequestParam注解非常类似,只是有点细节不同:

  • @RequestParam是以方法参数变量名和传入的键对应,POJO对象作为方法参数时,是以POJO对象中的属性名对应传入的键
  • @RequestParam默认必须传入该请求数据,而 POJO 对象是根据请求数据来填充属性,如果请求数据没有,则属性就是默认值(new对象时每个属性的默认值)
    @PostMapping("/pojo")
    public Object pojo1(String username, Integer count)
        Map<String, String> map = new HashMap<>();
        map.put("用户名", username);
        map.put("count", String.valueOf(count));
        return map;
    
<h3>@RequestBody</h3>
当请求的数据类型Content-Type为 application/json 时,需要显示的使用@RequestBody注解
例如:首先在example下创建一个User类
@Getter
@Setter
@ToString
public class User 
    private String username;
    private String password;

在请求映射方法中作为方法参数,使用RequestBody注解

    @PostMapping("/json")
    public Object json(@RequestBody User user)
        Map<String, String> map = new HashMap<>();
        map.put("用户名", user.getUsername());
        map.put("密码", user.getPassword());
        return map;
    

@RequestPart

对于请求的数据类型Content-Type为 multipart/form-data 时,二进制文件除了以上@RequestParam和 POJO 对象的方式外,还可以使用@RequestPart。

    @PostMapping("/part")
    public Object part(User user, @RequestPart MultipartFile file) throws
            IOException 
        Map<String, String> map = new HashMap<>();
        map.put("用户名", user.getUsername());
        map.put("密码", user.getPassword());
        map.put("文件名", file.getName()+", "+file.getOriginalFilename());
        map.put("文件类型", file.getContentType());
        map.put("文件大小", file.getSize()/1024+"KB");
        map.put("文件内容(二进制转字符串)", new String(file.getBytes()));
        return map; 
    

Servlet API

在控制器方法参数中,可以使用Servlet相关API,SpringMVC会自动将相关Servlet对象装配到方法参数
中,如 HttpServletRequest 、 HttpServletResponse 、 HttpSession 等。

    @GetMapping("/servlet")
    public void servlet(HttpServletRequest req, HttpServletResponse resp) throws
            IOException 
        req.setCharacterEncoding("UTF-8");
        resp.setCharacterEncoding("UTF-8");
        resp.setContentType("text/html");
        String username = req.getParameter("username");
        String password = req.getParameter("password");
        PrintWriter pw = resp.getWriter();
        pw.println("接收到的请求为:用户名="+username+",密码:"+password);
        pw.flush();
        pw.close();
    

返回值设置为void,此时和在Servlet中开发差不多了。当然也可以使用返回值,SpringMVC会自动跳转
页面(无@ResponseBody,返回类型为String),或返回Content-Type: text/html的网页内容(使用
@ResponseBody,返回类型为String),或返回 json 字符串(@ResponseBody,返回 POJO 对象)

以上是关于SpringMVC的返回值和参数类型的主要内容,如果未能解决你的问题,请参考以下文章

张飞和李逵的各方面对比

如何在Spring中调用存储过程来读取返回值和输出参数?

实例化默认值和变量

Postgres 存储函数可以同时具有返回值和输出参数吗?

张飞与李逵的人物比较

Go语言的断言返回值和类型转换的区别