2011-05-18 113 views
46

我已经使用Jersey Framework和Java在Netbean IDE中编写了REST Web服务。如何从Android调用RESTful Web服务?

对于用户需要提供用户名和密码的每个请求,我知道此验证不是最佳实践(使用卷曲命令,如:curl -u username:password -X PUT http://localhsot:8080/user)。

现在我想从Android类调用REST Web服务。

我应该怎么做?

我有一个Android类,它使用DefaultHttpClientCredentialUsernameAndPassword,但是当我在Eclipse中运行它时,有时候会出现运行时异常或SDK异常。

+0

你可以发布例外吗? – 2011-05-18 15:28:13

回答

18

这是一个样本RESTClient实现类

public class RestClient 
{ 
    public enum RequestMethod 
    { 
     GET, 
     POST 
    } 
    public int responseCode=0; 
    public String message; 
    public String response; 
    public void Execute(RequestMethod method,String url,ArrayList<NameValuePair> headers,ArrayList<NameValuePair> params) throws Exception 
    { 
     switch (method) 
     { 
      case GET: 
      { 
       // add parameters 
       String combinedParams = ""; 
       if (params!=null) 
       { 
        combinedParams += "?"; 
        for (NameValuePair p : params) 
        { 
         String paramString = p.getName() + "=" + URLEncoder.encode(p.getValue(),"UTF-8"); 
         if (combinedParams.length() > 1) 
          combinedParams += "&" + paramString; 
         else 
          combinedParams += paramString; 
        } 
       } 
       HttpGet request = new HttpGet(url + combinedParams); 
       // add headers 
       if (headers!=null) 
       { 
        headers=addCommonHeaderField(headers); 
        for (NameValuePair h : headers) 
         request.addHeader(h.getName(), h.getValue()); 
       } 
       executeRequest(request, url); 
       break; 
      } 
      case POST: 
      { 
       HttpPost request = new HttpPost(url); 
       // add headers 
       if (headers!=null) 
       { 
        headers=addCommonHeaderField(headers); 
        for (NameValuePair h : headers) 
         request.addHeader(h.getName(), h.getValue()); 
       } 
       if (params!=null) 
        request.setEntity(new UrlEncodedFormEntity(params, HTTP.UTF_8)); 
       executeRequest(request, url); 
       break; 
      } 
     } 
    } 
    private ArrayList<NameValuePair> addCommonHeaderField(ArrayList<NameValuePair> _header) 
    { 
     _header.add(new BasicNameValuePair("Content-Type","application/x-www-form-urlencoded")); 
     return _header; 
    } 
    private void executeRequest(HttpUriRequest request, String url) 
    { 
     HttpClient client = new DefaultHttpClient(); 
     HttpResponse httpResponse; 
     try 
     { 
      httpResponse = client.execute(request); 
      responseCode = httpResponse.getStatusLine().getStatusCode(); 
      message = httpResponse.getStatusLine().getReasonPhrase(); 
      HttpEntity entity = httpResponse.getEntity(); 

      if (entity != null) 
      { 
       InputStream instream = entity.getContent(); 
       response = convertStreamToString(instream); 
       instream.close(); 
      } 
     } 
     catch (Exception e) 
     { } 
    } 

    private static String convertStreamToString(InputStream is) 
    { 
     BufferedReader reader = new BufferedReader(new InputStreamReader(is)); 
     StringBuilder sb = new StringBuilder(); 
     String line = null; 
     try 
     { 
      while ((line = reader.readLine()) != null) 
      { 
       sb.append(line + "\n"); 
      } 
      is.close(); 
     } 
     catch (IOException e) 
     { } 
     return sb.toString(); 
    } 
} 
+2

在没有评论的情况下添加一个类的源代码,或总结发生在哪一点上的人对新手到RESTful服务(例如我自己)感到困惑。 – 2017-02-09 02:53:05

6

停止,不管你在干什么! :)

实施RESTful客户端作为服务并将密集网络的东西委托给与活动无关的组件:SERVICE。

关注此见地的视频 http://www.youtube.com/watch?v=xHXn3Kg2IQE其中维吉尔Dobjanschi在解释他的做法(ES)这一挑战......

13

最近发现,第三方库 - Square Retrofit可以做的工作非常出色。


定义REST端点

public interface GitHubService { 
    @GET("https://stackoverflow.com/users/{user}/repos") 
    List<Repo> listRepos(@Path("user") String user,Callback<List<User>> cb); 
} 

获取具体的服务

RestAdapter restAdapter = new RestAdapter.Builder() 
    .setEndpoint("https://api.github.com") 
    .build(); 
GitHubService service = restAdapter.create(GitHubService.class); 

调用REST端点

List<Repo> repos = service.listRepos("octocat",new Callback<List<User>>() { 
    @Override 
    public void failure(final RetrofitError error) { 
     android.util.Log.i("example", "Error, body: " + error.getBody().toString()); 
    } 
    @Override 
    public void success(List<User> users, Response response) { 
     // Do something with the List of Users object returned 
     // you may populate your adapter here 
    } 
}); 

该库为您处理json序列化和deserailization。您也可以自定义序列化和反序列化。

Gson gson = new GsonBuilder() 
    .setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES) 
    .registerTypeAdapter(Date.class, new DateTypeAdapter()) 
    .create(); 

RestAdapter restAdapter = new RestAdapter.Builder() 
    .setEndpoint("https://api.github.com") 
    .setConverter(new GsonConverter(gson)) 
    .build(); 
+0

有没有关于这个的真实例子?我不太了解细节。 – Gatunox 2015-03-15 02:15:27

+0

Retrofit为您生成Restful Web服务客户端。你只需要用一些注释来定义接口。有关详细信息,请参阅http://square.github.io/retrofit/ – Tianhai 2015-03-15 09:57:05

+0

我已经看过它。但o仍然没有得到它。 Trats为什么即时通讯寻找一个真实的例子。没有几件代码 – Gatunox 2015-03-15 13:47:24

0

什么后端?如果是JAVA,那么您可以使用REST和Java(JAX-RS)使用Jersey。

在Android端,您可以使用这个简单的RestClient来使用该REST服务。

对于JSON < - >双方对象映射(Android,Java后端)可以使用GSON。

0

也许是迟到了,也许你已经使用过它,但有另一个名为ksoap,它的相当惊人..它还包括超时,并可以有效地解析任何基于SOAP的Web服务。我也做了一些更改,以适应我的解析..查看它

0

按照以下步骤使用Android中的RestFul。

第一步

创建一个Android的空白项目。

第二步

需要互联网接入许可。在AndroidManifest.xml文件中写下面的代码。

<uses-permission android:name="android.permission.INTERNET"> 
</uses-permission> 

第三步:

需要它在其他的服务器或同一台机器上运行REST风格的URL。

第四步:

做一个RESTful客户端这将延伸的AsyncTask。请参阅RestFulPost.java。

第五步:

制作DTO类问题的REST请求和响应。

RestFulPost.java

package javaant.com.consuming_restful.restclient; 
import android.app.ProgressDialog; 
import android.content.Context; 
import android.os.AsyncTask; 
import android.util.Log; 
import com.google.gson.Gson; 
import org.apache.http.HttpResponse; 
import org.apache.http.client.methods.HttpPost; 
import org.apache.http.entity.StringEntity; 
import org.apache.http.impl.client.DefaultHttpClient; 
import org.apache.http.util.EntityUtils; 
import java.util.Map; 
import javaant.com.consuming_restful.util.Util; 
/** 
* Created by Nirmal Dhara on 29-10-2015. 
*/ 
public class RestFulPost extends AsyncTask<map, void,="" string=""> { 
    RestFulResult restFulResult = null; 
    ProgressDialog Asycdialog; 
    String msg; 
    String task; 
    public RestFulPost(RestFulResult restFulResult, Context context, String msg,String task) { 
     this.restFulResult = restFulResult; 
     this.task=task; 
     this.msg = msg; 
     Asycdialog = new ProgressDialog(context); 
    } 
    @Override 
    protected String doInBackground(Map... params) { 
     String responseStr = null; 
     Object dataMap = null; 
     HttpPost httpost = new HttpPost(params[0].get("url").toString()); 

     try { 
      dataMap = (Object) params[0].get("data"); 
      Gson gson = new Gson(); 
      Log.d("data map", "data map------" + gson.toJson(dataMap)); 
      httpost.setEntity(new StringEntity(gson.toJson(dataMap))); 
      httpost.setHeader("Accept", "application/json"); 
      httpost.setHeader("Content-type", "application/json"); 
      DefaultHttpClient httpclient= Util.getClient(); 
      HttpResponse response = httpclient.execute(httpost); 
      int statusCode = response.getStatusLine().getStatusCode(); 
      Log.d("resonse code", "----------------" + statusCode); 

      if (statusCode == 200) 
       responseStr = EntityUtils.toString(response.getEntity()); 
      if (statusCode == 404) { 
       responseStr = "{\n" + 
         "\"status\":\"fail\",\n" + 
         " \"data\":{\n" + 
         "\"ValidUser\":\"Service not available\",\n" + 
         "\"code\":\"404\"\n" + 
         "}\n" + 
         "}"; 
      } 

     } catch (Exception e) { 
      e.printStackTrace(); 
     } 
     return responseStr; 
    } 
    @Override 
    protected void onPreExecute() { 
     Asycdialog.setMessage(msg); 
     //show dialog 
     Asycdialog.show(); 
     super.onPreExecute(); 
    } 
    @Override 
    protected void onPostExecute(String s) { 
     Asycdialog.dismiss(); 
     restFulResult.onResfulResponse(s,task); 
    } 
} 

有关详细信息和完整的代码,请访问http://javaant.com/consume-a-restful-webservice-in-android/#.VwzbipN96Hs

1

我以前OkHttpClient调用RESTful Web服务。这很简单。

OkHttpClient httpClient = new OkHttpClient(); 
Request request = new Request.Builder() 
       .url(url) 
       .build(); 

Response response = httpClient.newCall(request).execute(); 
String body = response.body().string() 
+2

这不是Android的_built-in_组件。 – Czechnology 2016-10-09 20:49:35

1

使用Spring为Android与RestTemplate https://spring.io/guides/gs/consuming-rest-android/

// The connection URL 
String url = "https://ajax.googleapis.com/ajax/" + 
    "services/search/web?v=1.0&q={query}"; 

// Create a new RestTemplate instance 
RestTemplate restTemplate = new RestTemplate(); 

// Add the String message converter 
restTemplate.getMessageConverters().add(new StringHttpMessageConverter()); 

// Make the HTTP GET request, marshaling the response to a String 
String result = restTemplate.getForObject(url, String.class, "Android"); 
+1

那些倒票的人应该解释这个答案有什么问题。 – jk7 2017-03-14 16:58:39

0

这里是我的库,我已经为简单的web服务呼叫建立,

您可以通过添加一行gradle这个依赖使用 -

compile 'com.scantity.ScHttpLibrary:ScHttpLibrary:1.0.0' 

她e是使用的示范。

https://github.com/vishalchhodwani1992/httpLibrary