本文默认读者会创建Springboot项目,另外,本文采用kotlin语言。
@Controller
控制器用于接收和响应用户发送的请求,一个控制器类需要被@Controller注解:
@Controller
class TestController {
}
控制器类一般放在controller包下:
@RequestMapping
基本用法
@RequestMapping注解标注类或方法,表示它可以处理指定url的请求,一般处理方法都需要返回一个字符串:
@Controller
class TestController {
@RequestMapping("/index")
fun index(): String{
// 处理逻辑
}
}
如果我们使用@ResponseBody标注这个处理方法,那么它的返回值会原封不动地以字符串的形式返回给客户端,我们用一个例子来说明这一点:
创建一个Spring Boot项目,在controller包下创建一个TestController类:
package com.example.c0101.controller
import org.springframework.stereotype.Controller
import org.springframework.web.bind.annotation.RequestMapping
import org.springframework.web.bind.annotation.ResponseBody
@Controller
class TestController {
@RequestMapping("/index")
@ResponseBody
fun index(): String{
return "Hello World"
}
}
接下来,运行代码,访问http://127.0.0.1:8080/index,浏览器显示:
另外,@RequestMapping还可以让一个处理方法处理多个地址的请求:
@Controller
class TestController {
@RequestMapping(value=arrayOf("/index", "/main", "/"))
fun index(): String{
// 处理逻辑
}
}
注意,此时必须显示调用value,并传入一个Array
规定请求类型
@RequestMapping有一个method参数,通过对这个参数赋值,可以规定其能够接受的请求类型,同理需要传入一个Array:
@RequestMapping("/", method = arrayOf(RequestMethod.GET))
fun index(): String{
// 逻辑
}
我们看一个例子:
修改TestController类:
package com.example.c0101.controller
import org.springframework.stereotype.Controller
import org.springframework.web.bind.annotation.RequestMapping
import org.springframework.web.bind.annotation.RequestMethod
import org.springframework.web.bind.annotation.ResponseBody
@Controller
class TestController {
@RequestMapping("/", method = arrayOf(RequestMethod.GET))
@ResponseBody
fun get(): String{
return "GET请求"
}
@RequestMapping("/", method = arrayOf(RequestMethod.POST))
@ResponseBody
fun post(): String{
return "POST请求"
}
}
运行代码,使用postman分别发送GET和POST请求:
可以看到,服务器对于不同的请求返回了不同的字符串
规定请求参数
@RequestMapping有一个params参数,传入一个参数名的数组,可以规定其请求参数:
@RequestMapping("/", params = arrayOf("name"))
fun index(): String{
// 逻辑
}
我们来看一个例子:
修改TestController类:
package com.example.c0101.controller
import org.springframework.stereotype.Controller
import org.springframework.web.bind.annotation.RequestMapping
import org.springframework.web.bind.annotation.ResponseBody
@Controller
class TestController {
@RequestMapping("/", params = arrayOf("name"))
@ResponseBody
fun index(): String{
return "主页"
}
@RequestMapping("/")
@ResponseBody
fun noParams(): String{
return "参数错误"
}
}
可以看到,如果用户传入了name参数,则返回“主页”,否则返回“参数错误”。
使用postman分别测试传入参数和未传入参数的情况:
规定数据格式
规定数据格式可以使用consumes,传入一个Array,表示可以接收的数据格式:
@RequestMapping("/", consumes = arrayOf("application/json"))
fun index(): String{
//逻辑
}
举个例子:
修改TestController:
package com.example.c0101.controller
import org.springframework.stereotype.Controller
import org.springframework.web.bind.annotation.RequestMapping
import org.springframework.web.bind.annotation.ResponseBody
@Controller
class TestController {
@RequestMapping("/", consumes = arrayOf("application/json"))
@ResponseBody
fun index(): String{
return "主页"
}
@RequestMapping("/")
@ResponseBody
fun noParams(): String{
return "格式错误"
}
}
可以看到,如果用户发送json数据,服务器会返回“主页”,否则返回“格式错误”。
使用postman分别发送json格式、非json格式的请求体:
将@RequestMapping标注在类上
@RequestMapping不仅可以标注在方法上,还可以标注在类上。标注在类上后,方法的@RequestMapping表示下一层的地址:
@Controller
@RequestMapping("/shop")
class TestController {
@RequestMapping("/index")
@ResponseBody
fun index(): String{
return "主页"
}
@RequestMapping("/book")
@ResponseBody
fun book(): String{
return "图书页"
}
}
此时,访问主页需要访问/shop/index,访问图书页需要访问/shop/book。
页面跳转
如果不标注@ResponseBody,则会根据返回的字符串进行页面跳转:
修改TestController:
package com.example.c0101.controller
import org.springframework.stereotype.Controller
import org.springframework.web.bind.annotation.RequestMapping
import org.springframework.web.bind.annotation.ResponseBody
@Controller
class TestController {
@RequestMapping("/")
fun index(): String{
return "/book"
}
@RequestMapping("/book")
@ResponseBody
fun book(): String{
return "图书页"
}
}
可以看到,当访问/地址时,会跳转至/book地址,使用浏览器访问http://127.0.0.1:8080/:
我们也可以跳转至其他网站,修改TestController:
package com.example.c0101.controller
import org.springframework.stereotype.Controller
import org.springframework.web.bind.annotation.RequestMapping
@Controller
class TestController {
@RequestMapping("/")
fun index(): String{
return "redirect:http://www.baidu.com/"
}
}
访问http://127.0.0.1:8080/:
可以看到,页面跳转到了百度网站上。
@RestController
@RestController实际上是@Controller和@ResponseBody的简化版,被这个注解标注的控制器类的方法默认向客户端直接返回字符串
传递参数
传递参数可以自动传递,也可以通过@RequestParam传递:
自动传递
修改TestController如下:
package com.example.c0101.controller
import org.springframework.web.bind.annotation.RequestMapping
import org.springframework.web.bind.annotation.RestController
@RestController
class TestController {
@RequestMapping("/")
fun index(name: String): String{
return "你的用户名是$name"
}
}
使用postman访问,并规定用户名:
注意:由于方法的参数名是name,所以传入的参数名也应该是name.
如果我们不提供正确的参数,服务器会报错:
这是因为Kotlin的默认数据类型不支持null,如果想要允许这种情况,可以修改name的类型为String?,再重试:
通过@RequestParam传递
@RequestParam可以传入一个value参数(也是默认属性),是传入参数的名称:
@RestController
class TestController {
@RequestMapping("/")
fun index(@RequestParam("name") username: String?): String{
return "你的用户名是$username"
}
}
传递请求体
@RequestBody可以用于传递请求体:
@RestController
class TestController {
@RequestMapping("/")
fun index(@RequestBody username: String?): String{
return "你的用户名是$username"
}
}
如果传入的请求体是json,且方法参数的类型也是对应的类型,则@RequestBody会自动封装json数据:
修改TestController如下:
package com.example.c0101.controller
import org.springframework.web.bind.annotation.RequestBody
import org.springframework.web.bind.annotation.RequestMapping
import org.springframework.web.bind.annotation.RestController
@RestController
class TestController {
@RequestMapping("/")
fun index(@RequestBody usernames: List<String>): String{
var users = ""
for (user in usernames){
users += user
users += "\n"
}
return users
}
}
使用postman发送一个json数组:
可以看到,服务器向浏览器返回了用户列表。
动态URL地址
我们也可以将URL地址的一部分作为参数传递给方法,使用@PathVariable:
修改TestController如下:
@RestController
class TestController {
@RequestMapping("/{name}")
fun index(@PathVariable("name") username: String): String{
return "你的用户名是$username"
}
}
访问http://127.0.0.1:8080/zhangsan,可以看到:
访问http://127.0.0.1:8080/lisi,可以看到: