绝大多数的Java项目都是基于Spring(或者SpringBoot),而Spring的核心就是SpringMVC。SpringMVC是Spring框架的核心模块,而SpringBoot是Spring的脚手架。学好SpringMVC只需要掌握三个方面即可:连接、获取参数、输出数据。本文将展开进行讲述。
目录
一、什么是Spring MVC?
Spring Web MVC是基于Servlet API构建·放入原始Web框架,一开始就包含在Spring框架中。名称来源于其源模块的名称(Spring-webmvc),也称Spring MVC。Spring MVC是基于Servlet封装的一套框架,能更方便的完成web开发。
Serlvet是jdk提供的java语言进行web开发的一套标准规范(定义了很多API,其中很多方法没有具体实现),web服务器实现了这些规范。我们开发的java web项目部署到web服务器,
运行起来本质上是调用该web服务器的具体实现。依次达到程序基于servlet标准规范来开发,可以无缝的运行在任意支持servlet的web服务器中(servlet容器)。
1、MVC定义
MVC是Model View Controller的缩写,是软件工程中的一种软件架构模式,把软件系统分为模型、视图和控制器三个基本部分:
- Model(模型):是应用程序中用于处理应用程序数据逻辑的部分。对应请求和响应数据转换的对象;model是Spring MVC的框架,自动的将请求数据转换为Java对象。
- View(视图):返回给前端使用的内容(处理数据显示的部分)。通常视图依据模型数据创建。
- Controller(控制器):处理请求和响应。通常控制器负责从试图中读取数据,控制用户输入,并向模型发送数据。
- MVC:设计思想,web开发,划分了三个概念;
- 传统的软件架构的三层模型:Controller、Service、dao/mapper;
- 软件分层:每一个业务功能,都有自己的三层,controller调用sercive,service调用dao。
2、MVC和Spring MVC
绝大多数的Java项目都是基于Spring(或者SpringBoot),而Spring的核心就是SpringMVC。SpringMVC是Spring框架的核心模块,而SpringBoot是Spring的脚手架。
- MVC是一种设计思想,Spring MVC是堆MVC思想的具体实现;
- Spring MVC是一个实现了MVC模式,并继承Servlet APi的web框架。
二、Spring MVC使用
SpringMVC项目的创建和SpringBoot创建项目相同,这里不再多说。
@Controller=>控制器
@RequestMapping=>定义服务资源(路径,请求方法,响应类型等等)
(可以使用在类和方法上,服务资源路径:类上的路径+方法上的路径)
1、获取请求数据
如何查看使用postman发的http请求的报文?
(1)使用fidder抓包工具
(2)使用postman进行查看:
获取请求数据:queryString、表单格式、json格式、from-data
(1)基础数据类型/包装类型
可以接收queryString、表单格式、from-data格式的数据(不支持json):
- 变量名需要和请求数据的键一致,如果不一致,接收到的就是null;
- 基础数据类型:不传数据时,会500报错;包装类型不传时为null;
- 如果前端传送的数据类类型和后端的类型不匹配,会400报错。
添加@RequestParam注解(关联的字段名和参数名不相同时,使用@RequestParam(“字段名”)),作用在方法参数上:
- 表示请求必须包含该字段,否则报错400
- 注解有一个参数required,默认为true表示参数必填;可以更改为false设置为非必填。
(2)自定义对象
支持queryStirng、表单格式、from-data格式(不支持json)。
自定义类型,如果使用@RequestParam注解,任何一个字段为传入时都会报错。
(3)from-data格式的文件上传
使用SpringMVC里面提供的一个文件类型MultipartFile,并且变量名必须和上传文件的键名相同。
基于MultipartFile类型:
- 无注解;
- @RequestParam注解=>默认必填;
- @RequestPart注解=>默认必填。
方法参数名和键名不相同时,可以使用之前的方法进行关联。
(4)自定义类型的对象(@RequestBody注解)
使用@RequestBody注解,只用来接收json,其他数据格式都不能接收。
对象中的数据,来接收请求数据。注:如果不包含该字段,则属性为空。
(5)路径变量
路径某个部分可以动态变化,可以看作变量。HTTP协议,规定请求的数据只能是在queryString或者body中,这里没有遵循该规则,将数据存放在url中。(方法参数上使用@PathVariable注解)
根据id来查询用户信息,就拥有一个id字段作为请求数据:/path/query/123,可以把/123部分先用一个变量来表示,然后在方法参数上关联这个变量:
【1】参数名和关联的字段名相同
【2】参数名和关联的字段名不同
(6)获取Cookie/Session/herder
会话管理机制:基于Cookie和Session实现
(1)会话:用户登陆一个网站后,退出或登陆超时之前都属于一个会话。
(2)会话管理流程:
- 登陆成功后,服务端会创建sessionId以及session对象,并保存在web服务器的一个map数据结构中,同时返回响应头Set-Cookie:sessionId=值。
- 客户端保存Cookie信息到本地;
- 每次请求都携带Cookie:sessionId=值;服务端会通过请求头的Cookie中的sessionId的值在map中进行查找。
模拟登陆创建session对象以及获取session中的字段:
//模拟登陆创建session
@RequestMapping("/login")
public String login(String username, String password, HttpServletRequest req){
log.debug("username:{},password:{}",username,password);
//登陆成功
if(username.equals("abc")&&password.equals("123")){
//创建session(创建sessionId及Session对象)并返回Set-Cookie
HttpSession session=req.getSession();
//在session对象中保存键值对的数据
session.setAttribute("user","创建的会话");
}
return "kognzhi";
}
//获取session中的某个字段的值:@SessionAttribute
@RequestMapping("/attribute")
public String Attribute(@SessionAttribute("user") String user){
log.debug("获取session中的用户:{}",user);
return "kongzhi";
}
简洁获取:
- @CookieValue:简洁获取Cookie中的数据
Cookie的格式:Cookie:键1=值1;键2=值2- @RequestHeader:简洁获取Herder
- @SessionAttribute:简洁获取Session
2、返回数据
(1)返回静态页面
创建前端页面
创建控制器
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
//类/方法注解,表示服务资源的路径
@RequestMapping("/user")
public class UserController {
//返回值(字符串)是网页的路径
@RequestMapping("/login")
public String Login(){
return "/index.html";
}
}
(2)返回json字符串(响应正文)
ajax请求,一般都是返回json。使用@ResponseBody注解(表示,将返回的对象转换为json对象,设置为响应正文):
- 如果返回值为字符串,会转换为text/html;
- 如果返回值是对象,会转换为application/json返回给前端。
//返回json字符串:@ResponseBody,且方法的返回值为list,map,自定义类型即可
@RequestMapping("/response")
@ResponseBody
public Object response(){
Map<String,Object> map=new HashMap<>();
map.put("username","张三");
map.put("nickname","小张");
return map;
}
注解可以使用在类、方法上:
- 使用在类上,表示所有的@RequestMappering注解的方法,都默认有该注解;
- 使用在方法上,作为响应正文的内容。
(3)请求转发和重定向
请求转发 vs 请求重定向(默认为请求转发):
- forward请求转发:路径不发生改变(服务端进行转发);服务器端转发可能造成源外部资源不能访问;
- redirect请求重定向:路径发生改变,发送两次请求。(第一次返回301/302/307重定向状态码+Location重定向地址;第二次浏览器自动发送location路径的请求)
请求转发和请求重定向:
// 请求重定向
@RequestMapping("/index")
public String index(){
return "redirect:/index.html";
}
// 请求转发
@RequestMapping("/index2")
public String index2(){
return "forward:/index.html";
}
3、组合注解
- @RestController:类注解,等同于@controller+@ResponseBody;
- @GetMapping:方法注解,等同于@RequestMapping(method=RequestMethod.GET)。只提供get服务方法;
- @PostMapping:方法注解,等同于@RequestMapping(method=RequestMethod.POST)。只提供POST服务方法;
对于@RequestMapping提供所有的服务方法get、post、put等。