本文介绍在使用springBoot如何进行Restful Api接口的开发及相关注解已经参数传递如何处理。

一、概念:

  REST全称是Representational State Transfer,中文意思是表述(编者注:通常译为表征)性状态转移。 它首次出现在2000年Roy Fielding的博士论文中,Roy Fielding是HTTP规范的主要编写者之一。 他在论文中提到:"我这篇文章的写作目的,就是想在符合架构原理的前提下,理解和评估以网络为基础的应用软件的架构设计,得到一个功能强、性能好、适宜通信的架构。REST指的是一组架构约束条件和原则。" 如果一个架构符合REST的约束条件和原则,我们就称它为RESTful架构。
  REST本身并没有创造新的技术、组件或服务,而隐藏在RESTful背后的理念就是使用Web的现有特征和能力, 更好地使用现有Web标准中的一些准则和约束。虽然REST本身受Web技术的影响很深, 但是理论上REST架构风格并不是绑定在HTTP上,只不过目前HTTP是唯一与REST相关的实例。 所以我们这里描述的REST也是通过HTTP实现的REST。

二、注解说明:

1.Rest控制器

@RestController注释用于定义RESTful Web服务。它提供JSON,XML和自定义响应。其语法如下所示

@RestController
public class UserRestController{ }

有了该注解,在响应返回的是json格式的数据,我们就不要写@ResponseBody注解了

2.Java请求映射

@RequestMapping注释用于定义访问REST端点的Request URI。可以定义Request方法来使用和生成对象。默认请求方法是:GET。

@RequestMapping(value = "/products")
public List<ApiUser> getAllUsers(){ }

该注解还可以有几个属性:method制定请求允许的request方法,produces返回的数据类型,例如以下写法:

@RequestMapping(value = "/user/roleCode/{roleCode}", method = RequestMethod.GET,produces=MediaType.APPLICATION_JSON_UTF8_VALUE) 

当然我们也可以在全局类前指定返回的数据类型。例如:

@RestController
@RequestMapping(value = "/rest", produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
public class UserRestController{
....

3.Java请求主体

@RequestBody注释用于定义请求正文内容类型。

public List<ApiUser> getUserListByApiUser(@RequestBody ApiUser apiUser) {

}

4.Java路径变量

@PathVariable批注用于定义自定义或动态请求URI。 请求URI中的Path变量定义为花括号{},如下所示

public List<ApiUser> getUserByRoleCode(@PathVariable("roleCode") String roleCode){

}

5.Java请求参数

@RequestParam注释用于从请求URL读取请求参数。默认情况下,它是必需参数。还可以为请求参数设置默认值,如下所示 -

public List<ApiUser> getUserByUserName(@RequestParam(value = "userName", required = false, defaultValue = "system") String userName) {

}

6.@RequestParam与@PathVariable的区别

在spring MVC中,两者的作用都是将request里的参数的值绑定到contorl里的方法参数里的,区别在于,URL写法不同。

使用@RequestParam时,URL是这样的:http://host:port/path?参数名=参数值

使用@PathVariable时,URL是这样的:http://host:port/path/参数值

例如

三、RestFul风格提交:

  RESTful架构应该遵循统一接口原则,统一接口包含了一组受限的预定义的操作,不论什么样的资源,都是通过使用相同的接口进行资源的访问。接口应该使用标准的HTTP方法如GET,PUT和POST,并遵循这些方法的语义。如果按照HTTP方法的语义来暴露资源,那么接口将会拥有安全性和幂等性的特性,例如GET和HEAD请求都是安全的, 无论请求多少次,都不会改变服务器状态。而GET、HEAD、PUT和DELETE请求都是幂等的,无论对资源操作多少次, 结果总是一样的,后面的请求并不会产生比第一次更多的影响。

  本文主要介绍,POST、PUT、DELETE、GET四种风格的restful请求。@RequestMapping(value="/") method 不写的话,默认GET、POST都支持,根据前端方式自动适应。

3.1 GET主要用于资源的获取

例如:比如根据用户编码获取用户。我们就可以使用Get,传单个参数,根据参数去查询用户

@RequestMapping(value = "/user/userCode/{userCode}", method = RequestMethod.GET)
public ApiUser getUserByUserCode(@PathVariable("userCode") String userCode) {
AfaUser user = userService.getAfaUserByUserCode(userCode);
ApiUser apiUser=BeanUtils.copyBean(user,ApiUser.class);
if(user!=null){
List<OrgBean> orgs=this.getOrgParentListByOrgId(user.getMainOrgid());
apiUser.setOrgs(orgs);
}
return apiUser;
}

有人就问了,那要是我有多个参数,GET我怎么操作了:

方法一:换成POST请求,将所有参数封装成一个类,然后使用 @RequestBody注解将参数自动解析成该类的一个实例

@ApiOperation(value = "根据用户对象获取用户列表")
@RequestMapping(value = "/users", method = RequestMethod.POST)
public List<ApiUser> getUserListByApiUser(@RequestBody ApiUser apiUser) {
AfaUser afaUser = BeanUtils.copyBean(apiUser, AfaUser.class);
List<ApiUser> apiUserList=BeanUtils.copyList(userService.getAfaUserList(afaUser), ApiUser.class);
for(ApiUser _user:apiUserList){
if(StringUtils.isNotNullAndBlank(_user.getMainOrgid())){
List<OrgBean> orgs=this.getOrgParentListByOrgId(_user.getMainOrgid());
_user.setOrgs(orgs);
}
}
return apiUserList;
}

有人说那你这样就不符合规范了,不过,这个“规范”只是建议大家这么来遵守,并不是强制要求

方法二:还是使用GET请求,但是将所有请求参数通过JSON格式来传递,controller拿到参数后,使用 JSON 相关的库(如 gson),将该JSON转化为相应的对象

public List<String> getName(@RequestParam String queryDtoStr) {
QueryDto queryDto = new Gson().fromJson(queryDtoStr, QueryDto .class);
// ....
return new ArrayList<>();
}

这样请求的就要像这样:

http://localhost:8080/app/names?queryDtoStr={"query1":12,"query2":2,"query3":2}

3.2 POST主要用于创建资源

HTTP POST请求用于创建资源。 此方法包含请求正文。可以发送请求参数和路径变量来定义自定义或动态URL。例如:

@RequestMapping(value="/user", method = RequestMethod.POST)
public void doInsert(@RequestBody ApiUser apiUser) {
AfaUser user = BeanUtils.copyBean(apiUser, AfaUser.class);
userService.addAfaUser(user);
}

3.3 PUT主要用于更新资源

HTTP PUT请求用于更新现有资源,此方法包含请求正文。可以发送请求参数和路径变量来自定义或动态URL。例如:

    @RequestMapping(value = "/user", method = RequestMethod.PUT)
public void doUpdate(@RequestBody ApiUser apiUser) {
AfaUser user = BeanUtils.copyBean(apiUser, AfaUser.class);
userService.updateAfaUser(user);
}

3.4 DELETE主要用于删除资源

HTTP DELETE请求用于删除现有资源,此方法包含请求正文。可以发送请求参数和路径变量来自定义或动态URL。例如:

    @ApiOperation(value = "删除用户")
@RequestMapping(value = "/user", method = RequestMethod.DELETE)
public void doDelelte(@RequestBody ApiUser apiUser) {
AfaUser user = BeanUtils.copyBean(apiUser, AfaUser.class);
userService.delAfaUser(user);
}

以上方法参数是接收一个对象,如果是单个属性,可以直接跟在url后面。

完整示例:

/**
*
* @author Shaw
*
*/
@RestController
@RequestMapping(value = "/rest", produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
@Api(value = "/rest", tags = "UserRestController", description = "用户管理接口")
public class UserRestController{ @Resource
private AfaUserService userService; @Resource
private AfaRoleService afaRoleService; @Resource
private AfaOrgService orgService; @Resource
private MenuHelper menuHelper; @Resource
private AfaOrgService afaOrgService; @Resource
private AfaAuthPartyService afaAuthPartyService; @ApiOperation(value = "新增用户")
@RequestMapping(value="/user", method = RequestMethod.POST)
public void doInsert(@RequestBody ApiUser apiUser) {
AfaUser user = BeanUtils.copyBean(apiUser, AfaUser.class);
userService.addAfaUser(user);
} @ApiOperation(value = "更新用户")
@RequestMapping(value = "/user", method = RequestMethod.PUT)
public void doUpdate(@RequestBody ApiUser apiUser) {
AfaUser user = BeanUtils.copyBean(apiUser, AfaUser.class);
userService.updateAfaUser(user);
} @ApiOperation(value = "删除用户")
@RequestMapping(value = "/user", method = RequestMethod.DELETE)
public void doDelelte(@RequestBody ApiUser apiUser) {
AfaUser user = BeanUtils.copyBean(apiUser, AfaUser.class);
userService.delAfaUser(user);
} @ApiOperation(value = "修改密码")
@RequestMapping(value = "/user/password", method = RequestMethod.PUT)
public void resetUserPassWord(@RequestBody ApiUser apiUser) {
AfaUser afaUser = BeanUtils.copyBean(apiUser, AfaUser.class);
userService.resetUserPassWord(afaUser);
} @ApiOperation(value = "根据用户编码获取用户")
@RequestMapping(value = "/user/userCode/{userCode}", method = RequestMethod.GET)
public ApiUser getUserByUserCode(@PathVariable("userCode") String userCode) {
AfaUser user = userService.getAfaUserByUserCode(userCode);
ApiUser apiUser=BeanUtils.copyBean(user,ApiUser.class);
if(user!=null){
List<OrgBean> orgs=this.getOrgParentListByOrgId(user.getMainOrgid());
apiUser.setOrgs(orgs);
}
return apiUser;
} @ApiOperation(value = "根据用户id获取用户")
@RequestMapping(value = "/user/userId/{userId}", method = RequestMethod.GET)
public ApiUser getUserByUserId(@PathVariable("userId") String userId) {
if(StringUtils.isNotNullAndBlank(userId)){
AfaUser user = userService.getAfaUserByUserId(userId);
ApiUser apiUser=BeanUtils.copyBean(user,ApiUser.class);
if(user!=null){
List<OrgBean> orgs=this.getOrgParentListByOrgId(user.getMainOrgid());
apiUser.setOrgs(orgs);
}
return apiUser;
}
return null;
} @ApiOperation(value = "根据角色编码获取用户")
@RequestMapping(value = "/user/roleCode/{roleCode}", method = RequestMethod.GET)
public List<ApiUser> getUserByRoleCode(@PathVariable("roleCode") String roleCode) {
List<AfaUser> user = userService.getUserByRoleCode(roleCode);
return BeanUtils.copyList(user, ApiUser.class);
} @ApiOperation(value = "获取所有用户")
@RequestMapping(value = "/users", method = RequestMethod.GET)
public List<ApiUser> getAllUserList() {
return BeanUtils.copyList(userService.getAfaUserList(),ApiUser.class);
} @ApiOperation(value = "根据用户对象获取用户列表")
@RequestMapping(value = "/users", method = RequestMethod.POST)
public List<ApiUser> getUserListByApiUser(@RequestBody ApiUser apiUser) {
AfaUser afaUser = BeanUtils.copyBean(apiUser, AfaUser.class);
List<ApiUser> apiUserList=BeanUtils.copyList(userService.getAfaUserList(afaUser), ApiUser.class);
for(ApiUser _user:apiUserList){
if(StringUtils.isNotNullAndBlank(_user.getMainOrgid())){
List<OrgBean> orgs=this.getOrgParentListByOrgId(_user.getMainOrgid());
_user.setOrgs(orgs);
}
}
return apiUserList;
} @ApiOperation(value = "根据角色编码获取角色")
@RequestMapping(value = "/users/roleCodes", method = RequestMethod.POST)
public List<ApiUser> getUserByRoleCodes(@RequestBody List<String> roleList) {
return BeanUtils.copyList(userService.getUserByRoleCodes(roleList),ApiUser.class);
} @ApiOperation(value = "根据角色编码获取角色")
@RequestMapping(value = "/users/page", method = RequestMethod.POST)
public Page<ApiUserOrgPos> queryAfaUserPage(@RequestBody Searcher searcher,Page<ApiUserOrgPos> page) {
Page<AfaUserOrgPos> apiUserOrgPos = BeanUtils.copyList(page, AfaUserOrgPos.class);
return BeanUtils.copyList(userService.queryAfaUserPage(searcher, apiUserOrgPos,null), ApiUserOrgPos.class);
} @ApiOperation(value = "根据用户对象获取角色列表")
@RequestMapping(value = "/role/user/", method = RequestMethod.POST)
public List<ApiRole> getRolesByUser(@RequestBody ApiUser apiUser) {
AfaUser afaUser = BeanUtils.copyBean(apiUser, AfaUser.class);
String userCode=afaUser.getUserCode();
return BeanUtils.copyList(menuHelper.findRoleByUserCode(userCode, null), ApiRole.class);
} @ApiOperation(value = "根据用户Id对象获取角色列表")
@RequestMapping(value = "/role/userId/{userId}", method = RequestMethod.GET)
public List<ApiRole> getRolesByUserId(@PathVariable("userId") String userId) {
AfaUser afaUser=userService.getAfaUserByUserId(userId);
String userCode=afaUser.getUserCode();
return BeanUtils.copyList(menuHelper.findRoleByUserCode(userCode, null), ApiRole.class);
} @ApiOperation(value = "根据角色编码、机构id获取用户列表")
@RequestMapping(value = "/users/{roleCode}/{orgId}", method = RequestMethod.GET)
public List<ApiUser> getUsersByRoleCodeAndOrgId(@PathVariable("roleCode") String roleCode, @PathVariable("orgId") String orgId) {
List<AfaUser> afaUserList=new ArrayList<AfaUser>();
//1、先获取机构编码
AfaOrg afaOrg=null;
if(StringUtils.isNotNullAndBlank(orgId)){
afaOrg=afaOrgService.getAfaOrgByOrgId(orgId);
} String orgCode=null;
if(afaOrg!=null){
orgCode=afaOrg.getOrgCode();
} //2、根据机构编码和角色获取角色授权表
List<AfaAuthParty> partyList=null;
if(StringUtils.isNullOrBlank(roleCode)&&StringUtils.isNullOrBlank(orgId)){ }else{
partyList=afaAuthPartyService.getAfaAuthPartyByRoleCodeAndOrgCode(orgCode,roleCode);
} //3、根据party_type类型获取用户。
//当party_type为org的时候,获取该org下的所有用户
//当party_type为user的时候,判断该用户的主机构是不是orgId下的
if(partyList!=null&&partyList.size()!=0){
for(AfaAuthParty _party:partyList){
AfaUser afaUser=new AfaUser();
if(StringUtils.isNotNullAndBlank(orgId)){
afaUser.setMainOrgid(orgId);
} if("org".equals(_party.getPartyType())){
afaUserList.addAll(userService.getAfaUserList(afaUser));
} if("user".equals(_party.getPartyType())){
afaUser.setUserCode(_party.getPartyCode());
}
afaUserList.addAll(userService.getAfaUserList(afaUser));
}
}
if(afaUserList.size()!=0){
for (int i = 0; i < afaUserList.size()-1; i++) {
for (int j = afaUserList.size()-1; j > i; j--) {
if (afaUserList.get(j).getUserCode().equals(afaUserList.get(i).getUserCode())) {
afaUserList.remove(j);
}
}
}
} return BeanUtils.copyList(afaUserList, ApiUser.class);
} @ApiOperation(value = "更新某些机构下用户的状态")
@RequestMapping(value = "/users/status", method = RequestMethod.POST)
public void changeUserStatusByOrgIdList(@RequestBody UserRequestParam requestParamObject) {
if(CollectionUtils.isNotEmpty(requestParamObject.getOrgIdList())){
userService.changeUserStatusByOrgIdList(requestParamObject.getOrgIdList(),requestParamObject.getStatus());
}
} @ApiOperation(value = "根据casn获取用户列表")
@RequestMapping(value = "/users/casn/{caSn}", method = RequestMethod.GET)
public List<ApiUser> getApiUserByCaSn(@PathVariable("caSn")String caSn) {
List<AfaUser> afaUser=userService.getApiUserByCaSn(caSn);
return BeanUtils.copyList(afaUser, ApiUser.class);
} }

SpringBoot RestFul风格API接口开发的更多相关文章

  1. Restful风格API接口开发springMVC篇

    Restful风格的API是一种软件架构风格,设计风格而不是标准,只是提供了一组设计原则和约束条件.它主要用于客户端和服务器交互类的软件.基于这个风格设计的软件可以更简洁,更有层次,更易于实现缓存等机 ...

  2. SpringBoot实战(二)Restful风格API接口

    在上一篇SpringBoot实战(一)HelloWorld的基础上,编写一个Restful风格的API接口: 1.根据MVC原则,创建一个简单的目录结构,包括controller和entity,分别创 ...

  3. 通过beego快速创建一个Restful风格API项目及API文档自动化

    通过beego快速创建一个Restful风格API项目及API文档自动化 本文演示如何快速(一分钟内,不写一行代码)的根据数据库及表创建一个Restful风格的API项目,及提供便于在线测试API的界 ...

  4. 通过beego快速创建一个Restful风格API项目及API文档自动化(转)

    通过beego快速创建一个Restful风格API项目及API文档自动化 本文演示如何快速(一分钟内,不写一行代码)的根据数据库及表创建一个Restful风格的API项目,及提供便于在线测试API的界 ...

  5. 第03章—打造RESTful风格API

    spring boot 系列学习记录:http://www.cnblogs.com/jinxiaohang/p/8111057.html 码云源码地址:https://gitee.com/jinxia ...

  6. API接口开发 配置、实现、测试

    Yii2 基于RESTful架构的 advanced版API接口开发 配置.实现.测试 环境配置: 开启服务器伪静态 本处以apache为例,查看apache的conf目录下httpd.conf,找到 ...

  7. day2(RESTful风格API)

    1.RESTful风格API  详情查看博客地址:https://www.cnblogs.com/xiaonq/p/10053234.html 1.1 什么是RESTful REST与技术无关,代表的 ...

  8. F5 api接口开发实战手册(二)

    F5 rest api 各对象使用方式详解 本篇文章介绍rest api接口下Collection.Resource.Subcollections.SubResource的各种使用方法.如果您不了解这 ...

  9. 浅谈使用 PHP 进行手机 APP 开发(API 接口开发)

    做过 API 的人应该了解,其实开发 API 比开发 WEB 更简洁,但可能逻辑更复杂,因为 API 其实就是数据输出,不用呈现页面,所以也就不存在 MVC(API 只有 M 和 C),那么我们来探讨 ...

随机推荐

  1. linux基础11-bash编程(字符串测试 和 for循环)

    练习:传递一个用户名参数给脚本,判断此用户的用户名跟其基本组的组名是否一致,并将结果显示出来.(1)字符测试:==:测试是否相等,相等为真,不等为假!=: 测试是否不等,不等为真,等为假>< ...

  2. linux下查看进程命令

    他们都是用来显示当前运行的进程,但是: ps -aux 是用BSD的格式来显示python这个进程显示的项目有:USER , PID , %CPU , %MEM , VSZ , RSS , TTY , ...

  3. postman(一):主界面模块解析

    在做接口测试时经常会用到postman,但是一直没有总结过,太过零散,这次找了一些好的资料,结合自己平时所用到的功能,总结一波 打开postman,主界面如下 左侧菜单 1.History标签 里面存 ...

  4. winform 分页控件

    http://www.cnblogs.com/liuyunsheng/p/4853387.html http://www.cnblogs.com/wuhuacong/archive/2011/07/0 ...

  5. Confluence 6 示例 - https://confluence.atlassian.com/

    这里是有关存储空间和内存使用的情况,数据更新于 2013年04月: 数据库大小 2827 MB Home 目录占用空间大小 116 GB 平均内存消耗 1.9 GB 选择实例的数据库表格 数据(Dat ...

  6. 一次完整的http事务的过程

    1.域名解析 2.发起TCP三次握手 3.建立TCP连接以后发起http请求 4.服务器端响应请求,浏览器得到html代码 5.浏览器解析html代码并请求html中的资源 6.浏览器对页面进行渲染呈 ...

  7. python安装scrapy

    Scrapy基于事件驱动网络框架 Twisted 编写,Twisted是一个异步非阻塞框架. 安装 scrapy 要先安装 Twisted,不然无法安装成功,链接: Python Extension ...

  8. JavaScript下实现交换数组元素上下移动例子

    // 交换数组元素    var swapItems = function(arr, index1, index2) {        arr[index1] = arr.splice(index2, ...

  9. equals方法使用技巧

    Object类中的equals方法用于检测一个对象是否等于另外一个对象.在Object类中,这个方法将判断两个对象是否具有相同的引用. 如果两个对象那个具有相同的引用,他们一定是相同的,从这方面看,将 ...

  10. ubuntu 16.04 安装brackets

    1 github 上下载deb包 2 双击deb包但是安装不了(无任何提示,是因为缺少lib文件) 网上给出的解决方案 使用debtool 接压 deb包 把缺少的lib复制进去 配置文件中去掉该 l ...