高效开发:Controller层涉及的注解辨析

302 阅读5分钟

文章目录

前言

接口对外暴露就是Controller层,所有Controller涉及的注解就是这么多,接口三板斧:url(包括请求方式)、接收参数、返回值

和接口 url 相关的三个Mappering后缀注解

@GetMapping @PostMapping @RequestMapping 三个都是spring注解,都是Mappering后缀注解,都是和和接口 url 相关的注解。

@GetMapping用于将HTTP get请求映射到特定处理程序的方法注解
具体来说,@GetMapping是一个组合注解,是@RequestMapping(method = RequestMethod.GET)的缩写。

@PostMapping用于将HTTP post请求映射到特定处理程序的方法注解
具体来说,@PostMapping是一个组合注解,是@RequestMapping(method = RequestMethod.POST)的缩写。

@RestController
@RequestMapping("/hello")
public class HelloController{
    @GetMapping("/getRule")
    public Rule getRule(){
        Rule rule=new Rule();
        return rule;
    }
    @RequestMapping(method = RequestMethod.GET  ,value = "/getRule2")
    public Rule getRule2(){
        Rule rule=new Rule();
        return rule;
    }
}

实际开发上,可以在Controller类中使用@RequestMapping写公共url路径,在方法中使用@GetMapping @PostMapping 简写,这样是可以的。

和接收参数相关的两个Request前缀注解

@RequestParam、 @RequestBody的区别

@RequestParam处理键值对,@RequestBody处理Json对象

两者的应用场景不一样,使用@RequestParam主要处理contentType为application/x-www-form-urlencoded的数据, 这种格式的特点就是,name/value 成为一组,每组之间用 & 联接,而 name与value 则是使用 = 连接。

如: wwwh.baidu.com/q?key=fdsa&lang=zh 这是get , 而 post 请求则是使用请求体,虽然参数不在 url 中,在请求体中的参数表现形式也是: key=fdsa&lang=zh的形式。

这种方式的好处就是所有浏览器都支持,在请求发送过程中会对数据进行序列化处理,以键值对形式。 但是application/x-www-form-urlencoded 是没有办法将复杂的 JSON 组织成键值对形式,你可以发送请求,但是服务端收到数据为空, 因为 ajax不知道怎样处理这个数据。

使用@RequestBody:主要处理contentType不为application/x-www-form-urlencoded的数据,比如application/json。所以,我们一般调用ajax请求用@RequestBody一定要注意在ajax中要指明contentType:“application/json;charset=UTF-8” data:JSON.stringify(json数组);

这里简单科普一下,原生的表单提交或ajax提交的请求如果不指定contentType属性(表单中为enctype)则都是默认为application/x-www-form-urlencoded

看到这里那么有的小伙伴要就要问了,公司产品里很多页面是调用ajax请求,接口用的是@RequestBody注解接收参数,也没看到指定contentType application/json;charset=UTF-8呀,如下图所示:

在这里插入图片描述

在这里插入图片描述

而且貌似参数都不是json格式的字符串而是一个JSON对象,这是因为 。。。

在这里插入图片描述

这个是工具类调用的ajax,也就是说这个ajax是被公司封装过的,里面的内容如下

在这里插入图片描述

现在是不是一切都说得通了!!!

有些小伙伴一直搞不明白JSON对象和json字符串的区别,这里也简单科普一下。
JSON的全称是JavaScript Object Notation,即JSON是JavaScript原生格式,即一个JavaScript对象
JSON中的五种写法这里就不一一介绍了,有兴趣的可以自己去百度。
而json字符串顾名思义,即JSON转字符串,一般使用JSON.stringify()

@RequestParam可以使用多个,@RequestBody只能使用一个

使用@RequestParam:要指明前端传过来的参数名并与其对应

在这里插入图片描述

同一个方法中可以使用多个@RequestParam注解,比如form表单,往往不会提交指定某个字符串作为参数,而是提交整个表单,就可以用下面这种方式去接收表单的参数

在这里插入图片描述

那么@RequestBody注解可以使用多次吗

答案是 不可以!!!

但是它可以定义一个对象去接收所有的参数,比如

在这里插入图片描述

那么该实体变量匹配到的所有参数就都可以被接收了,如果匹配不到怎么办,没关系,如果是继承了框架BaseEntity的实体,那么该实体则继承了Map的特性

即使匹配不到也可以存到其的Map父类的 key-value中。

小结:一般情况下, RequestBody 注解 ,代表 json格式提交数据;RequestParams或者省略,代表 form 形式的提交数据。

另外,附加上“参数默认值或允许不传递的处理”,如下:

@GetMapping("/hello")
public String hello(
@RequestParam(value ="param1" ,defaultValue="1") Integer param1,
@RequestParam(value ="param1" ,request=false) String param2 ,
@RequestParam(value ="param1" ,defaultValue="false") Boolean param3 )

不管参数是什么类型,Integer还是Boolean还是String,默认值都是String。

和返回结果相关的三个注解

@Controller @ResponseBody @RestController 三个都是spring注解,由于后端更多的是返回数据而不是页面跳转,所有@RestController出现了

@RestController注解相当于@ResponseBody + @Controller合在一起的作用。

1.使用@Controller 注解,在对应的方法上,视图解析器可以解析return 的jsp,html页面,并且跳转到相应页面;若返回json等内容到页面,则需要加@ResponseBody注解。

 @CrossOrigin 
 @Controller 
 public class HospitalController {
    //注入Service服务对象
    @Autowired
    private HospitalService hospitalService;
    /**
     * 查询所有医院信息(未分页)
     */
    @RequestMapping(value = "findAllHospital",method = RequestMethod.GET)
    public @ResponseBody List<Hospital> findAllHospital(){
        List<Hospital> hospitalList= hospitalService.findAllHospital();
        return hospitalList;
    }
}

2.@RestController注解,相当于@Controller+@ResponseBody两个注解的结合,返回json数据不需要在方法前面加@ResponseBody注解了,但使用@RestController这个注解,就不能返回jsp,html页面,视图解析器无法解析jsp,html页面。

 @CrossOrigin 
 @RestController /* @Controller + @ResponseBody*/ 
 public class HospitalController {
    //注入Service服务对象
    @Autowired
    private HospitalService hospitalService;
    /**
     * 查询所有医院信息(未分页)
     */
    @RequestMapping(value = "findAllHospital",method = RequestMethod.GET)
    public  List<Hospital> findAllHospital(){
        List<Hospital> hospitalList= hospitalService.findAllHospital();
        return hospitalList;
    }
}

小结:Controller 注解,返回视图(试图解析器+前缀后缀);
Controller + ResponseBody 注解或者 RestController 注解,代表返回json格式。