一文彻底搞懂什么是SpringMVC!

一文彻底搞懂什么是SpringMVC!

什么是SpringWebMVC

Spring WebMVC是基于ServletAPI构建的原始Web框架,从⼀开始就包含在Spring框架中。它的 正式名称“SpringWebMVC”来⾃其源模块的名称(Spring-webmvc),但它通常被称为"Spring MVC".

MVC定义

MVC是ModelViewController的缩写,它是软件⼯程中的⼀种软件架构设计模式,它把软件系统分为模型、视图和控制器三个基本部分

View(视图) 指在应⽤程序中专⻔⽤来与浏览器进⾏交互,展⽰数据的资源.Model(模型) 是应⽤程序的主体部分,⽤来处理程序中数据逻辑的部分.Controller(控制器) 可以理解为⼀个分发器,⽤来决定对于视图发来的请求,需要⽤哪⼀个模型 来处理,以及处理完后需要跳回到哪⼀个视图。即⽤来连接视图和模型

什么是Spring MVC

与另外两者的区别请看这:Spring,Spring Boot 和 Spring MVC 的关系以及区别 MVC是⼀种架构设计模式,也是⼀种思想, ⽽SpringMVC是对MVC思想的具体实现.除此之外, Spring MVC还是⼀个Web框架.

总结来说,SpringMVC是⼀个实现了MVC模式的Web框架.

所以,SpringMVC主要关注有两个点: 1. MVC 2. Web框架

学习Spring MVC

主要分为一下三个方面:

建⽴连接:将用户(浏览器)和 Java 程序连接起来,也就是访问⼀个地址能够调⽤到我们的Spring 程序。

请求: ⽤⼾请求的时候会带⼀些参数,在程序中要想办法获取到参数, 所以请求这块主要是 获取参数的功能.

响应: 执⾏了业务逻辑之后,要把程序执⾏的结果返回给用户, 也就是响应.

创建项目

Spring MVC 项目创建和 Spring Boot 创建项目相同,在创建的时候选择 Spring Web 就相当于创建了 Spring MVC 的项目。

建立连接

在 Spring MVC 中使⽤**@RequestMapping**来实现 URL 路由映射 ,也就是浏览器连接程序的作用

@RequestMapping是什么?

假设有以下代码:

import org.springframework.web.bind.annotation.RequestMapping;

import org.springframework.web.bind.annotation.RestController;

@RestController

public class TestController {

@RequestMapping("/hello")

public String hello() {

return "hello";

}

}

那么我们通过浏览器访问:http://127.0.0.1:8080/hello 就可以看到程序返回的数据了

@RequestMapping注解介绍

@RequestMapping 是 Spring Web MVC 应⽤程序中最常被用到的注解之⼀,它是用来注册接口的路由映射的.

表示服务收到请求时, 路径为 /hello 的请求就会调用 hello 这个方法的代码

路由映射: 当用户访问⼀个 URL 时, 将用户的请求对应到程序中某个类的某个方法的过程就叫路由映射.

既然如此,为什么要添加@RestController呢

如果我们把RestController去掉,程序会报404,即找不到界面

why? 在我们的项目中,会有很多类,每个类会有很多的方法,Spring会对所有的类进行扫描,如果类存在@RestController注解,Spring才会去扫描类方法里面是否有添加@RequestMapping 这个注解

@RequestMapping使用

@RequestMapping 既可修饰类,也可以修饰方法 ,当修饰类和方法时,访问的地址是类路径 + 方法路径.支持Get、Post和其他请求方式 如上代码可以改成:

import org.springframework.web.bind.annotation.RequestMapping;

import org.springframework.web.bind.annotation.RestController;

@RequestMapping("/test")

@RestController

public class TestController {

@RequestMapping("/hello")

public String hello() {

return "hello";

}

}

那么我们通过浏览器访问:http://127.0.0.1:8080/test/hello 就可以看到程序返回的数据了

[!IMPORTANT] 注意事项

@RequestMapping的URL 路径最前⾯加不加 / (斜杠)都可以, Spring程序启动时, 会进行判断, 如果前面没有加 / , Spring会拼接上⼀个 /@RequestMapping支持GET和POST请求,需要显示支持的话可以添加method进行选择:

@RequestMapping(value = "/getRequest",method= RequestMethod.POST)可以点击注释类,查看其源码结构,更清晰易懂

传递参数

传参常见的4种方法介绍here

@RestController

public class TestController {

@RequestMapping("/hello")

public String hello(String name) {

return name;

}

}

注意事项

前端与后端传入的参数名字和类型需要相同,除非使用[[@RequestParam]]进行绑定使用基本类型来接收参数时, 参数必须传(除boolean类型), 否则会报500错误,类型不匹配时, 会报400错误.

所以在项目开发中,对于参数可能为空的数据,建议使用包装类型

如果参数很多呢? 我们可以把这些参数封装为一个对象

@Data

public class User {

private Long id;

private String userName;

private String password;

}

@RestController

public class TestController {

@RequestMapping("/hello")

public String hello(User user) {

return user.toString();

}

}

这样前端传参的时候就需要用JSON格式进行传参

{

"id": "1",

"userName": "12345",

"password": "12345",

}

Spring 会根据参数名称⾃动绑定到对象的各个属性上, 如果某个属性未传递, 则赋值为null(基本类型则赋值为默认初识值, ⽐如int类型的属性, 会被赋值为0)

传递数组

SpringMVC可以自动绑定数组参数的赋值

使⽤浏览器发送请求并传参,下列请求都是对的

http://127.0.0.1:8080/param/m5?arrayParam=zhangsan&arrayParam=lisi&arrayParam=wangwu

http://127.0.0.1:8080/param/m6?listParam=zhangsan%2clisi%2cwangwu

http://127.0.0.1:8080/param/m5?arrayParam=zhangsan,lisi,wangwu 此时后端接受代码:

@RestController

public class TestController {

@RequestMapping("/hello")

public String hello(String[] strings) {

return Arrays.toString(strings);

}

}

当 URL 中需要包含一些特殊字符,例如逗号、空格等,这些字符不能直接放在 URL 中,需要进行 URL 编码。 %2c 就是逗号的 URL 编码。

传递集合

集合参数:和数组类似, 同⼀个请求参数名有为多个, 且需要使⽤ @RequestParam 绑定参数关系 请求方式和数组类似: ⽅式⼀: http://127.0.0.1:8080/param/m6?listParam=zhangsan&listParam=lisi&listParam=wangwu ⽅式⼆: http://127.0.0.1:8080/param/m6?listParam=zhangsan%2clisi%2cwangwu

此时后端接受代码:

public class TestController {

@RequestMapping("/hello")

public String hello(@RequestParam List listParam) {

return "size:"+ listParam.size() + ",listParam:" + listParam;

}

}

传递JSON数据

什么是JSON?

详解:什么是JSON。

JSON字符串和Java对象互转

JSON本质上是⼀个字符串, 通过⽂本来存储和描述数据

Spring MVC框架也集成了JSON的转换⼯具, 我们可以直接使⽤, 来完成JSON字符串和Java对象的互转,内置是通过jackson-databind的依赖进行的转化的

后端在进行接收JSON对象, 需要使⽤@RequestBody注解

public class TestController {

@RequestMapping("/hello")

public String hello(@RequestBody person) {

return person.toString();

}

}

获取URL中参数@PathVariable

@PathVariable与@RequestParam的区别

path variable: 路径变量:即字⾯表达的意思, 这个注解主要作用在请求URL路径上的数据绑定

默认传递参数写在URL上,SpringMVC就可以获取到,如: http://127.0.0.1:8080/param/m8/5/zhangsan

后端代码:

public class TestController {

@RequestMapping("/hello/{id}/{name}")

public String hello(@PathVariable Integer id,@PathVariable("name") String userName) {

return "获取参数, id:" id +", name:" + userName;

}

}

注意点

如果方法参数名称和需要绑定的URL中的变量名称⼀致时, 可以简写, 不用给@PathVariable的属性赋值, 如上述例子中的id变量如果⽅法参数名称和需要绑定的URL中的变量名称不⼀致时, 需要@PathVariable的属性value赋值, 如上述例子中的userName变量

上传⽂件@RequestPart

后端代码实现:

@RequestMapping("/upFile")

public String getfile(@RequestPart("file") MultipartFile file) throws IOException {

//获取文件名称

String fileName = file.getOriginalFilename();

//文件上传到指定路径

file.transferTo(new File("F:/temp/" +fileName));

return "接受到的文件名为" +fileName;

}

练习:图片上传|利用@RequestPart实现图片上传

获取Cookie/Session

什么是Cookie/Session:here

传统方法获取Cookie

@RequestMapping("/m10")

public String method10(HttpServletRequest request,HttpServletResponse response)

{

// 获取所有 cookie 信息

Cookie[] cookies = request.getCookies();

// 打印Cookie信息

StringBuilder builder = new StringBuilder();

if (cookies!=null){

for (Cookie ck:cookies) {

builder.append(ck.getName()+":"+ck.getValue());

}

}

return "Cookie信息:"+builder;

}

httpServlet请求,httpServletResponse 是 Servlet 提供的两个类别,是SpringMVC方法的内置对象。需要时直接在方法中添加声明即可。httpServlet 请求对象代表客户端的请求,当客户端通过HTTP协商访问服务器时,HTTP请求 求头中的所有信息都封装在这个对象中,通过这个对象提供的方法,可以获得客户端请求的所有信 休息。httpServletResponse 对象代表服务器的响应。HTTP响应的信息都在这个对象中,例如向客户 端发送的数据,响应头,状态码等,通过这个对象提供的方法,可以获得服务器响应的所有内容SpringMVP在这两个对象的基础上进行了封装,为我们提供了更多简单的使用方法。

简洁方法获取Cookie

@RequestMapping("/getCookie")

public String cookie(@CookieValue("bite") String bite) {

return "bite: " + bite;

}

Session是服务器端的机制,我们需要先存储,才能再获取Session也是基于HttpServletRequest 来存储和获取的

Session存储

@RequestMapping("/setSess")

public String setSess(HttpServletRequest request)

{

HttpSession session = request.getSession();

if (session != null) {

session.setAttribute("username", "java");

}

return "session 存储成功";

}

这个代码中看不到 SessionId 这样的概念的,getSession 操作内部提取到请求中的Cookie 里的 SessionId,然后根据SessionId获取到对应的Session对象。Session 对象用HttpSession来描述

获取Session有两种方式

HttpSession getSession(boolean create);HttpSession getSession();

HttpSession getSession(boolean create): 参数如果为 true, 则当不存在会话时新建会话; 参数如果为 false, 则当不存在会话时返回 nullHttpSession getSession(): 和getSession(true) 含义一样,默认值为true。void setAttribute(String name, Object value): 使用指定的名称绑定一个对象到该 session 会话

Session读取

读取 Session 可以使用 HttpServletRequest

@RequestMapping("/getSess")

public String getSess(HttpServletRequest request) {

// 如果 session 不存在,不会自动创建

HttpSession session = request.getSession(false);

String username = null;

if (session != null && session.getAttribute("username") != null) {

username = (String) session.getAttribute("username");

}

return "username: " + username;

}

Object getAttribute(String name): 返回在该 session 会话中具有指定名称的对象,如果没有指定名称的对象,则返回 null。

简洁获取 Session(1)

@RequestMapping("/getSess2")

public String getSess2(@SessionAttribute(value = "username",required = false)

String username) {

return "username: "+username;

}

简洁获取 Session(2)

通过Spring MVC内置对象HttpSession 来获取

@RequestMapping("/getSess3")

public String getSess3(HttpSession session) {

String username = (String)session.getAttribute("username");

return "username: "+username;

}

HttpSession session = request.getSession(); Session 不存在的话,会自动创建

获取Header

获取Header也是从 HttpServletRequest 中获取

@RequestMapping("/param10")

public String param10(HttpServletRequest request, HttpServletResponse response)

{

String userAgent = request.getHeader("User-Agent");

return name + ":" + userAgent;

}

使用HttpServletRequest 提供的getHeader方法来获取,参数对应HTTP请求报头的"Key"

简洁获取 Header

@RequestMapping("/header")

public String header(@RequestHeader("User-Agent") String userAgent) {

return "userAgent:" + userAgent;

}

@RequestHeader注解的参数值为HTTP请求报头中的"Key"

响应

在我们前⾯的代码例⼦中,都已经设置了响应数据, Http响应结果可以是数据, 也可以是静态⻚⾯,也可以针对响应设置状态码, Header信息等

返回数据@ResponseBody

后端代码:

@Controller

public class TestController {

@RequestMapping("/index")

@ResponseBody

public String returnData(){

return "返回数据";

}

}

使用浏览器访问:http://127.0.0.1:8080/returnData,可以看到可以成功返回数据

如果去除@ResponseBody会报404错误,因为此时程序认为需要返回的是视图,根据内容去查找文件,但是查询不到,路径不存在

同时如果在返回的数据中有HTML代码,也会被浏览器进行解析

@Controller

public class TestController {

@RequestMapping("/index")

@ResponseBody

public String returnData(){

return "

返回html数据

";

}

}

[!EXAMPLE] 响应中的Content-Type常见取值有以下几种:

text/html: body的数据格式是HTMLtext/css: body的数据格式是CSSapplication/javascript: body的数据格式是JavaScriptapplication/JSON: body的数据格式是JSON

返回JSON

后端返回结果为对象:

@Controller

public class TestController {

@RequestMapping("/json")

@ResponseBody

public HashMap returnJSON(){

HashMap map = new HashMap<>();

map.put("id","1");

map.put("name","doublez");

return map;

}

}

设置状态码

Spring MVC会根据我们方法的返回结果自动设置响应状态码,但是也可以手动指定状态码 通过SpringMVC的内置对象HttpServletResponse提供的方法来进⾏设置

@RequestMapping("/status")

@ResponseBody

public String setStatus(HttpServletResponse response){

response.setStatus(401);

return "设置状态码成功";

}


相关推荐

杭州华数宽带套餐价格表
如何知道CPU
韩国电竞这么厉害为什么没csgo战队?
堇怎么读 堇什么意思
90分钟绝杀!世界第52创造的黑马奇迹,力压德国登顶世预赛
360311开头的身份证是江西省萍乡市上栗区的行政区划代码