为啥 RestKit 会更改我的响应内容类型?

Posted

技术标签:

【中文标题】为啥 RestKit 会更改我的响应内容类型?【英文标题】:why is RestKit changing my response content-type?为什么 RestKit 会更改我的响应内容类型? 【发布时间】:2013-10-26 07:07:15 【问题描述】:

简而言之:我尝试从服务器获取数据,并将 http 请求标头的 content-type 设置为 @"text/html.. 但由于某种原因,RestKit 将其更改为 application/JSON

解释: 如果我只使用AFNetworking.. 发出这个请求,事情就像一个魅力.. 这就是我的 AFNetworking 代码的样子:

AFHTTPClient *client = [AFHTTPClient alloc] initWithBaseURL:
                                               [NSURL URLWithString:kApiBaseUrl]];
singleton.parameterEncoding = AFJSONParameterEncoding;
[singleton setDefaultHeader:@"Accept" value:@"text/html"];
[client getPath:getPath parameters:nil success:successCallback failure:failureCallback];

如果我使用那个完全相同的客户端并将其附加到

MyClient *client = [MyClient getSingleton];  //MyClient is instantiated as above        
self.objectManager = [[RKObjectManager alloc] initWithHTTPClient:client];
self.objectManager.managedObjectStore = self.managedObjectStore;
// this should have already been done by my client, but putting
// it here just to be sure
[self.objectManager setAcceptHeaderWithMIMEType:@"text/html"];

[[RKObjectManager sharedManager] getObjectsAtPath:kGradesPath 
                                       parameters:nil 
                                          success:^(RKObjectRequestOperation *operation, RKMappingResult *mappingResult) 
 // handle success
 failure:^(RKObjectRequestOperation *operation, NSError *error) 
 // handle failure
];

我得到的错误是:

 restkit.network:RKObjectRequestOperation.m:576 Object request failed: 
 Underlying HTTP request operation failed with error: Error
 Domain=org.restkit.RestKit.ErrorDomain Code=-1016 "Expected content type (
    "application/x-www-form-urlencoded",
    "application/json"
), got text/html" UserInfo=0x8f7acd0

深入研究主题.. 我在managedObjectRequestOperationWithRequest 中设置了一个断点,然后我检查了HTTPRequestOperation 创建的acceptableContentTypes,结果为零!所以我假设 RestKit 只是把它自己的默认可接受的内容类型.. 我只是不知道在哪里以及如何防止它。想法?

p.s.我无法控制服务器,因此无法将其 content-type 标头更改为 application/JSON


更新:

事实证明,在RKObjectRequestOperation.m 中,它从[RKMIMETypeSerialization registeredMIMETypes];(第354 行)中获取了mime-type.. 所以在RKMIMETypeSerialization.h 中有方法:

/**
 Registers the given serialization class to handle content for the given MIME Type identifier.

 MIME Types may be given as either a string or as a regular expression that matches the MIME Types for which the given serialization should handle. Serializations are searched in the reverse order of their registration. If a registration is made for an already registered MIME Type, the new registration will take precedence.

 @param serializationClass The class conforming to the RKSerialization protocol to be registered as handling the given MIME Type.
 @param MIMETypeStringOrRegularExpression A string or regular expression specifying the MIME Type(s) that given serialization implementation is to be registered as handling.
 */
+ (void)registerClass:(Class<RKSerialization>)serializationClass forMIMEType:(id)MIMETypeStringOrRegularExpression;

如何使用它来注册 text/html 内容类型?

【问题讨论】:

【参考方案1】:

RestKit 通常期望其响应数据使用单个 MIMEType (JSON)。但是,您可以使用您找到的方法告诉它处理其他类型,例如text/plaintext/html,根据我的经验,它非常方便。将此添加到我的 RestKit 配置(我在我的应用程序委托中执行)允许我接受 application/jsontext/html 作为响应数据内容类型。

[RKMIMETypeSerialization registerClass:[RKNSJSONSerialization class] forMIMEType:@"text/html"];

在我的情况下,这也很有帮助,因为 Jersey(我公司后端团队使用的 Web 服务框架)将空有效负载的内容类型默认为 text/plain,这会触发故障块,除非我专门注册了那个 MIMEType。

希望这会有所帮助。

【讨论】:

上面可以有side effects吗? 在我的情况下没有帮助,我有新错误:“加载了内容类型为 'text/html' 的无法处理的响应 (200)” @VasyaVasyaa 我以前见过,它通常与正确设置我的响应描述符和成功代码有关。【参考方案2】:

我使用 change const value 来输入像这样从服务器 api 接收的内容

NSString * const RKMIMETypeJSON = @"text/html";

如果接收到的文本结构与 JSON 相同,则此方法非常有效

【讨论】:

以上是关于为啥 RestKit 会更改我的响应内容类型?的主要内容,如果未能解决你的问题,请参考以下文章

RestKit 0.20 - 预期的内容类型(空)

使用 RestKit 处理原始数据的响应

为啥 ring 的资源响应以 application/octet-stream 内容类型响应?

“找不到给定内容的任何映射,keyPath=null”RestKit 0.2

为啥 String::sub!() 会更改 Ruby 中克隆对象的原始内容?

Restkit如何将任意json(键可能会超时更改)映射到NSDictionary