Spring Android POST在ResponseEntity中没有返回类型应用程序/八位字节流

Posted

技术标签:

【中文标题】Spring Android POST在ResponseEntity中没有返回类型应用程序/八位字节流【英文标题】:Spring Android POST no return type application/octet-stream in ResponseEntity 【发布时间】:2013-02-07 19:04:54 【问题描述】:

我正在使用运行 Express 3.0 的 Node.js 服务器。

在我的应用程序的一个部分中,我将 json 发布到一个 URI 以在 /api/transactions/powerup 购买电源。这有几个返回选项。

我会收到 201 表示交易有效,或者收到 404 表示请求因资金不足而无效。我的问题是,如果我想仅根据 ResponseEntity 中的标头告诉 android 客户端它是否成功。

没有传回客户端的 json,因为 HTTP 代码可以告诉我它是否成功。有谁知道怎么做?

PowerupPurchase purchase = new PowerupPurchase();
purchase.setPowerId(params[0]);
final String url = getString(R.string.external_api_url) + "/transactions/powers?apiKey="+mCurrentUser.getApiKey();

Log.i(TAG,url);
// create the headers
HttpHeaders requestHeaders = new HttpHeaders();
requestHeaders.setAccept(Collections.singletonList(MediaType.APPLICATION_JSON));
requestHeaders.setAcceptEncoding(ContentCodingType.GZIP);
requestHeaders.setContentType(MediaType.APPLICATION_JSON);

// Create the Json that will be exchanged
HttpEntity<?> requestEntity = new HttpEntity<PowerupPurchase>(purchase, requestHeaders);
// Create a new RestTemplate instance
RestTemplate restTemplate = new RestTemplate();

MappingJacksonHttpMessageConverter converter = new MappingJacksonHttpMessageConverter();
List<MediaType> mediaList = new LinkedList<MediaType>();
mediaList.add(new MediaType("application","octet-stream",Charset.forName("UTF-8")));
converter.setSupportedMediaTypes(mediaList);
restTemplate.getMessageConverters().add(converter);

   try 
        // Make the network request
    ResponseEntity<?> response = restTemplate.postForEntity(url, requestEntity, Object.class);
    // HOW DO I GET THE HEADERS??
        response.getHeaders()

400 似乎总是在 Spring Android 中抛出错误,无论如何我可以简单地查看 http 标头而不必担心返回对象映射到?

【问题讨论】:

【参考方案1】:

RestTemplate 使用的DefaultResponseErrorHandler 为所有 400 和 500 系列 HTTP 状态响应引发异常。一种选择是将自定义 ResponseErrorHandler 与您的 RestTemplate 请求一起使用,该请求不会引发异常。您可以修改您的请求以使用自定义处理程序,然后检查预期的状态代码:

// set the custom error handler
restTemplate.setErrorHandler(new CustomErrorHandler());

// make the request
ResponseEntity<Void> response = restTemplate.postForEntity(url, requestEntity, null);

// check status code
HttpStatus statusCode = response.getStatusCode();
if (statusCode == HttpStatus.CREATED) 
    // handle success
 else if (statusCode == HttpStatus.NOT_FOUND) 
    // handle error

这是一个不会抛出任何异常的“空”实现示例:

class CustomErrorHandler implements ResponseErrorHandler 

    @Override
    public void handleError(ClientHttpResponse response) throws IOException 
    

    @Override
    public boolean hasError(ClientHttpResponse response) throws IOException 
        return false;
    


因为服务器可能会返回其他状态码,所以最好查找预期的状态码,而不是为那些特定的状态码抛出异常。但这完全取决于您的需求。此示例扩展了 RestTemplate 使用的默认处理程序并检查预期的状态代码:

class CustomErrorHandler extends DefaultResponseErrorHandler 

    @Override
    public void handleError(ClientHttpResponse response) throws IOException 
        // check for expected status codes
        if (isExpected(response.getStatusCode())) 
            return;
        
        super.handleError(response);
    

    @Override
    public boolean hasError(ClientHttpResponse response) throws IOException 
        // check for expected status codes
        if (isExpected(response.getStatusCode())) 
            return false;
        
        return super.hasError(response);
    

    private boolean isExpected(HttpStatus statusCode) 
        return (statusCode == HttpStatus.CREATED || statusCode == HttpStatus.NOT_FOUND);
    


【讨论】:

【参考方案2】:

你确定可以使用失败的异常吗?

boolean success;
try
    ResponseEntity<?> response = restTemplate.postForEntity(url, requestEntity, Object.class);
    int result = response.getHeaders().getStatus()...
    success = result >= 200 && result < 300;
catch(Exception e)
    success = false;

【讨论】:

我只是希望有一些更合乎逻辑的东西。抓住逻辑只是伤害了我书呆子的小心脏。

以上是关于Spring Android POST在ResponseEntity中没有返回类型应用程序/八位字节流的主要内容,如果未能解决你的问题,请参考以下文章

使用 Retrofit 从 Android 向服务器发送字符串数组

Spring Android POST在ResponseEntity中没有返回类型应用程序/八位字节流

HttpClient的GET请求(post)请求

在Python Flask中,Axios POST没有被正确解析。

spring基础:@ResponseBody,PrintWriter用法

如何检索由axios post请求发送的php中的变量[重复]