从 Android 向 .net Restful WebService 发送参数

Posted

技术标签:

【中文标题】从 Android 向 .net Restful WebService 发送参数【英文标题】:Sending Parameters to .net Restful WebService from Android 【发布时间】:2013-05-02 20:50:08 【问题描述】:

我正在尝试发送一个调用一个将锯齿状数组作为参数的 Web 服务方法。我构建了数组,但它总是将 null 传递给 Web 服务。

这是我的 java 类:

package com.mitch.wcfwebserviceexample;

import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicHeader;
import org.apache.http.protocol.HTTP;
import org.json.JSONArray;
import org.json.JSONObject;

import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;
import android.app.Activity;

public class MainActivity extends Activity implements OnClickListener 
    private String values ="";
  Button btn;
  TextView tv;

    @Override
    protected void onCreate(Bundle savedInstanceState) 
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        btn = (Button)this.findViewById(R.id.btnAccess);
        tv = (TextView)this.findViewById(R.id.tvAccess);
        btn.setOnClickListener(this);
    

    @Override
    public void onClick(View arg0) 
        try
        
        AsyncTaskExample task = new AsyncTaskExample(this);
        task.execute("");
        String  test = values;
        tv.setText(values);
         catch(Exception e)
        
           Log.e("Click Exception ", e.getMessage());   
        

    

    public class AsyncTaskExample extends AsyncTask<String, Void,String>
    
        private String Result="";
        //private final static String SERVICE_URI = "http://10.0.2.2:1736";
        private final static String SERVICE_URI = "http://10.0.2.2:65031/SampleService.svc";
        private MainActivity host;
        public AsyncTaskExample(MainActivity host)
        
            this.host = host;
        

        public String GetSEssion(String URL)
        
          boolean isValid = true;
          if(isValid)
          

                    String[][] val = 
                        new String[] "Student.ID","123456",
                        new String[] "Student.username","user1",
                        new String[] "Student.password","123456",
                        new String[] "Student.location.id","12"
                    ;
                    HttpPost requestAuth = new HttpPost(URL +"/Login");
                    try
                  
                    JSONObject json = new JSONObject();
                //  json.put("sessionId", sessionId);
                    JSONArray params = new JSONArray();
                    params.put(val);
                    json.put("authenParams", params);

                    StringEntity se = new StringEntity(json.toString());
                    se.setContentType(new BasicHeader(HTTP.CONTENT_TYPE, "application/json"));
                    requestAuth.setHeader("Accept","application/json");
                    requestAuth.setEntity(se);
                    DefaultHttpClient httpClientAuth = new DefaultHttpClient();
                    HttpResponse responseAuth = httpClientAuth.execute(requestAuth);
                    HttpEntity responseEntityAuth = responseAuth.getEntity();
                    char[] bufferAuth = new char[(int)responseEntityAuth.getContentLength()];
                    InputStream streamAuth = responseEntityAuth.getContent();
                    InputStreamReader readerAuth = new InputStreamReader(streamAuth);
                    readerAuth.read(bufferAuth);
                    streamAuth.close();
                    String rawAuthResult = new String(bufferAuth);
                    Result = rawAuthResult;
                    String d = null;
        //      
             catch (ClientProtocolException e) 
                Log.e("Client Protocol", e.getMessage());
             catch (IOException e) 
                Log.e("Client Protocol", e.getMessage() );
             catch(Exception e)
            
                Log.e("Client Protocol", e.getMessage() );
            
          
          return Result;
        

        @Override
        protected String doInBackground(String... arg0) 
            android.os.Debug.waitForDebugger();
            String t = GetSEssion(SERVICE_URI);
            return t;
        

        @Override
        protected void onPostExecute(String result) 
        //  host.values = Result;
            super.onPostExecute(result);
        
        @Override
        protected void onPreExecute() 
            // TODO Auto-generated method stub
            super.onPreExecute();
        

        @Override
        protected void onCancelled() 
            // TODO Auto-generated method stub
            super.onCancelled();
        
    

下面是我应该接收参数的方法: 我在下面的代码中放了一个断点并检查它。该参数始终为空。

public string Login(string[][] value)
        
            string[] tester = null;
            string testerExample="";
            foreach (string[] st in value)
            
                tester = st;
            

            foreach (string dt in tester)
            
                testerExample = dt;
            

            return testerExample;
        

这是 IStudentService 中的方法声明:

[OperationContract]
        [WebInvoke(
            Method="POST", UriTemplate="Login", BodyStyle= WebMessageBodyStyle.WrappedRequest, ResponseFormat = WebMessageFormat.Json, RequestFormat = WebMessageFormat.Json)]
        string Login(string[][] value);

我按照您的建议尝试了,但没有成功。它返回“请求错误” 这是我粘贴的示例代码。

HttpClient client = new DefaultHttpClient();  
           HttpPost post = new HttpPost("http://10.0.2.2:65031/SampleService.svc/login");   
 List<NameValuePair> pairs = new ArrayList<NameValuePair>();  
pairs.add(new BasicNameValuePair("tester","abcd"));  
pairs.add(new BasicNameValuePair("sampletest","1234"));  
UrlEncodedFormEntity entity = new UrlEncodedFormEntity(pairs,HTTP.UTF_8);  
post.setEntity(entity);  
HttpResponse response = client.execute(post); 
HttpEntity responseEntity = response.getEntity();               
char[] buffer = new char[(int)responseEntity.getContentLength()];        
InputStream stream = responseEntity.getContent();        
InputStreamReader reader = new InputStreamReader(stream);        
reader.read(buffer);        stream.close();         
String value = new String(buffer);

【问题讨论】:

你为什么使用StringEntity?使用UrlEncodedFormEntity,更好。 我按照你的建议做了,但对我不起作用。它返回请求错误。 尝试使用 Fiddler 应用程序编写一个 http 请求。虽然我认为不可能调用以string[][] value 作为参数的服务。您应该将其替换为 string Login(string tester, string sampletest) 我试过你的建议字符串 Login(string tester, string sampletest),效果很好。我看到了预期的网络服务。 @vorrtex 你错了!!发送 JSON 你不应该使用UrlEncodedFormEntity 【参考方案1】:

我终于让它按照我想要的方式工作了。问题是我以这种方式构建数组(参见下面的第 1 节)并将其传递给 JSONObject 或 JSONArray。我使用 JSONArray 切换和构建 Array 并将其传递给 JSONObject(参见第 2 节)。它就像一个魅力。

第 1 部分: 错误的方法 - (如果您要查看数组并将它们放入 JSONArray 中,可能会以这种方式工作。如果可以直接完成,那就太麻烦了。)

String[][] Array = 
new String[]"Example", "Test",
new String[]"Example", "Test",
;

JSONArray jar1 = new JSONArray();
jar1.put(0, Array); **// Did not work**

第 2 节: 经过长时间的尝试以及来自@vorrtex 的一些非常有用的提示和提示,我做到了这一点。

JSONArray jar1 = new JSONArray();
jar1.put(0, "ABC");
jar1.put(1, "Son");
jar1.put(2, "Niece");

JSONArray jarr = new JSONArray();
jarr.put(0, jar1);

JSONArray j = new JSONArray();
j.put(0,"session");

JSONObject obj = new JSONObject();          
obj.put("value", jarr);
obj.put("test", j);
obj.put("name","myName");
Log.d("Obj.ToString message: ",obj.toString());
StringEntity entity = new StringEntity(obj.toString());

查看网络服务,它正是我想要的。

感谢您的帮助!!!!

【讨论】:

以上是关于从 Android 向 .net Restful WebService 发送参数的主要内容,如果未能解决你的问题,请参考以下文章

如何从 Java 中的 RESTFul 服务向 Ipstack API 请求 GET

如何从 android 调用 RESTful Web 服务?

OneSignal Android - 功能需要 RESTful API 密钥

在 Android 中使用 Restful WCF 服务

如何从Android调用RESTful Web服务?

将字符串从 android 传递到 wcf restful 服务变得空