I'm new to Retrofit. How can I send param and get Json from bellow url ?
http://xxx:8087/courier.svc/login?username=jim&password=123456
I need to a link for tutorial .
This code is in my MainActivity :
private void loadJSON(String username, String password) {
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("http://192.168.8.11:8087/sample.svc/")
.addConverterFactory(GsonConverterFactory.create())
.build();
RequestInterface_Login request = retrofit.create(RequestInterface_Login.class);
Call<JSONResponseLogin> call = request.getJSON(username, password);
call.enqueue(new Callback<JSONResponseLogin>() {
#Override
public void onResponse(Call<JSONResponseLogin> call, Response<JSONResponseLogin> response) {
JSONResponseLogin jsonResponse = response.body();
data = new ArrayList<>(Arrays.asList(jsonResponse.getLogin()));
}
#Override
public void onFailure(Call<JSONResponseLogin> call, Throwable t) {
Log.d("Error", t.getMessage());
}
});
}
My ModelLogin :
public class ModelLogin {
private String username;
private String password;
public String getUsername() {
return username;
}
public String getPassword() {
return password;
}
}
My RequestInterface_Login :
public interface RequestInterface_Login {
#GET("/login/{username}/{password}")
Call<JSONResponseLogin> getJSON(#Path("username") String username, #Path("password") String password);
}
My JSONResponseLogin :
public class JSONResponseLogin {
private ModelLogin[] login;
public ModelLogin[] getLogin() {
return login;
}
}
But get me NullPointerException!
I get json from service same bellow :
{"Key":null,"Response":1}
Before you get call the retrofit you can just print the URL and then you can load URL in browser and see what response is coming you can add log by bellow line before call.enqueue(new Callback<JSONResponseLogin>()
Log.e(TAG, "API URL: " + call.request().url());
Check your response
And let me know I will help you ... coz i am using retrofit in my 3 projects
Do like this ...in interface
#GET("/courier.svc/login?)
Call<JSONResponseLogin> getJSON(#Query("username") String username,
#Query("password") String password);
and remove it from base .baseUrl("http://192.168.8.11:8087")
I am writing this post on 'Retrofit in android' using our latest Retrofit library, This plugin can be be used to Integrate Retrofit to your project.
Before using reftrofit, we just need to follow some steps to add QAssist Plugins in Android studio which will reduce your efforts of Webservices integration.
1.Add (QAssist - Android Studio Plugin) Android plugin in your Android studio. ( https://github.com/sakkeerhussain/QAssist ).:-
2.When we done with the plugin then we need to restart our Android studio.
3.Check your Android studio Menubar You can find "QAssist".
4.Click on that and Start with Retrofit Integrate.
5.Now we need :
- BaseUrl of Web Api's
- All Api's en points.
- Sample request and Response of All request.
- After completing these steps your reftrofit(QAssist/retrofit package is genrated inside Project).
6.You can find A Class and One Interface inside that Package.
7.The interface contain all the endpoints detail and Class will cotain the Retrofit connection details.
8.We just need to add a small code to access and Api and Parse that Api' response to Data model.
9.Use this sample function to call Api.
private void demoRetroFitCall() {
APIService apiService = RetrofitManager.getInstance(this);
//APIService apiService = RetroFitApiClient.getClient().create(APIService.class);
Call<ModelData> call = apiService.TestGet();
call.enqueue(new Callback<ModelData>() {
#Override
public void onResponse(Call<ModelData> call, Response<ModelData> response) {
Log.d("TAG", "Data recived in response.body");
}
#Override
public void onFailure(Call<ModelData> call, Throwable t) {
Log.e("TAG", t.toString());
}
});
}
56 - voda
Related
I am getting a Null Pointer Exception. I want to retrieve a random quote from this Quotes Api - https://quotes.rest/ to display in my android application. Where am I going wrong?
(I apologise if I had not asked the question properly or violated any rules by posting a question. This is my first time asking a question)
I have created necessary POJOs and tried retrieving the quote in the MainActivity.
GetDataService service = RetrofitClientInstance.getRetrofitInstance().create(GetDataService.class);
Call<Example> call = service.getRandomQuote();
call.enqueue(new Callback<Example>() {
#Override
public void onResponse(Call<Example> call, Response<Example> response) {
String quote = response.body().getContents().getQuotes().get(0).getQuote();
Log.d(TAG, "onResponse: ************" + quote);
}
GetDataService
public interface GetDataService {
#GET("/quote/random")
Call<Example> getRandomQuote();
}
POJO- Quote
public class Quote {
#SerializedName("quote")
private String quote;
public Quote(String quote) {
this.quote = quote;
}
public String getQuote() {
return quote;
}
public void setQuote(String quote) {
this.quote = quote;
}
}
POJO- Contents
public class Contents {
#SerializedName("quotes")
#Expose
private List<Quote> quotes;
public List<Quote> getQuotes() {
return quotes;
}
public void setQuotes(List<Quote> quotes) {
this.quotes = quotes;
}
}
POJO- Example
public class Example {
#SerializedName("contents")
#Expose
private Contents contents;
public Contents getContents() {
return contents;
}
public void setContents(Contents contents) {
this.contents = contents;
}
}
RetrofitClientInstance class
public class RetrofitClientInstance {
private static Retrofit retrofit = null;
private static final String BASE_URL = "https://quotes.rest";
public static Retrofit getRetrofitInstance(){
if(retrofit == null){
retrofit = new Retrofit.Builder()
.baseUrl(BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.build();
}
return retrofit;
}
}
I expect the output to be a random quote from this Quotes Api (https://quotes.rest/) but I am getting a Null Pointer Exception. Following is the error-
java.lang.NullPointerException: Attempt to invoke virtual method 'com.platinumstudio.contactsdemo7.network.Contents com.platinumstudio.contactsdemo7.Example.getContents()' on a null object reference
at com.platinumstudio.contactsdemo7.MainActivity$3.onResponse(MainActivity.java)
The API that you're using here is this. As the API documentation says, an API key is required to fetch data. Since you didn't add an API key in your codes, it's should return an unsuccessful response with the HTTP Status Code of 401.
And it's always the best practice to check if the response is successful before proceeding to execute operations on received data to avoid crash issues in the app. Always keep this code snippet when you're fetching data from an API:
call.enqueue(new Callback<Example>() {
#Override
public void onResponse(Call<Example> call, Response<Example> response) {
if(response.isSuccessful && response.body() != null){
//Get contents & quote
}
else {
//Check response code & show the relevant error message through Toast or Dialog
}
}
#Override
public void onFailure(Call call, Throwable t) {
//Show a failed message to the user
}
}
I believe that you need to add Api key to your request, otherwise you'll not be allowed to access the data. Hence, your response's body is null, which causes the crash. As it says on the website:
For using the private end points and subscribing to the API please visit https://theysaidso.com/api.
https://theysaidso.com/api/
From the API website you will find the link to access the ramdom quote
here is the link:
http://quotes.rest/quote/random.json?api_key=
without the key you will get Unauthorized access
This API requires Authorization key to access the data. Hence, modify your interface GetDataService like below :
public interface GetDataService {
#GET("/quote/random/")
Call<Example> getRandomQuote(#HeaderMap Map<String, String> headerMap);
}
//HeaderMap will have authorization key and its value as <Key,Value> pair.
Hello I am new to Android. I am trying to call and save two API from same class and place both data from those API into same RecyclerView.
The first retrofit is working but in the second retrofit call there is problem.
The code is as below for second retrofit
private void callRetrofitListData(){
pariyojanaInterfaces = ApiClient.getApiClient().create(PariyojanaInterface.class);
Log.e("pariyojanaInterfaces", String.valueOf(pariyojanaInterfaces));
Call<List<Data>> call = pariyojanaInterfaces.getData(memberId);
Log.e("urll",call.request().toString())
call.enqueue(new Callback<List<Data>>() {
#Override
public void onResponse(Call<List<Data>> call, Response<List<Data>> response) {
Log.e("check","chekc");
datas = (List<Data>) response.body();
itemListAdapter = new ItemListAdapter(getApplicationContext(), datas);
rv.setLayoutManager(new LinearLayoutManager(getApplicationContext()));
rv.setAdapter(itemListAdapter);
}
#Override
public void onFailure(Call<List<Data>> call, Throwable t) {
Log.e("error", t.getMessage());
}
});
}
In this case the debugger is not going inside this function
call.enqueue(new Callback<List<Data>>()
and says No such instance field: 'PariyojanaInterfaces'.
The PariyojanaInterface is shown below:
public interface PariyojanaInterface {
#POST("projectBudget/pariyojanaListForMobile")
Call<List<Data>> getData(#Query("memberId") int memberId);
}
Can somebody please help me solve my problem?
You have to add #FormUrlEncoded in your interface before #POST() line
and
in POST method we use #FIELD instead of #QUERY
I have two APIs -
One to search for a phone number (let's say http://example.com/api/?phone=1234567890) which returns the id of the person associated with that phone number
And another (http://example.com/api/con/id/) to fetch for contact details.
Basically, in the second call, I have to include the id that is returned in the first call.
My question is how do I do this?
I've come till here in my code, but I couldn't find anything beyond this for my situation.
public interface RequestInterface {
#GET("/con/")
Call<JSONResponse> getJSON();
}
Since there is a change in dynamic path so if you are trying to call it from local server you need to create .htaccess file with following rules:
# Turn rewrite engine on
Options +FollowSymlinks
RewriteEngine on
# map neat URL to internal URL
RewriteRule ^api/con/([0-9]+)/?$ RestController.php?phone=single&id=$1 [NC,L,QSA]
RewriteCond %{QUERY_STRING} (?:^|&)number=(\d+)$
RewriteRule ^api/?$ RestController.php?phone=all&no=%1 [NC,L]
This will redirect your server based on the query parameters and URL.
public interface RequestInterface
{
BASE_URL = "http://example.com"
#GET("/api")
Call<YourFetchResponse> getPhoneDetails(#Query("api_key") String apiKey,#Query("phone") String phone);
#GET("/api/con/{id}")
Call<YourIdResponse> getIdDetails(#Query("api_key") String apiKey,#Path("id") String id);
}
MainActivity.java
Call<YourFetchResponse> call = RequestInterface.getPhoneDetails(API_KEY,PHONE);
call.enqueue(new Callback<YourFetchResponse>()
{
#Override
public void onResponse(Call<YourFetchResponse> call, Response<YourFetchResponse> response)
{
Call<YourIdResponse> call1 = RequestInterface.getIdDetails(API_KEY, response.body().getId);
call1.enqueue(new Callback<YourIdResponse>()
{
#Override
public void onResponse(Call<YourIdResponse> call, Response<YourIdResponse> response)
{....}
#Override
public void onFailure(Call<YourFetchResponse> call, Throwable t)
{....}
}
#Override
public void onFailure(Call<YourFetchResponse> call, Throwable t)
{....}
});
You need to use #Path annotation.
public interface RequestInterface {
BASE_URL = "http://example.com/api/";
#GET("con/{id}")
Call<YourFetchResponse> contactFetch(#Path("id") String id);
#GET("")
Call<YourIdResponse> contactId(#Query("phone") String phone);
}
Good luck there.
public interface RequestInterface {
#GET("serviceURL")
Call<JSONResponse> getPhoneDetails(#Query("api_key") String apiKey);
#GET("serviceURL")
Call<JSONResponse> getIdDetails(#Query("api_key") String apiKey);
}
onResponse of First service call second service.
I'm going to develop a small-sized system to raise my developing skills.
It consists of the three parts listed below:
1. Web DB
2. Web Page
3. Android App
The main feature is managing the members. (login, just showing the user information)
At this point, I'm wondering about the android app part.
Especially, the HTTP.
I found two libraries which are JSoup and Retrofit.
As far as I can tell, those libraries are a little bit different.
I think the retrofit is a better fit for me...
Up until now I couldn't find a good sample...
Can you give me a hint how to do this?
If you are trying to connect to a Web Database I would suggest using Volley which is really simple and straightforward and really powerful yet: https://developer.android.com/training/volley/index.html.
Here's an example on how you could set your query with volley from the android developer site:
final TextView mTextView = (TextView) findViewById(R.id.text);
...
// Instantiate the RequestQueue.
RequestQueue queue = Volley.newRequestQueue(this);
String url ="http://www.google.com";
// Request a string response from the provided URL.
StringRequest stringRequest = new StringRequest(Request.Method.GET, url,
new Response.Listener<String>() {
#Override
public void onResponse(String response) {
// Display the first 500 characters of the response string.
mTextView.setText("Response is: "+ response.substring(0,500));
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
mTextView.setText("That didn't work!");
}
});
// Add the request to the RequestQueue.
queue.add(stringRequest);
Retrofit example
Synchronous
Interface
public interface RestApi {
#POST("/Login")
String login(#Body User user);
}
Simple class which follows the singleton design pattern
public class RestClient {
private static RestApi API_INSTANCE;
private static final String ENDPOINT = "http://192.168.6.99:50500/Phone";
static {
setUpHttpClient();
}
private static void setUpHttpClient() {
RestAdapter restAdapter = new RestAdapter.Builder()
.setEndpoint(ENDPOINT)
.setLogLevel(BuildConfig.DEBUG ?
RestAdapter.LogLevel.FULL :
RestAdapter.LogLevel.NONE)
.build();
API_INSTANCE = restAdapter.create(RestApi.class);
}
private RestClient() {}
public static RestApi getApiInstance() {
return API_INSTANCE;
}
}
Call it for example in an IntentService
String userToken = "";
try {
// post to http://192.168.6.99:50500/Phone/Login
userToken = RestClient.getApiInstance().login(new User(login, password));
} catch (RetrofitError error) {
//...
}
build.gradle
compile 'com.squareup.retrofit:retrofit:1.9.0'
Or Asynchronous
interface
public interface RestApi {
#POST("/Login")
void login(#Body User user, Callback<String> token);
}
and do the request with a callback..
I just started using Retrofit to consume APIs. I am able to update a User's profile successfully but I can't pass in the information to a User Object:
Interface RetrofitService:
public interface RetrofitService {
#FormUrlEncoded
#POST("/profile/update")
public void updateUser(
#Field("user_id") String userId,
#Field("user_token") String userToken,
#Field("first_name") String firstName,
#Field("last_name") String lastName,
Callback<JSONObject> callback);
}
Activity ProfileUpdate:
updateProfile.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
//Build RestAdapter
RestAdapter restAdapter = new RestAdapter.Builder()
.setEndpoint("http://xxx.xxx.xxx.xxx/")
.build();
//Create API service
RetrofitService service = restAdapter.create(RetrofitService.class);
//Invoke method
service.updateUser(
user.getUserId(),
user.getUserToken(),
mFirstName.getText().toString(),
mLastName.getText().toString(),
new Callback<JSONObject>() {
#Override
// user remains null!
public void success(JSONObject jsonObject, Response response) {
Toast.makeText(ProfileMe.this, "Profile Updated", Toast.LENGTH_SHORT).show();
Log.d("succes", "Success!");
}
#Override
public void failure(RetrofitError error) {
Log.d("failure", "Failed");
}
});
}
});
The above code works and the user's profile is updated. However the JSONObject in the onSuccess remains null.
I've been using Gson until now and I would do something like this:
//update user with new information
User user = gson.fromJson(responseData,User.class);
How do I do this with Retrofit?
EDIT
Response from the server returns a JSONObject. I changed the code above to satisfy those requirements but I am still returned a null JSONObject
Change to this:
public interface RetrofitService {
#FormUrlEncoded
#POST("/profile/update")
public void updateUser(
#Field("user_id") String userId,
#Field("user_token") String userToken,
#Field("first_name") String firstName,
#Field("last_name") String lastName,
Callback<User> callback);
}
You need to set in the callback what you are expecting to receive in the response. If the WS returns a User object you need to set that in the callback
Make sure that your rest has a Object as return (Json formatter).
You need change your code to this:
public interface RetrofitService {
#FormUrlEncoded
#POST("/profile/update")
public void updateUser(
#Field("user_id") String userId,
#Field("user_token") String userToken,
#Field("first_name") String firstName,
#Field("last_name") String lastName,
Callback<User> callback);
}
Retrofit uses Gson by default to convert HTTP bodies to and from JSON.
If you want to specify behavior that is different from Gson's defaults
(e.g. naming policies, date formats, custom types), provide a new Gson
instance with your desired behavior when building a RestAdapter. Refer
to the Gson documentation for more details on customization.
Edited
If your server returns something like this:
{
"user_id": "21q3123"
"user_token":"asd2334rter"
"first_name" : "User Test"
"last_name" : "user last name"
}
On your Android client you need to have something like this also
public class User {
String user_id;
String user_token;
String first_name;
String last_name;
//Getter and Setters
}
Retrofit by default use Gson to parser all requests.
See here a good example of Paser.com and Retrofit:
Android-Retrofit-Example