当RestTemplate从spring获得null响应时会发生什么?

时间:2014-01-27 14:40:36

标签: java spring spring-mvc

我想知道当spring服务器在客户端返回空对象(而不是“空”对象)时发生了什么。它会引发异常吗?或者只是将其标记为null

客户代码:

// Does it throw an exception or will I have obj==null or obj "empty" ?
MyDto obj = restTemplate.getForObject(url, MyDto.class);

服务器代码:

@RequestMapping(value = "/urlpath", method = RequestMethod.GET)
@ResponseBody
public MyDto getObj() {
    return null;
}

我当然简化了代码。我在这里问的原因是,打开我的调试服务器需要很长时间,并使用pom.xml等创建一个简单的基本环境(我是Spring的新手)。

1 个答案:

答案 0 :(得分:5)

当您使用@ResponseBody注释处理程序方法时,Spring使用RequestResponseBodyMethodProcessor生成响应正文。它在handleReturnValue方法中执行此操作,该方法实现为

@Override
public void handleReturnValue(Object returnValue, MethodParameter returnType,
        ModelAndViewContainer mavContainer, NativeWebRequest webRequest)
        throws IOException, HttpMediaTypeNotAcceptableException {

    mavContainer.setRequestHandled(true);
    if (returnValue != null) {
        writeWithMessageConverters(returnValue, returnType, webRequest);
    }
}

因此,如果返回的值为null,则不会将任何内容写入正文。

RestTemplate因此会尝试从空MyDto反序列化StringRestTemplate使用HttpMessageConvertExtractor反序列化响应。 extractData方法实现为

@Override
@SuppressWarnings({ "unchecked", "rawtypes" })
public T extractData(ClientHttpResponse response) throws IOException {
    if (!hasMessageBody(response)) {
        return null;
    }
    MediaType contentType = getContentType(response);

    for (HttpMessageConverter<?> messageConverter : this.messageConverters) {
        if (messageConverter instanceof GenericHttpMessageConverter) {
            GenericHttpMessageConverter<?> genericMessageConverter = (GenericHttpMessageConverter<?>) messageConverter;
            if (genericMessageConverter.canRead(this.responseType, null, contentType)) {
                if (logger.isDebugEnabled()) {
                    logger.debug("Reading [" + this.responseType + "] as \"" +
                            contentType + "\" using [" + messageConverter + "]");
                }
                return (T) genericMessageConverter.read(this.responseType, null, response);
            }
        }
        if (this.responseClass != null) {
            if (messageConverter.canRead(this.responseClass, contentType)) {
                if (logger.isDebugEnabled()) {
                    logger.debug("Reading [" + this.responseClass.getName() + "] as \"" +
                            contentType + "\" using [" + messageConverter + "]");
                }
                return (T) messageConverter.read((Class) this.responseClass, response);
            }
        }
    }
    throw new RestClientException(
            "Could not extract response: no suitable HttpMessageConverter found for response type [" +
                    this.responseType + "] and content type [" + contentType + "]");
}

换句话说,如果没有正文,则返回null

所以你的MyDto对象在这里

MyDto obj = restTemplate.getForObject(url, MyDto.class);

将是null