高效开发:Controller层涉及的注解辨析
Posted Java架构师(公众号:毛奇志)
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了高效开发:Controller层涉及的注解辨析相关的知识,希望对你有一定的参考价值。
文章目录
前言
接口对外暴露就是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格式。
以上是关于高效开发:Controller层涉及的注解辨析的主要内容,如果未能解决你的问题,请参考以下文章
spring的注解形式:@Repository@Service@Controller,
springmvc里面自定义注解实现aop,controller层里面注解一直不生效,但是注解放在service层又可以??
高效开发:如何使用@Tranactional注解保证本地事务一致性