MVC

Q: SpringMVC中MVC是什么?
MVC全称Model View Controller,是软件架构设计的一种思想,它将软件分为Model,View,Controller三部分,Model负责业务逻辑处理,View负责结果展示,Controller负责获取数据丢给Model。

SpringMVC

Q: SpringMVC和MVC有什么关联?
SpringMVC全称Spring Web MVC,是基于Servlet API构建的一个web框架。MVC是一种软件架构设计思想,而SpringMVC则是对这种思想的具体实现,同时SpringMVC还是一个Web框架。

Q: SpringMVC和SpringBoot是什么关系?
SpringBoot是创建SpringMVC项目的一种方式,当项目中按照SpringMVC的架构包含了web模块时我们就认为此项目也是个SpringMVC项目。SpringMVC是SpringBoot的一个模块,一个项目既可以是SpringMVC项目,同时也可以是SpringBoot项目。

交互

Q: SpringMVC的Controller模块如何获取数据的?
通过@RequestMapping注解实现URL路由映射,让用户使用浏览器建立与服务器的连接。

Q: URL路由映射是什么?
当用户访问某个URL时,将用户请求对应到程序中某个类的某个方法的过程称为路由映射。

Q: @RequestMapping注解的功能怎么理解?
@RequestMapping注解可以理解为门牌号,可以挂在类门口,也可以挂在方法门口,起到说明类路径和方法路径的目的。使用@RequestMapping注解后用户就可以以serviceURL+类路径+方法路径来直接访问到方法。

tips:为了更准确地找到并管理类路径和方法路径,建议给类和方法都加上@RequestMapping注解,同时方法前的@RequestMapping注解建议采用方法名作为参数。

举个例子:

1
2
3
4
5
6
7
8
9
@RestController
@RequestMapping("/example")
public class ExampleController{

@RequestMapping("/getName")
public String getName(String name){
return name;
}
}

用户访问时使用URL即可:https://localhost:8080/example/getName?name=fjsi

Q: @RequestMapping在所有类前都能加吗?
并不是,MVC模式里负责获取用户请求数据的模块是Controller部分,因此@RequestMapping是加在Controller模块的类和接口方法前面的。

tips:Controller模块的类前还要加@RestController注解,表明这个类是属于Controller模块,只有加了@RestController注解,Spring才会进入到类中找@RequestMapping修饰的方法。

Q: @RequestMapping注解的参数还有什么?
@RequestMapping注解的参数除了门牌号value之外还有个method参数。
@RequestMapping支持GET、POST等请求,method说明请求方式,使用举例:

1
@RequestMapping(value="/getName", method=RequestMethod.GET)

Q: @RequestMapping与@GetMapping什么关系
@GetMapping是@RequestMapping(method=RequestMethod.GET)的简化写法,同等作用。同理的还有@PostMapping,@PutMapping,@DeleteMapping

传参

在Spring框架中,特别是Spring MVC部分,处理HTTP请求时经常会用到几种注解来映射请求参数到方法的参数上,下面介绍几种常用的,注意区分。

@RequestParam‌

‌用途‌:用于将请求参数绑定到controller的方法参数上。它告诉Spring MVC,请求中的哪个参数应该被绑定到controller的方法参数上。
‌示例:
请求方式为GET,URL为localhost:8080/student?id=1
Controller中接口方法部分为:

1
2
3
4
@GetMapping("/student")
public String getNameById(@RequestParam(value = "id") long id) {
return studentService.getNameById(id);
}

则结果就是@RequestParam会将URL中的id=1传递给getNameById()方法的id参数。

@RequestParam有三个参数:

参数名 选择 含义
value 必选 要绑定的变量名,与url中变量名统一
required 可选 truefalse来表示此参数是否为必选参数,必选时不传参数报错
defaultValue 可选 没传参数时的默认值

@RequestParam也可以传递多个参数,controller中接口方法的每个参数前都加@RequestParam,而URL的书写格式类似localhost:8080/student?id=1&age=18

‌@PathVariable‌

‌用途‌:用于将URL模板变量绑定到方法参数上。这与@RequestParam不同,因为它从URL的路径中提取信息,而不是查询字符串。
‌示例:
URL为localhost:8080/student/1
Controller中接口方法部分为:

1
2
3
4
@GetMapping("/student/{id}")
public String getNameById(@PathVariable(value = "id") long id) {
return studentService.getNameById(id);
}

@PathVariable("id") long id会将URL中的{id}部分的值绑定到id变量上。‌

有时你会看到@PathParam注解,它的作用与@PathVariable相同,在选择使用@PathVariable还是@PathParam时,你需要考虑你的项目是基于哪个框架或规范。如果你的项目是基于Spring MVC的,那么你应该使用@PathVariable;如果你的项目是基于JAX-RS的,那么你应该使用@PathParam。

@RequestBody‌

‌用途‌:用于将HTTP请求的正文内容绑定到方法参数上,通常用于处理非表单数据(如JSON、XML)。
‌示例:
POST请求,请求体为json类型
URL为localhost:8080/student
Controller中接口方法部分为:

1
2
3
4
@PutMapping(value = "/student")
public Long updateStudent(@RequestBody Student student) {
return studentService.updateStudent(student);
}

请求体为:

1
2
3
4
5
6
{
"id": 1,
"name": "fjsi",
"email": "fjsi@fjsi.com",
"age": 18
}

Student是服务端定义的一个实体,有成员变量id,name,email,age。
@RequestBody可将JSON转换为Student的实例。

总结一下
Controller书写时要遵循RESTful API规范。
参数比较少且可以暴露给外界时,常采用@RequestParam方式;只有一个参数时用@PathVariable比较方便;参数数量较多或者不想暴露给外面(不可见)时推荐使用POST请求方式,将参数用json的方式作为RequestBody传入,通过@RequestBody将JSON绑定到服务端定义的实体实例上。

同时,建议接口的方法参数采用基本类型的包装类来代替基本数据类型。
如果方法参数为基本数据类型,那么当传入按参数为空,或者没有参数传入时服务会直接报错崩溃,如果方法参数为包装类型则会传入null,在代码中进行null判断之后抛出异常,这样能避免忘了传参导致服务崩溃,同时还能更快定位错误,例如:

1
2
3
4
@RequestMapping("/getAge")
public Integer getAge(Integer age){
return age;
}