奇怪的 httpPost 行为(可能与 json、auth、代理相关)GET 有效,POST 有效,但没有代理就不行(部分解决)

发布于 2024-10-16 17:59:39 字数 8018 浏览 2 评论 0原文

我编写了一个 REST WCF RIA Silverlight 4.0 兼容服务,我可以从 javascript + jQuery.1.4.2.js + JSON2.js (当然,从 .NET 4.0 应用程序)成功访问它

基本上,我正在做的事情在我的 Android 活动中是:

            HttpPost request = new HttpPost(SERVICE_URI + "/SubmitChanges");             
        request.setHeader("Accept", "application/json; charset=utf-8");             
        request.setHeader("Content-type", "application/json; charset=utf-8");
        // Build JSON string            
        JSONStringer myTable = new JSONStringer()
        .object()
        .key("changeSet")
        .array()
            .object()
            .key("Id").value(0)
            .key("Entity")
                .object()
                    .key("__type").value("MyTable:#MyServiceApp.Web")
                    .key("ID").value(21)
                .endObject()
            .key("Operation").value(4)
            .endObject()
        .endArray()
        .endObject();
        Log.d("WebInvoke", "MyTable : " + myTable.toString());                           
        StringEntity entity = new StringEntity(myTable.toString());

//          entity.setContentType("application/json; charset=utf-8"); 
//          entity.setContentEncoding(new BasicHeader(HTTP.CONTENT_TYPE,"application/json; charset=utf-8")); 
            request.setEntity(entity);
            Log.d("WebInvoke", "Entity : " + entity.toString());                           
            // Send request to WCF service             
            DefaultHttpClient httpClient = new DefaultHttpClient();
            httpClient.getCredentialsProvider().setCredentials(new AuthScope(null,-1), new UsernamePasswordCredentials("myuser","mypassword"));
//          HttpClientParams myParam = (HttpClientParams) httpClient.getParams();
//          Log.d("WebInvoke", "Entity : " + myParam.toString());                           

            HttpResponse response = httpClient.execute(request);              

当转向 Android 应用程序时,我注意到我无法执行 PUT 操作(GET 工作正常)。他们返回错误 400 - 错误请求 由于它在 js 上运行正常,我使用 fiddler2 来看看发生了什么。当我设置模拟器通过 fiddler 代理工作时,请求突然变得正常。然后我在没有代理的情况下再次尝试,它返回错误 400。我还尝试将 apk 上传到我的 Galaxy S 并通过网络连接。同样,GET 有效,但 PUT 无效...

有什么想法吗?

致敬,奥斯卡。

UPDATE

这是在没有代理的情况下执行请求之前

request HttpPost  (id=830085521536) 
    aborted false
    abortLock   ReentrantLock  (id=830085616656)
    connRequest null
    entity  StringEntity  (id=830085531688)
    headergroup HeaderGroup  (id=830085644864)
    params  null
    releaseTrigger  null
    uri URI  (id=830085878840)
httpClient  DefaultHttpClient  (id=830085612544)    
    connManager null
    cookieStore BasicCookieStore  (id=830085604904)
    credsProvider   BasicCredentialsProvider  (id=830085612624)
    defaultParams   null
    httpProcessor   null
    keepAliveStrategy   null
    log Jdk14Logger  (id=830085596488)
    proxyAuthHandler    null
    redirectHandler null
    requestExec null
    retryHandler    null
    reuseStrategy   null
    routePlanner    null
    supportedAuthSchemes    null
    supportedCookieSpecs    null
    targetAuthHandler   null
    userTokenHandler    null

这是在没有代理的情况下执行请求之后

request HttpPost  (id=830085521536) 
    aborted false
    abortLock   ReentrantLock  (id=830085616656)
    connRequest null
    entity  StringEntity  (id=830085531688)
    headergroup HeaderGroup  (id=830085644864)
    params  BasicHttpParams  (id=830085486480)
    releaseTrigger  SingleClientConnManager$ConnAdapter  (id=830085855888)
    uri URI  (id=830085878840)
httpClient  DefaultHttpClient  (id=830085612544)    
    connManager SingleClientConnManager  (id=830085927648)
    cookieStore BasicCookieStore  (id=830085604904)
    credsProvider   BasicCredentialsProvider  (id=830085612624)
    defaultParams   BasicHttpParams  (id=830085575968)
    httpProcessor   BasicHttpProcessor  (id=830085617496)
    keepAliveStrategy   DefaultConnectionKeepAliveStrategy  (id=830085544576)
    log Jdk14Logger  (id=830085596488)
    proxyAuthHandler    DefaultProxyAuthenticationHandler  (id=830085951384)
    redirectHandler DefaultRedirectHandler  (id=830085524448)
    requestExec HttpRequestExecutor  (id=830085525992)
    retryHandler    DefaultHttpRequestRetryHandler  (id=830085583064)
    reuseStrategy   DefaultConnectionReuseStrategy  (id=830085882544)
    routePlanner    DefaultHttpRoutePlanner  (id=830085880096)
    supportedAuthSchemes    AuthSchemeRegistry  (id=830085650400)
    supportedCookieSpecs    CookieSpecRegistry  (id=830085516320)
    targetAuthHandler   DefaultTargetAuthenticationHandler  (id=830085583264)
    userTokenHandler    DefaultUserTokenHandler  (id=830085486432)
response    BasicHttpResponse  (id=830085980112)    
    entity  BasicManagedEntity  (id=830085983552)
    headergroup HeaderGroup  (id=830085625184)
    locale  Locale  (id=830085944016)
    params  ClientParamsStack  (id=830085486448)
    reasonCatalog   EnglishReasonPhraseCatalog  (id=830004383520)
    statusline  BasicStatusLine  (id=830085625160)

这是在使用代理执行请求之前

request HttpPost  (id=830085966120) 
    aborted false   
    abortLock   ReentrantLock  (id=830085966520)    
    connRequest null    
    entity  StringEntity  (id=830085971592) 
    headergroup HeaderGroup  (id=830085966392)  
    params  null    
    releaseTrigger  null    
    uri URI  (id=830085966568)  
httpClient  DefaultHttpClient  (id=830085973896)    
    connManager null    
    cookieStore BasicCookieStore  (id=830085974504) 
    credsProvider   BasicCredentialsProvider  (id=830085974144) 
    defaultParams   null    
    httpProcessor   null    
    keepAliveStrategy   null    
    log Jdk14Logger  (id=830085974120)  
    proxyAuthHandler    null    
    redirectHandler null    
    requestExec null    
    retryHandler    null    
    reuseStrategy   null    
    routePlanner    null    
    supportedAuthSchemes    null    
    supportedCookieSpecs    null    
    targetAuthHandler   null    
    userTokenHandler    null    

这是在使用代理执行请求之后

request HttpPost  (id=830085966120) 
    aborted false   
    abortLock   ReentrantLock  (id=830085966520)    
    connRequest null    
    entity  StringEntity  (id=830085971592) 
    headergroup HeaderGroup  (id=830085966392)  
    params  BasicHttpParams  (id=830085980824)  
    releaseTrigger  SingleClientConnManager$ConnAdapter  (id=830085981992)  
    uri URI  (id=830085966568)  
httpClient  DefaultHttpClient  (id=830085973896)    
    connManager SingleClientConnManager  (id=830085978144)  
    cookieStore BasicCookieStore  (id=830085974504) 
    credsProvider   BasicCredentialsProvider  (id=830085974144) 
    defaultParams   BasicHttpParams  (id=830085977232)  
    httpProcessor   BasicHttpProcessor  (id=830085978848)   
    keepAliveStrategy   DefaultConnectionKeepAliveStrategy  (id=830085978816)   
    log Jdk14Logger  (id=830085974120)  
    proxyAuthHandler    DefaultProxyAuthenticationHandler  (id=830085980560)    
    redirectHandler DefaultRedirectHandler  (id=830085980152)   
    requestExec HttpRequestExecutor  (id=830085976912)  
    retryHandler    DefaultHttpRequestRetryHandler  (id=830085980128)   
    reuseStrategy   DefaultConnectionReuseStrategy  (id=830085978800)   
    routePlanner    DefaultHttpRoutePlanner  (id=830085978832)  
    supportedAuthSchemes    AuthSchemeRegistry  (id=830085975792)   
    supportedCookieSpecs    CookieSpecRegistry  (id=830085976320)   
    targetAuthHandler   DefaultTargetAuthenticationHandler  (id=830085980344)   
    userTokenHandler    DefaultUserTokenHandler  (id=830085980776)  
response    BasicHttpResponse  (id=830085927240)    
    entity  BasicManagedEntity  (id=830085863688)   
    headergroup HeaderGroup  (id=830085944256)  
    locale  Locale  (id=830085944272)   
    params  ClientParamsStack  (id=830085980792)    
    reasonCatalog   EnglishReasonPhraseCatalog  (id=830004383520)   
    statusline  BasicStatusLine  (id=830085927216)  

I write a REST WCF RIA Silverlight 4.0 compatible service, that I can access sucessfully from a javascript + jQuery.1.4.2.js + JSON2.js (and, of course, from .NET 4.0 applications)

Basically, what I'm doing in my Android activity is:

            HttpPost request = new HttpPost(SERVICE_URI + "/SubmitChanges");             
        request.setHeader("Accept", "application/json; charset=utf-8");             
        request.setHeader("Content-type", "application/json; charset=utf-8");
        // Build JSON string            
        JSONStringer myTable = new JSONStringer()
        .object()
        .key("changeSet")
        .array()
            .object()
            .key("Id").value(0)
            .key("Entity")
                .object()
                    .key("__type").value("MyTable:#MyServiceApp.Web")
                    .key("ID").value(21)
                .endObject()
            .key("Operation").value(4)
            .endObject()
        .endArray()
        .endObject();
        Log.d("WebInvoke", "MyTable : " + myTable.toString());                           
        StringEntity entity = new StringEntity(myTable.toString());

//          entity.setContentType("application/json; charset=utf-8"); 
//          entity.setContentEncoding(new BasicHeader(HTTP.CONTENT_TYPE,"application/json; charset=utf-8")); 
            request.setEntity(entity);
            Log.d("WebInvoke", "Entity : " + entity.toString());                           
            // Send request to WCF service             
            DefaultHttpClient httpClient = new DefaultHttpClient();
            httpClient.getCredentialsProvider().setCredentials(new AuthScope(null,-1), new UsernamePasswordCredentials("myuser","mypassword"));
//          HttpClientParams myParam = (HttpClientParams) httpClient.getParams();
//          Log.d("WebInvoke", "Entity : " + myParam.toString());                           

            HttpResponse response = httpClient.execute(request);              

When turned to Android app, I noted that I cannot do PUT's operations (GETs worked OK). They returned error 400 - Bad request
As it worked OK on js, I used fiddler2 to see what's happend. When I setup the emulator to work throught fiddler proxy, suddenly, the request has turned OK. Then I tryed again without proxy, and it returned to error 400. I tryed also uploading the apk to my Galaxy S and connecting through web. Again, GETs works, but PUTs don't...

Any ideas?

Saludos, OSCAR.

UPDATE

This is previous to execute request without proxy

request HttpPost  (id=830085521536) 
    aborted false
    abortLock   ReentrantLock  (id=830085616656)
    connRequest null
    entity  StringEntity  (id=830085531688)
    headergroup HeaderGroup  (id=830085644864)
    params  null
    releaseTrigger  null
    uri URI  (id=830085878840)
httpClient  DefaultHttpClient  (id=830085612544)    
    connManager null
    cookieStore BasicCookieStore  (id=830085604904)
    credsProvider   BasicCredentialsProvider  (id=830085612624)
    defaultParams   null
    httpProcessor   null
    keepAliveStrategy   null
    log Jdk14Logger  (id=830085596488)
    proxyAuthHandler    null
    redirectHandler null
    requestExec null
    retryHandler    null
    reuseStrategy   null
    routePlanner    null
    supportedAuthSchemes    null
    supportedCookieSpecs    null
    targetAuthHandler   null
    userTokenHandler    null

This is posterior to execute request without proxy

request HttpPost  (id=830085521536) 
    aborted false
    abortLock   ReentrantLock  (id=830085616656)
    connRequest null
    entity  StringEntity  (id=830085531688)
    headergroup HeaderGroup  (id=830085644864)
    params  BasicHttpParams  (id=830085486480)
    releaseTrigger  SingleClientConnManager$ConnAdapter  (id=830085855888)
    uri URI  (id=830085878840)
httpClient  DefaultHttpClient  (id=830085612544)    
    connManager SingleClientConnManager  (id=830085927648)
    cookieStore BasicCookieStore  (id=830085604904)
    credsProvider   BasicCredentialsProvider  (id=830085612624)
    defaultParams   BasicHttpParams  (id=830085575968)
    httpProcessor   BasicHttpProcessor  (id=830085617496)
    keepAliveStrategy   DefaultConnectionKeepAliveStrategy  (id=830085544576)
    log Jdk14Logger  (id=830085596488)
    proxyAuthHandler    DefaultProxyAuthenticationHandler  (id=830085951384)
    redirectHandler DefaultRedirectHandler  (id=830085524448)
    requestExec HttpRequestExecutor  (id=830085525992)
    retryHandler    DefaultHttpRequestRetryHandler  (id=830085583064)
    reuseStrategy   DefaultConnectionReuseStrategy  (id=830085882544)
    routePlanner    DefaultHttpRoutePlanner  (id=830085880096)
    supportedAuthSchemes    AuthSchemeRegistry  (id=830085650400)
    supportedCookieSpecs    CookieSpecRegistry  (id=830085516320)
    targetAuthHandler   DefaultTargetAuthenticationHandler  (id=830085583264)
    userTokenHandler    DefaultUserTokenHandler  (id=830085486432)
response    BasicHttpResponse  (id=830085980112)    
    entity  BasicManagedEntity  (id=830085983552)
    headergroup HeaderGroup  (id=830085625184)
    locale  Locale  (id=830085944016)
    params  ClientParamsStack  (id=830085486448)
    reasonCatalog   EnglishReasonPhraseCatalog  (id=830004383520)
    statusline  BasicStatusLine  (id=830085625160)

This is previous to execute request with proxy

request HttpPost  (id=830085966120) 
    aborted false   
    abortLock   ReentrantLock  (id=830085966520)    
    connRequest null    
    entity  StringEntity  (id=830085971592) 
    headergroup HeaderGroup  (id=830085966392)  
    params  null    
    releaseTrigger  null    
    uri URI  (id=830085966568)  
httpClient  DefaultHttpClient  (id=830085973896)    
    connManager null    
    cookieStore BasicCookieStore  (id=830085974504) 
    credsProvider   BasicCredentialsProvider  (id=830085974144) 
    defaultParams   null    
    httpProcessor   null    
    keepAliveStrategy   null    
    log Jdk14Logger  (id=830085974120)  
    proxyAuthHandler    null    
    redirectHandler null    
    requestExec null    
    retryHandler    null    
    reuseStrategy   null    
    routePlanner    null    
    supportedAuthSchemes    null    
    supportedCookieSpecs    null    
    targetAuthHandler   null    
    userTokenHandler    null    

This is posterior to execute request with proxy

request HttpPost  (id=830085966120) 
    aborted false   
    abortLock   ReentrantLock  (id=830085966520)    
    connRequest null    
    entity  StringEntity  (id=830085971592) 
    headergroup HeaderGroup  (id=830085966392)  
    params  BasicHttpParams  (id=830085980824)  
    releaseTrigger  SingleClientConnManager$ConnAdapter  (id=830085981992)  
    uri URI  (id=830085966568)  
httpClient  DefaultHttpClient  (id=830085973896)    
    connManager SingleClientConnManager  (id=830085978144)  
    cookieStore BasicCookieStore  (id=830085974504) 
    credsProvider   BasicCredentialsProvider  (id=830085974144) 
    defaultParams   BasicHttpParams  (id=830085977232)  
    httpProcessor   BasicHttpProcessor  (id=830085978848)   
    keepAliveStrategy   DefaultConnectionKeepAliveStrategy  (id=830085978816)   
    log Jdk14Logger  (id=830085974120)  
    proxyAuthHandler    DefaultProxyAuthenticationHandler  (id=830085980560)    
    redirectHandler DefaultRedirectHandler  (id=830085980152)   
    requestExec HttpRequestExecutor  (id=830085976912)  
    retryHandler    DefaultHttpRequestRetryHandler  (id=830085980128)   
    reuseStrategy   DefaultConnectionReuseStrategy  (id=830085978800)   
    routePlanner    DefaultHttpRoutePlanner  (id=830085978832)  
    supportedAuthSchemes    AuthSchemeRegistry  (id=830085975792)   
    supportedCookieSpecs    CookieSpecRegistry  (id=830085976320)   
    targetAuthHandler   DefaultTargetAuthenticationHandler  (id=830085980344)   
    userTokenHandler    DefaultUserTokenHandler  (id=830085980776)  
response    BasicHttpResponse  (id=830085927240)    
    entity  BasicManagedEntity  (id=830085863688)   
    headergroup HeaderGroup  (id=830085944256)  
    locale  Locale  (id=830085944272)   
    params  ClientParamsStack  (id=830085980792)    
    reasonCatalog   EnglishReasonPhraseCatalog  (id=830004383520)   
    statusline  BasicStatusLine  (id=830085927216)  

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

枕头说它不想醒 2024-10-23 17:59:39

由于与协议相关的问题,我开始在服务器中测试多种认证方案。似乎自 2008 年以来,java 和 apache 都不支持在新服务器中实现的新 NTLMv2。

我发现(并丢失了)一个网站,其中指出使用 JCIFS 来拉近差距。但事情并不是包含jar那么简单,还必须写一部分代码,而所有的支持都是不确定的,不能保证的。用实际行话来说,这意味着“仅使用基本身份验证”,但用大写字母......

顺便说一句,我找到了它的工作方式。它只是添加了这一点:

httpClient.getParams().setBooleanParameter(CoreProtocolPNames.USE_EXPECT_CONTINUE, false);

戴夫,我欠你一大笔钱!
非常感谢每一位阅读该主题的人!

致敬,奥斯卡。

Being a problem related to the protocol, I begin to test the diverses athentication schemes in the server. It seems that since 2008, java, nor apache, supports the new NTLMv2 implemented in the new servers.

I found (and lost) a web where is noted to use JCIFS to bring the gap. But the things are not so simple to include the jar, you must also write part of the code, and the support of all that is uncertain and not waranteed. This means, in practical lingo, 'use only basic authentication' but in capital letters...

BTW, I found the way it works. Its simply adding this:

httpClient.getParams().setBooleanParameter(CoreProtocolPNames.USE_EXPECT_CONTINUE, false);

Dave, I owe you one big!
Many thanks to every one for read the thread!

Saludos, OSCAR.

遇见了你 2024-10-23 17:59:39

您是否尝试过在 StringEntity 上显式设置 charset

import org.apache.http.protocol.HTTP;
...
StringEntity entity = new StringEntity(myTable.toString(),HTTP.UTF_8);

Have you tried explicitly setting the charset on the StringEntity?

import org.apache.http.protocol.HTTP;
...
StringEntity entity = new StringEntity(myTable.toString(),HTTP.UTF_8);
人疚 2024-10-23 17:59:39

对于任何引用这个问题的人(大约在提出问题一年后),我也遇到了类似的问题,代码几乎相同。问题似乎出在 setCredentials() 方法上。显然,它包含一些空格,这些空格对于 GET 来说没问题,但对于 PUT 或 POST 来说却会出现问题。

手动设置授权应该可以解决问题。例如:

request.setHeader("Authorization","Basic "+Base64.encodeToString("login:password".getBytes(),Base64.URL_SAFE|Base64.NO_WRAP););

记住使用Base64.URL_SAFE | Base64.NO_WRAP

参考:android 上带授权的 HTTP POST 请求

For anyone referencing this question (about a year after it was asked), I had a similar problem with almost identical code. The problem seems to be with the setCredentials() method. Apparently, it includes some whitespaces that are fine with GET but cause a problem with PUT or POST.

Setting the authorization manually should solve the problem. Something like:

request.setHeader("Authorization","Basic "+Base64.encodeToString("login:password".getBytes(),Base64.URL_SAFE|Base64.NO_WRAP););

Remember to use Base64.URL_SAFE | Base64.NO_WRAP.

Reference: HTTP POST request with authorization on android

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文