本节需求:外部通过url与服务端进行数据交互。
本节demo 在项目中的demo01下
Controller 是程序与外界沟通的入口,学会Controller 相关知识,主要是一些注解的使用是必备的基础知识,这节课就让我们来了解和使用Controller及其相关注释。
在上一节课的基础上,新建一个类 HelloController ,并且在类上和方法上写上相应的注解,如下:
@Controller
public class HelloController {
@GetMapping("/hello")
@ResponseBody
public String say() {
return "Hello Controller";
}
}
然后重新启动工程,然后访问,http://localhost:8080/hello ,不出意外将会返回 Hello Controller。这部分都是依赖于注解来运行的,这里我们着重讲什么去使用,暂不去理会背后的原理,会用了才能谈上其他的。接下来我们就一起看下一些常用的注解。
- @Controller 标明这个类是一个控制器,是交互的入口,默认返回view对象,在此先不考虑view对象的情况。
- @RestController 标明此Controller 提供RestAPI(没有ResrAPI 概念的在这可直接理解成返回json的数据格式),此注解是Spring4 之后添加的
- @ResponseBody 标明该请求返回的数据格式指定为json字符串。
- 以上三者之间的关系 @Controller 默认返回view类型,和 @ResponseBody 配合使用可返回json,相当于 @ResponseBody + @Controller = @RestController
- @RequestMapping 及其变体 映射http请求到java的方法, 常用的变体有GetMapping、PostMapping、PutMapping、DeleteMapping,分别代表查、增、改和删四种操作,不常用的有HeadMapping、OptionsMapping和PatchMapping。
- @RequstParam 映射请求参数到java 方法的参数,通常用于get请求中url 携带的参数。
- @PathVariable 映射url片段到java方法的参数
@RestController = @ResponseBody + @Controller;对比上个示例即可看出区别
@RestController
public class HelloController {
@GetMapping("/hello")
public String say() {
return "Hello RestController";
}
}
- 配置url 的映射,如果不指定请求方法,默认此注解包含了所有注解,基本用法如下:
@RestController
public class HelloController {
//指定请求方式为Get请求:method = RequestMethod.GET,如果不指定请求方法,那所有的请求方法都可以调用。
@RequestMapping(name = "/hello", method = RequestMethod.GET)
public String hello() {
return "Hello RequestMapping";
}
//与上面的方法等价,通常都是用下面这种方式
@GetMapping("/hello")
public String say() {
return "Hello GetMapping";
}
}
RequestMapping 的变体使用XXXMapping即可
- RequestMapping 常用的方式,指定url共同的片段
假设我现在设计的url 如下:
http://localhost:8080/hello/say
http://localhost:8080/hello/listen
那我该怎么写呢?显然是可以这样写的
@RestController
public class HelloController {
@GetMapping("/hello/say")
public String say() {
return "Hello say";
}
@GetMapping("/hello/listen")
public String listen() {
return "Hello listen";
}
}
但是这样如果有很多个方法,导致不断重写“/hello”,如果要改也很麻烦。我们可以有更优雅的办法,如下:
在类上添加@RequestMapping("/hello"),效果是一样的
@RestController
@RequestMapping("/hello")
public class HelloController {
@GetMapping("/say")
public String say() {
return "Hello say";
}
@GetMapping("/listen")
public String listen() {
return "Hello listen";
}
}
- 同一个方法映射多个url 地址
假设我现在设计的url 如下,因为一个类中方法名不能重名,那是不是意味着要写两个方法来映射不同的url,显然这是不可取的。
http://localhost:8080/hello/say
http://localhost:8080/hi/say
在 RequestMapping 配置多个不同的url片段即可
@RestController
@RequestMapping({"/hello","/hi"})
public class HelloController {
@GetMapping("/say")
public String say() {
return "Hello";
}
}
@GetMapping、@PostMapping 等变体类似于@RequestMapping的用法,都是配置url的映射,不同在于@GetMapping、@PostMapping 这些只能用于方法上,不能用于类上,@RequestMapping即可用于类上,也可以用于方法上。
如果@RequestMapping 不指定请求的方法等同于包含了@GetMapping、@PostMapping 等所以这些请求,也就是可以通过所有请求方法访问。通常来说需要明确指定那种方式访问。
如果我们想把参数放到url上,如 http://localhost:8080/hello/say/1 ,最后的“1”是我们想要获取的参数,我们就可以通过@PathVariable注解来获取。
@RestController
@RequestMapping("/hello")
public class HelloController {
@GetMapping("/say/{id}")
public String say(@PathVariable("id") Integer myId) {
return "hello,my id is " + myId;
}
}
这样我们就能够获取url中携带的参数了。
其格式为:{id},id为对应url中的参数值,@PathVariable(“id”) 中的“id”务必与url 映射的片段一致。
请求结果如下: hello,my id is 1
获取请求参数的值。对于get请求来说,除了通过以上的方式获取参数外,还有另一种方式,一般的结构如下,地址和参数之间以“?”分隔,后面是参数,参数之间以&符号分隔如:http://localhost:8080/hello/say?username=lili&age=18 此时想获取该参username 和age 惨数,需要用到@RequestParam
@RestController
@RequestMapping("/hello")
public class HelloController {
@GetMapping("/say")
public String say(@RequestParam("username") String mUsername,@RequestParam("age") String mAge) {
return "hello,my name is " + mUsername + ", I am " +mAge;
}
}
此时如果不传该参数,将会报错找不到该资源。如果该参数可有可无,又该怎么处理,
我们只需要设置@RequestParam 的属性即可,例子如下:required 的默认值为true,表示该参数必须。
@RestController
@RequestMapping("/hello")
public class HelloController {
@GetMapping("/say")
public String say(@RequestParam("username") String mUsername,@RequestParam("age",required = false,defaultValue = "18") String mAge) {
return "hello,my name is " + mUsername + ", I am " +mAge;
}
}
post 请求可以有多种方式获取,可以通过Map的形式,也可以通过json 对象形式,这里我们通过json方式示例,请求方将参数放在请求体中以application/json的形式发送。content-type:application/json
@PostMapping("/save")
public User saveUser(@RequestBody User user) {
System.out.println("username:"+user.getUserName +", age:"+user.getAge);
return user;
}
User是一个实体对象,将参数封装起来
public class User {
private String username;
private Integer age;
//省略get/set
}
总结
- @Controller: 处理http请求,默认返回view,配合@ResponseBody使用返回json字符串;
- @RestController: @RestController=@Controller+@ResponseBody,返回json 字符串;
- @RequestMapping 配置url映射,即可作用于类上,也可以作用于方法上,如果不指定请求方法,将包含所有变体。
- @GetMapping/PostMapping 等作用类似于@RequestMapping,但是只能作用于方法上
- @PathVariable 获取url中的数据
- @RequestParam 获取请求参数的值
- POST方式参数的获取