简体   繁体   English

改造-获取空错误响应正文(MalformedJsonException)

[英]Retrofit - getting null error response body (MalformedJsonException)

I'm trying to get error response body in onFailure(RetrofitError error) , but getting null . 我正在尝试在onFailure(RetrofitError error)获取错误响应主体,但获取null

I am using the header Accept: text/plain for requests and from response I receive Content-Type: text/plain and can see body as text if I set LogLevel.FULL . 我正在使用标头Accept: text/plain进行请求,并从响应中收到Content-Type: text/plain并且如果设置LogLevel.FULL可以将正文视为文本。 Moreover, error.getResponse().getStatus() gives me correct status code. 此外, error.getResponse().getStatus()为我提供了正确的状态代码。

But when I perform error.getBody() or error.getResponse.getBody() it returns null . 但是当我执行error.getBody()error.getResponse.getBody()它返回null Inside error I see that successType is java.lang.String , so I assume it should give me String , but error.getCause() shows me 内部error我看到successTypejava.lang.String ,所以我认为它应该给我String ,但是error.getCause()显示给我

com.google.gson.JsonSyntaxException: com.google.gson.stream.MalformedJsonException: Use JsonReader.setLenient(true) to accept malformed JSON at line 1 column 6 path $ com.google.gson.JsonSyntaxException:com.google.gson.stream.MalformedJsonException:使用JsonReader.setLenient(true)在第1行第6列的路径处接受格式错误的JSON $

Also, error.getKind() is CONVERSION , which stands for 另外, error.getKind()CONVERSION ,它表示

/** An exception was thrown while (de)serializing a body. / **在反序列化正文时引发了异常。 */ * /

but I expect to get kind as HTTP 但我希望能像HTTP

Question is why does it tries to convert into JSON when all headers are using text/plain and successType is String ? 问题是为什么当所有标头都使用text/plainsuccessTypeString时,为什么尝试转换为JSON? I need to get my response as plain text. 我需要以纯文本形式获得答复。

Code snippet: 程式码片段:

RestAdapter restAdapter = new RestAdapter.Builder()
        .setEndpoint(url)
        .setLogLevel(RestAdapter.LogLevel.FULL)
        .setClient(new CustomOkHttpClient())
        .setRequestInterceptor(new TransactionsRequestInterceptor())
        .build();

TransactionsRestClient httpClient = restAdapter.create(TransactionsRestClient.class);
httpClient.createNewTransaction(request, new retrofit.Callback<String>() {
    @Override
    public void success(String transactionId, Response response) {

    }

    @Override
    public void failure(RetrofitError error) {
        // error.getBody() is null
    }
}
public interface TransactionsRestClient {
    @POST("/transactions")
    void createNewTransaction(@Body TransactionRequest request, Callback<String> transactionId);
}

public class TransactionsRequestInterceptor implements RequestInterceptor {
    @Override
    public void intercept(RequestFacade request) {
        request.addHeader(HOST, host);
        request.addHeader(TOKEN, token);
        request.addHeader(ACCEPT, TEXT);
        request.addHeader(CONTENT_TYPE, JSON);
    }

Logged requests/responses: 记录的请求/响应:

 ---> HTTP POST $url
Host: $host
Accept: text/plain
Content-Type: application/json
Content-Length: 133
$request_body
---> END HTTP (133-byte body)

<--- HTTP 202 $url //202 is expected
Access-Control-Allow-Origin:
Content-Type: text/plain
Date: Wed, 20 May 2015 16:08:46 GMT
Server: spray-can/1.3.1
Content-Length: 50
Connection: keep-alive
OkHttp-Selected-Protocol: http/1.1
OkHttp-Sent-Millis: 1432138139875
OkHttp-Received-Millis: 1432138140004
The record for test10 is not currently authorized. // this is body I have to get
<--- END HTTP (50-byte body)

Thanks. 谢谢。

By default Retrofit reads the response as a JSON and parses it automatically. 默认情况下,Retrofit将响应作为JSON读取并自动解析。 You have to change it's default behavior. 您必须更改其默认行为。

This blog post might be helpful, and suggests you to get your String response as: 这篇博客文章可能会有所帮助,建议您以以下方式获得String响应:

new String(((TypedByteArray) response.getBody()).getBytes());

In your code new RestAdapter.Builder() you do not specify a Converter ( setConverter() ). new RestAdapter.Builder()的代码new RestAdapter.Builder()您没有指定Converter( setConverter() )。

Looking at Retrofit code, more specifically at RestAdapter and Platform I checked that if you do not specify a Converter it will use GSON as default: 查看Retrofit代码,更具体地说,在RestAdapterPlatform上,我检查了是否未指定Converter它将默认使用GSON:

@Override Converter defaultConverter() {
  return new GsonConverter(new Gson());
}

I believe the solution is to create a Custom Converter (extending Converter class) and do nothing with your response, just returning the raw String. 我相信解决方案是创建一个自定义转换器(扩展Converter类),并且对您的响应不执行任何操作,仅返回原始String。

Here 's an example on how to create your own Converter. 是有关如何创建自己的Converter的示例。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM