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);
          }
        });

参考资料

Spring in action 4

 

posted @ 2016-12-02 16:34  风一样的码农  阅读(5081)  评论(0编辑  收藏  举报