关于控制器详解

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容器中的其它相关数据作为参数,例如HttpServletRequestHttpServletResponseHttpSession

  • 异常:如果有,全部抛出

  • 注解:需要通过@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
/albumsadd-new
/albums//add-new
/albums/add-new
albums/add-new
albumsadd-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这类限制了请求方式的注解。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值