1、关于控制器
在编写控制器相关代码之前,需要在项目中添加spring-boot-starter-web
依赖项。
spring-boot-starter-web
是基于(包含)spring-boot-starter
的,所以,添加spring-boot-starter-web
后,就不必再显式的添加spring-boot-starter
了,则可以将原本的spring-boot-starter
改成spirng-boot-starter-web
即可,例如:
<!-- Spring Boot的Web依赖项,包含基础依赖项 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
spring-boot-starter-web
包含了一个内置的Tomcat,当启动项目时,会自动将当前项目编译、打包并部署到此Tomcat上。
在项目中,控制器表现为各个Controller
,是由Spring MVC框架实现的相关数据处理功能,以上添加的spring-boot-starter-web
包含了Spring MVC框架的依赖项(spring-webmvc
)。
控制器的主要作用是接收请求,并响应结果。
2、关于控制器类Controller
在Spring MVC框架,使用控制器(Controller
)来接收请求、响应结果。
在根包下的任何一个类,添加了@Controller
注解,就会被视为控制器类。
在默认情况下,控制器类中处理请求的方法,响应的结果是”视图组件的名称“,即:控制器对请求处理后,将返回视图名称,Spring MVC还会根据视图名称来确定视图组件,并且,由此视图组件来响应!这不是前后端分离的做法!
提示:如果需要了解传统的Spring MVC不使用前后端分离的做法,可以参考扩展视频教程《基于XML配置的Spring MVC框架》。
可以在处理请求的方法上添加@ResponseBody
注解,则此方法处理请求后,返回的值就是响应到客户端的数据!这种做法通常称之为”响应正文“。
@ResponseBody
注解还可以添加在控制器类上,则此控制器类中所有处理请求的方法都将是”响应正文“的!
另外,还可以使用@RestController
取代@Controller
和@ResponseBody
,关于@RestController
的源代码:
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Controller
@ResponseBody
public @interface RestController {
@AliasFor(
annotation = Controller.class
)
String value() default "";
}
可以看到,在@RestController
的源代码上,添加了@Controller
和@ResponseBody
,所以,可以把@RestController
称之为”组合注解“,而@Controller
和@ResponseBody
可以称之为@RestController
的”元注解“。
与之类似的,在Spring MVC框架中,添加了@ControllerAdvice
注解的类中的特定方法,将可以作用于每次处理请求的过程中,但是,仅仅只使用@ControllerAdvice
时,并不是前后端分离的做法,还应该结合@ResponseBody
一起使用,或,直接改为使用@RestControllerAdvice
,关于@RestControllerAdvice
的源代码片段:
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@ControllerAdvice
@ResponseBody
public @interface RestControllerAdvice {
// 暂不关心内部源代码
}
3、关于控制器类中处理请求的方法
关于处理请求的方法:
-
访问权限:应该使用
public
-
返回值类型:暂时使用
String
-
方法名称:自定义
-
参数列表:按需设计,即需要客户端提交哪些请求参数,在此方法的参数列表中就设计哪些参数,如果参数的数量有多个,并且多个参数具有相关性,则可以封装,并使用封装的类型作为方法的参数,另外,可以按需添加Spring容器中的其它相关数据作为参数,例如
HttpServletRequest
、HttpServletResponse
、HttpSession
等 -
异常:如果有,全部抛出
-
注解:需要通过
@RequestMapping
系列注解配置请求路径
4、关于@RequestMapping
在Spring MVC框架中,@RequestMapping
的主要作用是:配置请求路径与处理请求的方法的映射关系。
此注解可以添加在控制类上,也可以添加在处理请求的方法上。
通常,会在控制器类和处理请求的方法上都配置此注解,例如:
@RestController
@RequestMapping("/albums")
public class AlbumController {
@RequestMapping("/add-new")
public String addNew(AlbumAddNewDTO albumAddNewDTO) {
// 暂不关心方法内部代码
}
}
以上配置的路径将是:http://主机名:端口号/类上配置路径/方法上配置的路径
,即:http://localhost:8080/albums/add-new
并且,在使用`@RequestMapping
配置路径时,路径值两端多余的 /
是会被自动处理的,在类上的配置值和方法上的配置值中间的 /
也是自动处理的,例如,以下配置是等效的:
类上的配置值 | 方法上的配置值 |
---|---|
/albums | /add-new |
/albums | add-new |
/albums/ | /add-new |
/albums/ | add-new |
albums | /add-new |
albums | add-new |
albums/ | /add-new |
albums/ | add-new |
尽管以上8种组合配置是等效的,但仍推荐使用第1种。
在@RequestMapping
注解的源代码中,有:
@AliasFor("path")
String[] value() default {};
以上源代码表示在此注解中存在名为value
的属性,并且,此属性的值类型是String[]
,例如,你可以配置@RequestMapping(value = {"xxx", "zzz"})
,此属性的默认值是{}
(空数组)。
在所有注解中,value
是默认的属性,所以,如果你需要配置的注解参数是value
属性,且只配置这1个属性时,并不需要显式的指定属性名!例如:
@RequestMapping(value = {"xxx", "zzz"})
@RequestMapping({"xxx", "zzz"})
以上2种配置方法是完全等效的!
在所有注解中,如果某个属性的值是数组类型的,但是,你只提供1个值(也就是数组中只有一个元素),且这个值并不需要使用大括号框柱!例如:
@RequestMapping({"xxx", "zzz"})
@RequestMapping(value = "xxx")
以上2种配置方式是完全等效的!
在源代码中,关于value
属性的声明上还有@AliasFor("path")
,它表示”等效于“的意思,也就是说,value
属性与另一个名为path
的属性是完全等效的!
在@RequestMapping
的源代码中,还有:
RequestMethod[] method() default {};
以上属性的作用是配置并限制请求方式,例如,配置为:
@RequestMapping(value = "/add-new", method = RequestMethod.POST)
按照以上配置,以上请求路径只允许使用POST方式提交请求!
强烈建议在正式运行的代码中,明确的配置并限制各请求路径的请求方式!
另外,在Spring MVC框架中,还定义了基于@RequestMapping
的相关注解:
-
@GetMapping
-
@PostMapping
-
@PutMapping
-
@DeleteMapping
-
@PatchMapping
所以,在开发实践中,通常:在控制器类上使用@RequestMapping
配置请求路径的前缀部分,在处理请求的方法上使用@GetMapping
、@PostMapping
这类限制了请求方式的注解。