Spring MVC + JSON = 406 Not Acceptable

在開發接口時發現了一個很好玩的問題,兩個接口均是restful形式,參數在URL路徑中傳遞,返回結果形式均爲json,可是在接口測試時,一個接口正常,另外一個接口報錯:The resource identified by this request is only capable of generating responses with characteristics not acceptable according to the request "accept" headers.本文來分析一下其中的緣由。 php

  先介紹一下出錯的接口狀況,接口代碼以下: html

/**
 * 驗證email是否可用
 * @param email
 * @return
 */
@ResponseBody
@RequestMapping(value = "/emailCheck/{email}", method = RequestMethod.GET)
@ApiOperation(value = "驗證email是否可用", httpMethod = "GET", response = ApiResult.class, notes = "驗證email是否可用")
public ApiResult checkEmailValid(@ApiParam(required = true, name = "email", value = "待校驗的電子郵箱") @PathVariable String email) throws Exception{
    UcUserContact userContact = ucUserContactmanager.getByEmail(email);
    ApiResult<String> result = new ApiResult<String>();
    if (userContact != null){
        result.setData("0");//用戶名不可用
    }else{
        result.setData("1");//用戶名可用
    }
    result.setCode(ResultCode.SUCCESS.getCode());
    return result;
}

  經過Swagger生成的接口描述以下圖所示:
java

  在上圖的表單中將email的值設置爲456213@qq.com,發起對接口的測試請求,界面返回結果以下圖:
web

  服務端控制檯異常代碼以下: spring

org.springframework.web.HttpMediaTypeNotAcceptableException: Could not find acceptable representation

  細心的讀者可能會發現,在本文第二張圖中Curl中的header設置爲'Accept: text/html',這和本文提出的問題有沒有關聯呢?下面咱們再作一次實驗,將email的值設置爲456213,再次發送測試請求,界面返回結果以下圖:
json

  小夥伴們如今內心有疑問了吧?爲何header中的Accpet值會不同?爲何此次能過正常響應呢?讓咱們回想一下響應碼406的意思——Not Acceptable,即請求數據類型與返回數據類型不匹配。我本來請求返回html數據,你服務端卻給我返回json數據,我固然Not Acceptable啦!
  咱們已經很清楚的知道,restful接口返回結果均使用@ResponseBody註解轉爲json格式,若是客戶端請求json數據,接口確定能正常響應;若是客戶端請求其餘形式數據,咱們的接口也只能響應json數據,這樣子就出現本文討論的問題了。
  進一步討論,爲何修改參數以後,header中Accept的值不同了呢?讓咱們好好審視一下Request URL吧! api

http://localhost:8083/arrow-api/users/emailCheck/456213%40qq.com

  這個URL是以.com結尾,其形式爲使用.com頂級域名的網址,因此客戶端默認在這種請求的頭部設置'Accept: text/html',由於這種形式的地址通常都是對網頁的請求。不信,你能夠試試把該url的後綴.com去掉,再次測試請求。我猜,必定能夠正常響應。 restful

  那碰到這種狀況怎麼辦呢?其實,很簡單!只要不使用restful的形式綁定參數便可。我是這麼修改的: app

/**
 * 驗證email是否可用
 * @param email
 * @return
 */
@ResponseBody
@RequestMapping(value = "/emailCheck", method = RequestMethod.GET)
@ApiOperation(value = "驗證email是否可用", httpMethod = "GET", response = ApiResult.class, notes = "驗證email是否可用")
public ApiResult checkEmailValid(@ApiParam(required = true, name = "email", value = "待校驗的電子郵箱") @RequestParam String email) throws Exception{
    UcUserContact userContact = ucUserContactmanager.getByEmail(email);
    ApiResult<String> result = new ApiResult<String>();
    if (userContact != null){
        result.setData("0");//用戶名不可用
    }else{
        result.setData("1");//用戶名可用
    }
    result.setCode(ResultCode.SUCCESS.getCode());
    return result;
}

  讓咱們來看下測試結果吧!
ide

  注意看上圖中的Curl和Request URL哦!你應該明白了!

文章做者: xiaohui249
本文連接: http://javatech.wang/index.php/archives/77/ 版本全部 ©轉載時必須以連接形式註明做者和原始出處
相關文章
相關標籤/搜索