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/ 版本全部 ©转载时必须以连接形式注明做者和原始出处
相关文章
相关标签/搜索