Spring 4 创建REST API

简介:

什么是REST

  • 全称:表述性状态转移 (Representational State Transfer), 将资源的状态以最适合客户端或服务端的形式从服务器端转移到客户端(或者反过来)。
  • 面向资源,而不是面向行为
  • 资源通过URL进行识别和定位,
  • 一般URL中都使用名词,不使用动词
  • 对资源采取的行为使用HTTP方法来定义,如GET, POST, DELETE, PUT

Spring MVC REST API示例

以用户增删改查为例,设计 REST API.

这里,我们主要关注Spring Mvc中的Controller的设计:

UserController类:

复制代码
@RestController
@RequestMapping(value = "/users")
public class UserController extends BaseController
{
@Autowired
    private IUserService userService; ... }
复制代码

这里使用了@RestController注解,Spring将会为该Controller的所有处理方法应用消息转换功能,因此我们可以不必为每个方法都添加@ResponseBody。

Spring支持多种资源表述形式(JSON/XML/HTML...),不过一般使用JSON形式。

查询所有用户

对应请求的URL示例(无分页):http://localhost:8080/webbf/users

对应的URL示例(有分页):http://localhost:8080/webbf/users?offset=0&limit=10

使用的HTTP方法:GET

如果查询不到用户,返回状态码204,No Content

否则,返回状态码200, OK,返回的数据类型为 application/json;charset=utf-8

复制代码
    @RequestMapping(method = RequestMethod.GET, produces = "application/json; charset=utf-8")
    public ResponseEntity<List<User>> getUserList(
        @RequestParam(value = "offset", defaultValue = "0") long offset,
        @RequestParam(value = "limit", defaultValue = MAX_LONG_AS_STRING) long limit)
    {
        Map<String, Object> param = new HashMap<String, Object>();
        param.put("offset", offset);
        param.put("limit", limit);
        List<User> userList = userService.query(param);
        if (userList.size() == 0)
        {
            return new ResponseEntity<List<User>>(HttpStatus.NO_CONTENT);
        }
        return new ResponseEntity<List<User>>(userList, HttpStatus.OK);
    }
复制代码

查询单个用户

对应请求的URL示例:http://localhost:8080/webbf/users/1

使用的HTTP方法:GET

如果查询不到用户,返回状态码404,Not Found

否则,返回状态码200, OK,返回的数据类型为 application/json;charset=utf-8

复制代码
    @RequestMapping(value = "/{id}", method = RequestMethod.GET, produces = "application/json; charset=utf-8")
    public ResponseEntity<User> getUserById(@PathVariable Long id)
    {

        User user = userService.findById(id);
        if (user == null)
        {
            return new ResponseEntity<User>(HttpStatus.NOT_FOUND);
        }
        return new ResponseEntity<User>(userService.findById(id), HttpStatus.OK);
    }
复制代码

删除用户

对应请求的URL示例:http://localhost:8080/webbf/users/1

使用的HTTP方法:DELETE

如果查询不到被删除的用户,返回状态码404,Not Found

否则,删除成功,返回状态码204, No Content

复制代码
    @RequestMapping(value = "/{id}", method = RequestMethod.DELETE, produces = "application/json; charset=utf-8")
    public ResponseEntity<User> deleteUser(@PathVariable Long id)
    {
        User user = userService.findById(id);
        if (user == null)
        {
            return new ResponseEntity<User>(HttpStatus.NOT_FOUND);
        }
        userService.deleteUser(id);
        return new ResponseEntity<User>(HttpStatus.NO_CONTENT);
    }
复制代码

保存用户

对应请求的URL示例:http://localhost:8080/webbf/users

请求体:

{
    "name":"1",
    "address":"aa"
}

Content-Type: application/json

使用的HTTP方法:POST

响应的body为新创建的用户;

响应头的Locationhttp://localhost:8080/webbf/users/60

//如果用户已存在,返回状态码,409, Conflict

保存成功,返回状态码201, Created,返回的数据类型为 application/json;charset=utf-8

复制代码
    @RequestMapping(method = RequestMethod.POST, consumes = "application/json; charset=utf-8")
    public ResponseEntity<User> saveUser(@RequestBody User user, UriComponentsBuilder ucb)
    {

        // if (userService.isUserExist(user)) {
        // System.out.println("A User with name " + user.getName() +
        // " already exist");
        // return new ResponseEntity<User>(user, HttpStatus.CONFLICT);
        // }
        User saved = userService.saveUser(user);

        HttpHeaders headers = new HttpHeaders();
        URI locationUri = ucb.path("/users/").path(String.valueOf(saved.getId())).build().toUri();
        headers.setLocation(locationUri);

        ResponseEntity<User> responseEntity = new ResponseEntity<User>(saved, headers,
            HttpStatus.CREATED);
        return responseEntity;
    }
复制代码

修改用户

对应请求的URL示例:http://localhost:8080/webbf/users/1

请求体:

{
    "name":"1",
    "address":"aa"
}

Content-Type: application/json

使用的HTTP方法:PUT

响应的body为新创建的用户;

如果查询不到被修改的用户,返回状态码404,Not Found

保存成功,返回状态码201, Created,返回的数据类型为 application/json;charset=utf-8

复制代码
    @RequestMapping(value = "/{id}", method = RequestMethod.PUT, consumes = "application/json; charset=utf-8")
    public ResponseEntity<User> updateUser(@PathVariable("id") long id, @RequestBody User user)
    {
        User currentUser = userService.findById(id);

        if (currentUser == null)
        {
            return new ResponseEntity<User>(HttpStatus.NOT_FOUND);
        }

        currentUser.setId(id);
        currentUser.setName(user.getName());
        currentUser.setAddress(user.getAddress());

        userService.updateUser(currentUser);
        return new ResponseEntity<User>(currentUser, HttpStatus.OK);
    }
复制代码

 异常处理

请求中发生异常,返回500 Internal Server Error。

复制代码
    @ExceptionHandler(Exception.class)
    @ResponseBody
    public ResponseEntity<Exception> handleException(HttpServletRequest request, Exception e)
    {
        logger.error("Request FAILD, URL = {} method = {}", request.getRequestURI(), request.getMethod());
        logger.error(e.toString(), e);
        return new ResponseEntity<Exception>(e, HttpStatus.INTERNAL_SERVER_ERROR);
    }
复制代码

前端测试工具

因为我喜欢用fireFox, 所以我用restclient测试工具测试 REST API:

chrom的话,可以使用Postman。

修改用户测试

 

 新增用户测试

查询单个用户

前端AJAX调用 REST API 示例

查询用户

复制代码
      $.ajax({
         async: false,
          type : "get",
          url : "/webbf/users",
          data: {},
          datatype : 'json',
          
          success : function(data,textStatus) {
            this.trigger({userList:data});
          }.bind(this),
          
          error: function(jqXHR, textStatus, errorThrown) {
            alert(jqXHR.status + ' ' + jqXHR.responseText);
          }

        });
复制代码

删除用户

复制代码
      $.ajax({
         async: false,
          type : "delete",
          url : "/webbf/users/" + userId,
          data: {},
          datatype : 'json',
          success : function(data) {

              alert("删除成功");
              this.getAllUser();
 
          }.bind(this),
          
          error: function(jqXHR, textStatus, errorThrown) {
            alert(jqXHR.status + ' ' + jqXHR.responseText);
          }
        });
复制代码

新增用户

复制代码
      $.ajax({
         async: false,
         contentType: "application/json; charset=utf-8",
          type : "post",
          url : "/webbf/users",
          data: JSON.stringify({name:userName,address:address}),
          datatype : 'json',
          success : function(data) {

              alert("操作成功");
              this.openAddModal(false);
              this.getAllUser();
  
          }.bind(this),
          
          error: function(jqXHR, textStatus, errorThrown) {
            alert(jqXHR.status + ' ' + jqXHR.responseText);
          }
        });
复制代码


相关文章
|
15天前
|
前端开发 JavaScript API
基于React的简易REST API客户端设计与实现
基于React的简易REST API客户端设计与实现
17 3
|
24天前
|
SpringCloudAlibaba Java 网络架构
【Springcloud Alibaba微服务分布式架构 | Spring Cloud】之学习笔记(二)Rest微服务工程搭建
【Springcloud Alibaba微服务分布式架构 | Spring Cloud】之学习笔记(二)Rest微服务工程搭建
43 0
|
30天前
|
Java API Maven
使用Java和Spring Boot构建RESTful API
使用Java和Spring Boot构建RESTful API
15 0
|
3月前
|
JSON 缓存 API
title: 深入理解REST API设计的最佳实践
title: 深入理解REST API设计的最佳实践
35 0
|
3月前
|
JSON Java API
Spring Boot 无侵入式 实现API接口统一JSON格式返回
Spring Boot 无侵入式 实现API接口统一JSON格式返回
|
4月前
|
分布式计算 Hadoop Java
[hadoop3.x系列]HDFS REST HTTP API的使用(二)HttpFS
[hadoop3.x系列]HDFS REST HTTP API的使用(二)HttpFS
52 1
|
4月前
|
分布式计算 Hadoop API
✨[hadoop3.x系列]HDFS REST HTTP API的使用(一)WebHDFS
✨[hadoop3.x系列]HDFS REST HTTP API的使用(一)WebHDFS
57 1
|
4月前
|
缓存 Java 关系型数据库
Spring Boot实现RESTful接口架构实战(包括REST的讲解、定义、REST服务测试)
Spring Boot实现RESTful接口架构实战(包括REST的讲解、定义、REST服务测试)
48 0
|
4月前
|
JSON 前端开发 生物认证
REST API 的指纹验证机制
REST API 的指纹验证机制
29 0
|
4月前
|
存储 Java API
[读书笔记]Spring中对JSR310日期时间API的支持
[读书笔记]Spring中对JSR310日期时间API的支持
43 1