SpringMVC介绍
Spring Web MVC是基于Servlet API构建的原始Web框架,从一开始就包含在Spring Framework中。正式名称“Spring Web MVC”来自其源模块的名称( spring-webmvc
),但它通常被称为“Spring MVC”。
SpringMVC涉及组件
- DispatcherServlet : SpringMVC提供,需要使用web.xml配置使其生效,它是整个流程处理的核心,所有请求都经过它的处理和分发
- HandlerMapping : SpringMVC提供,需要进行IoC配置使其加入IoC容器方可生效,它内部缓存handler(controller方法)和handler访问路径数据,被DispatcherServlet调用,用于查找路径对应的handler
- HandlerAdapter : SpringMVC提供,需要进行IoC配置使其加入IoC容器方可生效,它可以处理请求参数和处理响应数据数据,每次DispatcherServlet都是通过handlerAdapter间接调用handler,他是handler和DispatcherServlet之间的适配器
- Handler : handler又称处理器,它是Controller类内部的方法简称,是由我们自己定义,用来接收参数,向后调用业务,最终返回响应结果
- ViewResovler : SpringMVC提供,我们需要进行IoC配置使其加入IoC容器方可生效,视图解析器主要作用简化模版视图页面查找的,但是需要注意,前后端分离项目,后端只返回JSON数据,不返回页面,那就不需要视图解析器。所以,视图解析器,相对其他的组件不是必须的
SpringMVC案例:
控制层:
@Controller
public class HelloController {
@RequestMapping("spring/hello")//对外访问的地址 此注解也会进行在handlerMapping注册的操作
@ResponseBody//不用找视图解析器
public String hello(){
System.out.println("hello,springmvc");
return "hello springmvc";
}
}
配置类:
/**
*要配置的操作:
* 1.将controller配置到ioc容器
* 2.将handlerMapping和handlerAdapter加入到ioc容器
*
*/
@Configuration
@ComponentScan("com.ergou.controller")
public class MvcConfig {
@Bean
public RequestMappingHandlerMapping handlerMapping(){
return new RequestMappingHandlerMapping();
}
@Bean
public RequestMappingHandlerAdapter handlerAdapter(){
return new RequestMappingHandlerAdapter();
}
}
初始化的类:
/**
*可以被web项目加载,会初始化容器,会设置dispatcherServlet的地址
*/
public class SpringMvcInit extends AbstractAnnotationConfigDispatcherServletInitializer {
@Override
protected Class<?>[] getRootConfigClasses() {
return new Class[0];
}
//设置我们项目对应的配置类
@Override
protected Class<?>[] getServletConfigClasses() {
return new Class[] {MvcConfig.class};
}
//配置springmvc内部自带的servlet访问地址
@Override
protected String[] getServletMappings() {
return new String[]{"/"};
}
}
SpringMVC接收数据
访问路径设置
@RequestMapping注解的作用就是将请求的 URL 地址和处理请求的方式(handler方法)关联起来,建立映射关系。
将地址写在RequestMapping注解的value属性中即可,同样只有value属性时,value=可以省略
@RequestMapping注解中的地址不是必须斜杆开头,可有可无
地址的表示方式
- 精准地址
- 例:/user/login
- 如果有多个地址,就用{}括号括起来,多个地址之间用逗号隔开,例如:@RequestMapping({”地址一”,”地址二”,……}
- 模糊地址
- *表示一层的任意字符串,**表示任意层的任意字符串
- 例:/user/* *处的一层的字符串可以是任何字符串
- 例:/user/** **处可以有多层字符串,每层的字符串任意
添加@RequestMapping的位置
@RequestMapping注解可以加在方法上,比如一个方法上的RequestMapping注解的地址为/user/login,则通过user/login地址就可以访问到此方法
@RequestMapping注解也可以加在类上,若一个类上的RequestMapping注解的地址为/user,该类的一个方法上的RequestMapping注解的地址为/login,则通过user/login地址就可以先访问地址为/user的类,在访问该类中地址为login的方法
请求方式指定
在@RequestMapping注解的method属性中写指定请求方式的枚举对象即可,如果要指定多个请求方式,也是用{}括起来即可
例:
@Controller
@RequestMapping("/user")
public class UserController {
@RequestMapping(value = "/login",method = RequestMethod.POST)//只允许使用post方式的请求
public String login(){
return null;
}
@RequestMapping(value = "/register",method = {RequestMethod.GET,RequestMethod.POST})//可以使用get方式的请求,也可以使用post方式的请求
public String register(){
return null;
}
}
注解进阶:
@GetMapping
@PostMapping
@PutMapping
@DeleteMapping
作用是这些注解比起RequestMapping,直接指定了请求的方式
只能使用在方法上
以@GetMapping为例:
@GetMapping(value = "/exit")
等同于
@RequestMapping(value = "exit",method = RequestMethod.GET)
接收参数
json和param参数
param参数:由key-value形式传递参数,key和value之间用=连接,多个key-value数据之间用&连接,只支持简单数据类型的数据,不支持数据的嵌套,形式:key=value&key=value&……
json参数:也是由key-value形式传递参数,key和value之间用:连接,多个key-value数据之间使用逗号隔开,整体是由一个{}括起来,如果一个value中又包括其他key-value数据,可以使用{}表示此value,{}中写其中的key-value数据,即json参数支持数据的嵌套,json支持复杂数据类型,比如数组、集合、对象等。形式:{key:value,key:{key:value,key,value},key:……}
param参数接收
- 直接接收
在handler方法的形参列表中,形参的命名和请求的参数名一致,相应的请求参数即会直接传给其同名的形参
@Controller
@RequestMapping("param")
public class ParamController {
@RequestMapping("data")
@ResponseBody
public String data(String name,int age){
System.out.println("name = " + name + ", age = " + age);
return "name = " + name + ", age = " + age;
}
}
- 注解指定
@RequestParam注解加在形参前,可以指定任意的请求参数名,可以要求参数必须传递或非必须传递,还可以指定不必须传递时设置形参的默认值
@RequestParam注解的属性:
- value:指定形参要接收的参数的参数名
- required:指定形参是否必须传递,true为必须传递,false为非必须传递,默认为true
- defaultValue:非必须传递时设置,当没有请求参数传递过来时,形参的值默认为该属性值
非必须传递时要用defaultValue属性设置默认值,如果形参没有接收到请求参数的数据,会报400异常
例:
@RequestMapping(value = "data1",method = RequestMethod.GET)
@ResponseBody
public String data1(@RequestParam(value = "account") String username,
@RequestParam(required = false,defaultValue = "1") int age){
System.out.println("username = " + username + ", age = " + age);
return "username = " + username + ", age = " + age;
}
-
特殊参数值
-
一个key值有多个value
- 若param参数中有两个key值相同value值不相同的参数,可以直接使用集合来接收其参数值
- 设置集合类型的形参时,要在此形参前加上@RequestParam注解,如果不加,会将字符串直接赋值给集合,加了此注解后,才会将多个参数依次加入集合中
@RequestMapping(value = "data2",method = RequestMethod.GET) @ResponseBody //若要传递的参数为:hbs=singing&hbs=dancing&hbs=rap&hbs=basketball public String data2(@RequestParam List<String> hbs){ System.out.println(hbs); return hbs.toString(); } //客户端收到的结果为[singing, dancing, rap, basketball]
-
使用实体对象接收参数值
- 准备一个用来接收请求参数的有对应属性和其get、set方法的实体类,要保证请求参数名和实体类的属性名对应一致,如果要默认值,直接在实体类中给要设默认值的属性赋值即可
- 形参列表中写一个此实体类类型的形参即可
@RequestMapping(value = "data3",method = RequestMethod.GET) @ResponseBody public String data3(User user){ System.out.println("user = " + user); return user.toString(); }
-
-
路径参数接收
-
路径传参指的是直接将要传递的值写在路径中,即直接将value写在路径中,例如,要将用户名为ergou,密码为1234的数据传递给handler,可以写作:user/login/ergou/1234
-
路径参数接收步骤:
- 设置动态路径:
在@RequestMapping注解的value属性中,在要用来接收参数的路径处写上{},在{}中写上该参数的参数名(以方便handler方法调用)即可,例:
@GetMapping("login/{username}/{password}")
- 接收动态路径参数
在handler方法的形参列表中写上相应的形参,形参名要和动态路径的{}中的参数名对应一致,且要在形参前加上@PathVariable注解
- @PathVariable,如果形参名和动态路径中的参数名不一致,可以用value的属性值指定形参要接收的动态路径中的参数(写入要接收的动态参数的参数名)
例:
@Controller @RequestMapping("path") public class PathController { @GetMapping("login/{username}/{password}") @ResponseBody public String login(@PathVariable String username,@PathVariable int password){ System.out.println("username = " + username + ", password = " + password); return "username = " + username + ", password = " + password; } }
-
json参数接收
接收json参数时,首先要准备一个接收json参数的实体类,其中的属性和参数一一对应。在形参列表中,写一个此实体类类型的形参,并在此形参前加上@RequestBody注解(加上此注解后就可以接收json参数)
@Controller
@RequestMapping("json")
@ResponseBody
public class JsonController {
@PostMapping("data")
public String data(@RequestBody Person person){
System.out.println("person = " + person);
return person.toString();
}
}
除此之外,还要项目导入json处理的依赖,以及给handlerAdapter配置json转化器
导入json处理依赖:
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.15.0</version>
</dependency>
给handlerAdapter配置json转化器:
在配置类上加上@EnableWebMvc注解即可
@EnableWebMvc//此注解会给handlerAdapter配置json转化器
@Configuration
@ComponentScan({"com.ergou.param","com.ergou.path","com.ergou.json"})
public class MvcConfig {
@Bean
public RequestMappingHandlerMapping handlerMapping(){
return new RequestMappingHandlerMapping();
}
@Bean
public RequestMappingHandlerAdapter handlerAdapter(){
return new RequestMappingHandlerAdapter();
}
}
@EnableWebMvc注解的作用:
此注解会自动将RequestMappingHandlerMapping和RequestMappingHandlerAdapter加入ioc容器中,除此之外还会配置json转化器。
所以在配置类上写好@EnableWebMvc注解后,可以省略RequestMappingHandlerMapping和RequestMappingHandlerAdapter的使用@Bean注解进行ioc配置的操作。
@EnableWebMvc//此注解会给handlerAdapter配置json转化器
@Configuration
@ComponentScan({"com.ergou.param","com.ergou.path","com.ergou.json"})
public class MvcConfig {
new RequestMappingHandlerAdapter();
}
接收cookie数据
在handler方法参数列表中的要接收cookie数据的形参前加上@CookieValue注解,可以在其中的value属性中指定要接收的cookie数据的名称
@Controller
@RequestMapping("cookie")
@ResponseBody
public class CookieController {
@RequestMapping(value = "data",method = RequestMethod.GET)
public String data(@CookieValue("cookie") String value){
System.out.println("value = " + value);
return value;
}
@GetMapping("save")
public String save(HttpServletResponse response){
Cookie cookie = new Cookie("cookie","root");
response.addCookie(cookie);
return cookie.toString();
}
}
原生对象获取
在形参中加上相应的注解或直接使用某些实体类的形参,可以获取对应的一些原生对象
Controller method argument 控制器方法参数 | Description |
---|---|
jakarta.servlet.ServletRequest, jakarta.servlet.ServletResponse | 请求/响应对象 |
jakarta.servlet.http.HttpSession | 强制存在会话。因此,这样的参数永远不会为 null 。 |
java.io.InputStream, java.io.Reader | 用于访问由 Servlet API 公开的原始请求正文。 |
java.io.OutputStream, java.io.Writer | 用于访问由 Servlet API 公开的原始响应正文。 |
@PathVariable | 接收路径参数注解 |
@RequestParam | 用于访问 Servlet 请求参数,包括多部分文件。参数值将转换为声明的方法参数类型。 |
@RequestHeader | 用于访问请求标头。标头值将转换为声明的方法参数类型。 |
@CookieValue | 用于访问Cookie。Cookie 值将转换为声明的方法参数类型。 |
@RequestBody | 用于访问 HTTP 请求正文。正文内容通过使用 HttpMessageConverter 实现转换为声明的方法参数类型。 |
java.util.Map, org.springframework.ui.Model, org.springframework.ui.ModelMap | 共享域对象,并在视图呈现过程中向模板公开。 |
Errors, BindingResult | 验证和数据绑定中的错误信息获取对象! |
共享域对象操作
获取共享域对象:
获取request共享域对象和session共享域对象:在形参列表处声明HttpServletRequest类型的对象和HttpSession类型的对象即可
获取ServletContext共享域对象:在Controller层的类中声明ServletContext类型的属性,在其上方加上@Autowired注解即可