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);
          }
        });
复制代码
相关文章
|
22天前
|
监控 Java 应用服务中间件
高级java面试---spring.factories文件的解析源码API机制
【11月更文挑战第20天】Spring Boot是一个用于快速构建基于Spring框架的应用程序的开源框架。它通过自动配置、起步依赖和内嵌服务器等特性,极大地简化了Spring应用的开发和部署过程。本文将深入探讨Spring Boot的背景历史、业务场景、功能点以及底层原理,并通过Java代码手写模拟Spring Boot的启动过程,特别是spring.factories文件的解析源码API机制。
56 2
|
2月前
|
Java API 数据库
构建RESTful API已经成为现代Web开发的标准做法之一。Spring Boot框架因其简洁的配置、快速的启动特性及丰富的功能集而备受开发者青睐。
【10月更文挑战第11天】本文介绍如何使用Spring Boot构建在线图书管理系统的RESTful API。通过创建Spring Boot项目,定义`Book`实体类、`BookRepository`接口和`BookService`服务类,最后实现`BookController`控制器来处理HTTP请求,展示了从基础环境搭建到API测试的完整过程。
51 4
|
2月前
|
Java API 数据库
如何使用Spring Boot构建RESTful API,以在线图书管理系统为例
【10月更文挑战第9天】本文介绍了如何使用Spring Boot构建RESTful API,以在线图书管理系统为例,从项目搭建、实体类定义、数据访问层创建、业务逻辑处理到RESTful API的实现,详细展示了每个步骤。通过Spring Boot的简洁配置和强大功能,开发者可以高效地开发出功能完备、易于维护的Web应用。
65 3
|
2月前
|
IDE Java API
基于Spring Boot REST API设计指南
【10月更文挑战第4天】 在现代的软件开发中,RESTful API已经成为了构建网络应用的标准之一。它通过HTTP协议提供了与资源交互的方式,使得不同的应用程序能够进行数据交互。Spring Boot作为一个功能强大的框架,它简化了配置和开发流程,成为了构建RESTful API的理想选择。本文将详细介绍如何在Spring Boot中设计和实现高质量的RESTful API,并提供一些最佳实践。
52 1
|
2月前
|
缓存 Java API
基于Spring Boot REST API设计指南
【10月更文挑战第11天】 在构建现代Web应用程序时,RESTful API已成为一种标准,使得不同的应用程序能够通过HTTP协议进行通信,实现资源的创建、读取、更新和删除等操作。Spring Boot作为一个功能强大的框架,能够轻松创建RESTful API。本文将详细介绍如何在Spring Boot中设计和实现高质量的RESTful API。
130 61
|
1月前
|
缓存 API 网络架构
掌握现代API开发:GraphQL vs REST
【10月更文挑战第24天】本文深入探讨了现代API开发中两种主流技术——GraphQL和REST的设计理念、技术特点及实际开发中的对比分析。GraphQL通过声明式数据请求和强类型系统提供更高的灵活性和性能,而REST则以其无状态特性和成熟的生态系统见长。文章还讨论了两者在客户端-服务器交互、安全性和工具支持方面的优劣,帮助开发者根据项目需求做出明智选择。
|
2月前
|
安全 Java API
基于Spring Boot REST API设计指南
【10月更文挑战第10天】 在现代Web应用开发中,RESTful API扮演着至关重要的角色。Spring Boot作为一个高效、便捷的Java开发框架,为构建RESTful API提供了强大的支持。本文将分享基于Spring Boot的REST API设计指南,涵盖从项目初始化到API文档配置的全过程。
53 0
|
2月前
|
Java API Maven
使用 Smart-doc 记录 Spring REST API
使用 Smart-doc 记录 Spring REST API
59 0
|
Java 网络架构 容器
spring rest 容易被忽视的后端服务 chunked 性能问题
spring boot 容易被忽视的后端服务 chunked 性能问题 标签(空格分隔): springboot springmvc chunked 背景 spring boot 创建的默认 spring mvc 项目 集成 JAX-RS 规范框架 Jersey 背景 在之前的一次性能压测的时候我们发现一个细节问题,我们使用 spring boot 创建的 web rest 项目,使用默认 spring mvc 作为 web rest 框架。
1523 0
|
3月前
|
SQL 监控 druid
springboot-druid数据源的配置方式及配置后台监控-自定义和导入stater(推荐-简单方便使用)两种方式配置druid数据源
这篇文章介绍了如何在Spring Boot项目中配置和监控Druid数据源,包括自定义配置和使用Spring Boot Starter两种方法。