IOS上的Android帖子请求

时间:2013-05-27 08:00:59

标签: android objective-c tomcat post

我正在尝试将Android应用移植到IOS平台。我从位于Apache Tomcat服务器中的服务获取数据,最近他们在服务上添加了安全性。安全概述是

  1. https简单请求
  2. if(valid_user) - >服务返回数据
  3. else->服务返回登录表单 - >发布凭据 - >服务返回数据
  4. Android版本没有问题。在添加安全性之前,我正在执行简单的http请求,但现在我需要使用我的凭据执行POST请求,因此我总是收到error.html。我远不是网络编程方面的专家。

    这是Android http客户端设置代码:

    if(httpClient==null)
    {
     DefaultHttpClient client = new DefaultHttpClient();
    
     KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
     trustStore.load(null, null);
     SSLSocketFactory sf = new MySSLSocketFactory(trustStore);
     sf.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
     SchemeRegistry registry = new SchemeRegistry();
     registry.register(new Scheme("https", sf, 8443));
    
     mgr = new ThreadSafeClientConnManager(client.getParams(), registry);
     int timeoutConnection = 5000;
     HttpConnectionParams.setConnectionTimeout(client.getParams(), timeoutConnection);
     // Set the default socket timeout (SO_TIMEOUT) 
     // in milliseconds which is the timeout for waiting for data.
     int timeoutSocket = 7000;
     HttpConnectionParams.setSoTimeout(client.getParams(), timeoutSocket);
     httpClient = new DefaultHttpClient(mgr, client.getParams());
    }
    

    这是MySSLSocketFactory类:

    public class MySSLSocketFactory extends SSLSocketFactory {
        SSLContext sslContext = SSLContext.getInstance("TLS");
    
        public MySSLSocketFactory(KeyStore truststore) throws NoSuchAlgorithmException, KeyManagementException, KeyStoreException, UnrecoverableKeyException {
            super(truststore);
    
            TrustManager tm = new X509TrustManager() {
                public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
                }
    
                public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
                }
    
                public X509Certificate[] getAcceptedIssuers() {
                    return null;
                }
            };
    
            sslContext.init(null, new TrustManager[] { tm }, null);
        }
    
        @Override
        public Socket createSocket(Socket socket, String host, int port, boolean autoClose) throws IOException, UnknownHostException {
            return sslContext.getSocketFactory().createSocket(socket, host, port, autoClose);
        }
    
        @Override
        public Socket createSocket() throws IOException {
            return sslContext.getSocketFactory().createSocket();
        }
    }
    

    这是Android的POST请求代码(工作正常):

    ...
    HttpPost httpost = new HttpPost(host+"/serviceName/j_security_check"); 
    List<BasicNameValuePair> nvps = new ArrayList<BasicNameValuePair>();
    nvps.add(new BasicNameValuePair("j_username", userName));
    nvps.add(new BasicNameValuePair("j_password", userPassword));
    
    try {
         httpost.setEntity(new UrlEncodedFormEntity(nvps, HTTP.UTF_8));
        } 
    catch (UnsupportedEncodingException e) {
        // TODO Auto-generated catch block
                    e.printStackTrace();
    }
    
    try {
         httpResponse = httpClient.execute(httpost);
    } catch (ClientProtocolException e) {
          // TODO Auto-generated catch block
          e.printStackTrace();
    } catch (IOException e) {
          // TODO Auto-generated catch block
          e.printStackTrace();
    }
    entity = httpResponse.getEntity();
    ...
    

    我尝试了几种方法但总是有相同的结果。我只添加了我认为非常出色的代码:

    -(void)connection:(NSURLConnection *)connection willSendRequestForAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge
    {
      NSURLCredential *credential=[NSURLCredential credentialWithUser:self.userName password:self.userpassword persistence:NSURLCredentialPersistenceForSession];
       [[challenge sender] useCredential:credential forAuthenticationChallenge:challenge];
    }
    

    在定义POST请求的方法中:

    {
    ...
    NSString *urlstr=[NSString stringWithFormat:@"%@%@",host,@"serviceName/j_security_check"];
    NSURL *url=[[NSURL alloc]initWithString:urlstr];
    NSMutableURLRequest *request=[NSMutableURLRequest requestWithURL:url];
    NSString *params=[[NSString alloc]initWithFormat:@"j_username=my_userName&j_userpassword=my_userPassword"];
    [request setHTTPMethod:@"POST"];
    [request setHTTPBody:[params dataUsingEncoding:NSUTF8StringEncoding]];
    [[NSURLConnection alloc]initWithRequest:request delegate:self];
    }
    

    我一直在网上搜索有效的POST请求,但没有一个是有用的......

    如果您需要更多信息,请索取

    你的帮助是吝啬的。

    编辑:我更改了willSendRequestForAuthenticationChallenge委托,因为使用前一个我没有获得login.html表单。

    编辑:我从android添加了http客户端设置代码。现在发布数据的方法看起来类似于@MTahir的答案,但我仍然得到了error.html,这意味着(我认为)POST方法工作正常,但数据没有以正确的方式编写。

1 个答案:

答案 0 :(得分:3)

如果您正在寻找一个可以发布数据的代码,那么试试这个,我使用它,效果很好。

它将数据发送到字典对象中。生成将要作为POST发送的数据然后返回响应(如果您希望结果以字符串格式,您可以使用[[NSString alloc] initWithData:dresponse encoding:NSASCIIStringEncoding];返回数据时)

-(NSData*) postData:(NSDictionary *) postDataDic{

NSData *dresponse = [[NSData alloc] init];

NSURL *nurl = [NSURL URLWithString:url];
NSDictionary *postDict = [[NSDictionary alloc] initWithDictionary:postDataDic];
NSData *postData = [self encodeDictionary:postDict];

// Create the request
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:nurl];
[request setHTTPMethod:@"POST"]; // define the method type
[request setValue:[NSString stringWithFormat:@"%d", postData.length] forHTTPHeaderField:@"Content-Length"];
[request setValue:@"application/x-www-form-urlencoded charset=utf-8" forHTTPHeaderField:@"Content-Type"];
[request setHTTPBody:postData];

    // Peform the request
    NSURLResponse *response;
    NSError *error = nil;

    dresponse = [NSURLConnection sendSynchronousRequest:request  
                                                 returningResponse:&response
                                                             error:&error];

return dresponse;
}

此方法为POST

准备字典数据
  - (NSData*)encodeDictionary:(NSDictionary*)dictionary {
    NSMutableArray *parts = [[NSMutableArray alloc] init];
    for (NSString *key in dictionary) {
        NSString *encodedValue = [[dictionary objectForKey:key] stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
        NSString *encodedKey = [key stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]; 
        NSString *part = [NSString stringWithFormat: @"%@=%@", encodedKey, encodedValue];
        [parts addObject:part];
    }
    NSString *encodedDictionary = [parts componentsJoinedByString:@"&"];
    return [encodedDictionary dataUsingEncoding:NSUTF8StringEncoding];
}

如果您有任何疑惑,请告诉我。