文章出處

什么是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

 


文章列表


不含病毒。www.avast.com
arrow
arrow
    全站熱搜
    創作者介紹
    創作者 大師兄 的頭像
    大師兄

    IT工程師數位筆記本

    大師兄 發表在 痞客邦 留言(0) 人氣()