I use Retrofit 2 library, and I need to send POST JSON request like this:
{
"datetime": 0,
"body": {
"gymId": "17C1B14C-C21F-41EE-BF75-F0E7843DB638",
"customerName": "test",
"customerEmail": "test#test.ru",
"content": "test"
}
}
How i can send this request use RequestBody?
Call<ApiClubRequest> clubContact(#Body RequestBody requestBody);
Or can easily make such a request?
This is my interface class with OkHttp settings.
public class RestClient {
private static ClassApiInterface WordClassApiInterface ;
private static String baseUrl = "http://my adddress" ;
public static WorldClassApiInterface getClient() {
if (WordClassApiInterface == null) {
OkHttpClient okClient = new OkHttpClient();
okClient.interceptors().add(new Interceptor() {
#Override
public Response intercept(Chain chain) throws IOException {
Response response = chain.proceed(chain.request());
return response;
}
});
Retrofit client = new Retrofit.Builder()
.baseUrl(baseUrl)
.client(okClient)
.addConverterFactory(GsonConverterFactory.create())
.build();
ApiInterface = client.create(ApiInterface.class);
}
return ClassApiInterface ;
}
public static Call<ApiClubRequest> clubcontact(String gymId, String customerName, String
customerEmail, String content){
ClubContactRequest request = new ClubContactRequest();
request.gymId = gymId;
request.customerName = customerName;
request.customerEmail = customerEmail;
request.content = content;
return ApiInterface.clubContact(request);
}
#Headers("Content-Type: application/json")
#POST("/hotline")
Call<ApiClubRequest> clubContact(#Body ClubContactRequest requestBody);
}
}
Create a request class and create fields with the same name as in the JSON:
public class ClubContactRequest {
public String gymId;
public String customerName;
public String customerEmail;
public String content;
}
Modify the POST #Body:
Call<ApiClubRequest> clubContact(#Body ClubContactRequest requestBody);
Then implement the request:
public Call<ApiClubRequest> clubcontact(String gymId, String customerName, String customerEmail, String content){
ClubContactRequest request = new ClubContactRequest();
request.gymId = gymId;
request.customerName = customerName;
request.customerEmail = customerEmail;
request.content = content;
return yourApiInterface.clubContact(request);
}
Related
I am facing problem sending post request with content-type as x-www-form-urlencoded in android retrofit. Not sure about the error I am making while sending post request. When same request is send via postman, I can receive expected correct response. Moreover, I tried sending same response via html form and received successful response
public class RequestManager {
private static Retrofit retrofit;
private static final String BASE_URL = "https://ipguat.apps.net.pk/Ecommerce/api/Transaction/";
private OkHttpClient okhttpClient;
static Gson gson = new GsonBuilder()
.setLenient()
.create();
public static Retrofit getRetrofitInstance() {
if (retrofit == null) {
retrofit = new retrofit2.Retrofit.Builder()
.baseUrl(BASE_URL)
.addConverterFactory(GsonConverterFactory.create(gson))
.build();
}
return retrofit;
}
}
//MainActivity from where I am sending post request
private void sendPayment(String token) {
Date c = Calendar.getInstance().getTime();
SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd");
String formattedDate = df.format(c);
Call<ResponseBody> call = service.sendPayment("102", "Arfeen Test", token, "00", "5", "03451234567", "arfeen#arfeen.me", "POSTMAN-TEST-ARF", "01", "Test Purchase", "www.facebook.com", "www.google.com", "TEST-01", formattedDate, "www.youtube.com");
call.enqueue(new Callback<ResponseBody>() {
#Override
public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
if (response.isSuccessful()) {
try {
renderPage(response.body().string());
} catch (IOException e) {
e.printStackTrace();
}
}
}
#Override
public void onFailure(Call<ResponseBody> call, Throwable t) {
Toast.makeText(MainActivity.this, "Something went wrong...Please try later!", Toast.LENGTH_SHORT).show();
}
}
);
}
// Interface where endpoint for API is mentioned
public interface TokenService {
#FormUrlEncoded
#POST("PostTransaction/")
Call<ResponseBody> sendPayment(#Field("MERCHANT_ID") String id,
#Field("MERCHANT_NAME") String merchantName,
#Field("TOKEN") String token,
#Field("PROCCODE") String proccode,
#Field("TXNAMT") String transaction,
#Field("CUSTOMER_MOBILE_NO") String mobile,
#Field("CUSTOMER_EMAIL_ADDRESS") String email,
#Field("SIGNATURE") String signature,
#Field("VERSION") String version,
#Field("TXNDESC") String productDescription,
#Field("SUCCESS_URL") String successUrl,
#Field("FAILURE_URL") String failureUrl,
#Field("BASKET_ID") String basketID,
#Field("ORDER_DATE") String orderDate,
#Field("CHECKOUT_URL") String checoutUrl);
}
Use #Headers annotation.
public interface TokenService {
#FormUrlEncoded
#Headers("Content-Type:application/x-www-form-urlencoded")
#POST("PostTransaction/")
Call<ResponseBody> sendPayment(#Field("MERCHANT_ID") String id,
#Field("MERCHANT_NAME") String merchantName,
#Field("TOKEN") String token,
#Field("PROCCODE") String proccode,
#Field("TXNAMT") String transaction,
#Field("CUSTOMER_MOBILE_NO") String mobile,
#Field("CUSTOMER_EMAIL_ADDRESS") String email,
#Field("SIGNATURE") String signature,
#Field("VERSION") String version,
#Field("TXNDESC") String productDescription,
#Field("SUCCESS_URL") String successUrl,
#Field("FAILURE_URL") String failureUrl,
#Field("BASKET_ID") String basketID,
#Field("ORDER_DATE") String orderDate,
#Field("CHECKOUT_URL") String checoutUrl);
}
Try set up OkhttpClient,
OkhttpManager.java
import android.content.Context;
import android.util.Log;
import android.webkit.CookieManager;
import java.security.cert.CertificateException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.TimeUnit;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import okhttp3.Cookie;
import okhttp3.CookieJar;
import okhttp3.HttpUrl;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import okhttp3.logging.HttpLoggingInterceptor;
public class OkHttpManager {
private final String TAG = "OkHttpManager";
private final int TIME_OUT_SECONDS = 60;
private static OkHttpManager instance = null;
private WebViewCookieHandler mWebViewCookieHandler = null;
public static OkHttpManager getInstance() {
if (instance == null) {
instance = new OkHttpManager();
}
return instance;
}
private OkHttpManager() {
if (mWebViewCookieHandler == null)
mWebViewCookieHandler = new WebViewCookieHandler();
}
private static ArrayList<String> sCurCookies = new ArrayList<>();
OkHttpClient getOkHttpClientDefault(Context context) {
// init okhttp 3 logger
HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor();
interceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
try {
final TrustManager[] trustAllCerts = new TrustManager[]{
new X509TrustManager() {
#Override
public void checkClientTrusted(java.security.cert.X509Certificate[] chain, String authType) throws CertificateException {
}
#Override
public void checkServerTrusted(java.security.cert.X509Certificate[] chain, String authType) throws CertificateException {
}
#Override
public java.security.cert.X509Certificate[] getAcceptedIssuers() {
return new java.security.cert.X509Certificate[]{};
}
}
};
return new OkHttpClient()
.newBuilder()
.cookieJar(mWebViewCookieHandler)
.hostnameVerifier((s, sslSession) -> true)
.connectTimeout(TIME_OUT_SECONDS, TimeUnit.SECONDS)
.readTimeout(TIME_OUT_SECONDS, TimeUnit.SECONDS)
.writeTimeout(TIME_OUT_SECONDS, TimeUnit.SECONDS)
.addInterceptor(interceptor)
.addInterceptor(chain -> {
Request.Builder builder = chain.request().newBuilder();
return chain.proceed(builder.build());
})
.addInterceptor(chain -> {
Response response = chain.proceed(chain.request());
if (!response.headers("Set-Cookie").isEmpty()) {
Log.d(TAG, "getCookie header added");
sCurCookies.addAll(response.headers("Set-Cookie"));
}
response.body();
return response;
})
.build();
} catch (Exception e) {
Log.e(TAG, e.toString());
}
return null;
}
private class WebViewCookieHandler implements CookieJar {
private CookieManager webviewCookieManager = CookieManager.getInstance();
#Override
public void saveFromResponse(HttpUrl url, List<Cookie> cookies) {
String urlString = url.toString();
for (Cookie cookie : cookies) {
webviewCookieManager.setCookie(urlString, cookie.toString());
}
}
#Override
public List<Cookie> loadForRequest(HttpUrl url) {
String urlString = url.toString();
String cookiesString = webviewCookieManager.getCookie(urlString);
if (cookiesString != null && !cookiesString.isEmpty()) {
//We can split on the ';' char as the cookie manager only returns cookies
//that match the url and haven't expired, so the cookie attributes aren't included
String[] cookieHeaders = cookiesString.split(";");
List<Cookie> cookies = new ArrayList<>(cookieHeaders.length);
for (String header : cookieHeaders) {
cookies.add(Cookie.parse(url, header));
}
return cookies;
}
return Collections.emptyList();
}
}
}
RequestManager.java
public class RequestManager {
private static Retrofit retrofit;
private static final String BASE_URL = "https://ipguat.apps.net.pk/Ecommerce/api/Transaction/";
private OkHttpClient okhttpClient;
static Gson gson = new GsonBuilder()
.setLenient()
.create();
public static Retrofit getRetrofitInstance(Activity activity) {
if (retrofit == null) {
retrofit = new retrofit2.Retrofit.Builder()
.baseUrl(BASE_URL)
.client(OkHttpManager.getInstance().getOkHttpClientDefault(activity))
.addConverterFactory(GsonConverterFactory.create(gson))
.build();
}
return retrofit;
}
}
I am hitting this API https://westus.dev.cognitive.microsoft.com/docs/services/563309b6778daf02acc0a508/operations/563309b7778daf06340c9652/console
below is my retrofit code. I am not able to send raw JSON in retrofit.
public void createProfileAPI()
{
ApiInterface apiService = ApiClient.getClientRequest().create(ApiInterface.class);
try
{
//pbVrd.setVisibility(View.VISIBLE);
JSONObject paramObject = new JSONObject();
paramObject.put("locale", "en-us");
LocaleModel localeModel = new LocaleModel();
localeModel.setLocale("en-us");
Call<BaseModel> call = apiService.SearchResponse(localeModel);
call.enqueue(new Callback<BaseModel>()
{
#Override
public void onResponse(Call<BaseModel> call, Response<BaseModel> response)
{
int responseCode = response.code();
Log.d("Deepakw" , responseCode+"");
BaseModel response1 = response.body();
Log.d("Deepak" , response.body().getIdentificationProfileId() + " //// " +response1.getIdentificationProfileId()+"");
}
#Override
public void onFailure(Call<BaseModel> call, Throwable t)
{
Log.d("Responce Failed ", "failed Response Mersen Fuse ");
String message = t.getMessage();
Log.d("failure", message);
}
});
}
catch (Exception e)
{
e.printStackTrace();
}
}
public class ApiClient {
public static final String BASE_URL = "https://westus.api.cognitive.microsoft.com/spid/v1.0/";
private static Retrofit retrofit = null;
public static Retrofit getClientRequest() {
if (retrofit == null) {
retrofit = new Retrofit.Builder()
.baseUrl(BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.build();
}
return retrofit;
}
}
public interface ApiInterface {
#Headers({
"Content-Type: application/json",
"Ocp-Apim-Subscription-Key: 0219cf3e3d444f0584f80b3a84613d12"
})
#POST("verificationProfiles")
Call<BaseModel> SearchResponse(#Body LocaleModel body);
};
I am not able to get response
API client
Please help
//In ApiInterface do like this
#Headers("charset:UTF-8")
#POST("verificationProfiles")
Call<BaseModel> SearchResponse(
#Header("Content-Type") String contentType,
#Body LocaleModel body);
have you tried #SerializedName("") and #Expose in your pojo class
#SerializedName("status")
#Expose
private Boolean status;
Instead of JSONObject, you can use Map
For example:
Headers("Content-Type: application/json")
#POST("/apipath")
request(#Body Map<String, String> body);
I am trying to add basic authentication (username and password) to a Retrofit OkHttp client. This is the code I have so far:
private static Retrofit createMMSATService(String baseUrl, String user, String pass) {
HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor();
interceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
OkHttpClient client = new OkHttpClient.Builder().addInterceptor(interceptor).build();
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(baseUrl)
.client(client)
.addConverterFactory(GsonConverterFactory.create())
.build();
return retrofit;
}
I am using Retrofit 2.2 and this tutorial suggests using AuthenticationInterceptor, but this class is not available.
Where is the correct place to add the credentials? Do I have to add them to my interceptor, client or Retrofit object? And how do I do that?
Find the Solution
1.Write a Interceptor class
import java.io.IOException;
import okhttp3.Credentials;
import okhttp3.Interceptor;
import okhttp3.Request;
import okhttp3.Response;
public class BasicAuthInterceptor implements Interceptor {
private String credentials;
public BasicAuthInterceptor(String user, String password) {
this.credentials = Credentials.basic(user, password);
}
#Override
public Response intercept(Chain chain) throws IOException {
Request request = chain.request();
Request authenticatedRequest = request.newBuilder()
.header("Authorization", credentials).build();
return chain.proceed(authenticatedRequest);
}
}
2.Finally, add the interceptor to an OkHttp client
OkHttpClient client = new OkHttpClient.Builder()
.addInterceptor(new BasicAuthInterceptor(username, password))
.build();
Retrofit 2
public class ServiceGenerator {
public static final String API_BASE_URL = "https://your.api-base.url";
private static OkHttpClient.Builder httpClient = new OkHttpClient.Builder();
private static Retrofit.Builder builder =
new Retrofit.Builder()
.baseUrl(API_BASE_URL)
.addConverterFactory(GsonConverterFactory.create());
private static Retrofit retrofit = builder.build();
public static <S> S createService(Class<S> serviceClass) {
return createService(serviceClass, null, null);
}
public static <S> S createService(
Class<S> serviceClass, String username, String password) {
if (!TextUtils.isEmpty(username)
&& !TextUtils.isEmpty(password)) {
String authToken = Credentials.basic(username, password);
return createService(serviceClass, authToken);
}
return createService(serviceClass, null);
}
public static <S> S createService(
Class<S> serviceClass, final String authToken) {
if (!TextUtils.isEmpty(authToken)) {
AuthenticationInterceptor interceptor =
new AuthenticationInterceptor(authToken);
if (!httpClient.interceptors().contains(interceptor)) {
httpClient.addInterceptor(interceptor);
builder.client(httpClient.build());
retrofit = builder.build();
}
}
return retrofit.create(serviceClass);
}
}
Retrofit 1.9
public class ServiceGenerator {
public static final String API_BASE_URL = "https://your.api-base.url";
private static RestAdapter.Builder builder = new RestAdapter.Builder()
.setEndpoint(API_BASE_URL)
.setClient(new OkClient(new OkHttpClient()));
public static <S> S createService(Class<S> serviceClass) {
return createService(serviceClass, null, null);
}
public static <S> S createService(Class<S> serviceClass, String username, String password) {
if (username != null && password != null) {
// concatenate username and password with colon for authentication
String credentials = username + ":" + password;
// create Base64 encodet string
final String basic =
"Basic " + Base64.encodeToString(credentials.getBytes(), Base64.NO_WRAP);
builder.setRequestInterceptor(new RequestInterceptor() {
#Override
public void intercept(RequestFacade request) {
request.addHeader("Authorization", basic);
request.addHeader("Accept", "application/json");
}
});
}
RestAdapter adapter = builder.build();
return adapter.create(serviceClass);
}
}
AuthenticationInterceptor.java
public class AuthenticationInterceptor implements Interceptor {
private String authToken;
public AuthenticationInterceptor(String token) {
this.authToken = token;
}
#Override
public Response intercept(Chain chain) throws IOException {
Request original = chain.request();
Request.Builder builder = original.newBuilder()
.header("Authorization", authToken);
Request request = builder.build();
return chain.proceed(request);
}
}
Usage
Retrofit 2
Interface
public interface LoginService {
#POST("/login")
Call<User> basicLogin();
}
Requester
LoginService loginService =
ServiceGenerator.createService(LoginService.class, "user", "secretpassword");
Call<User> call = loginService.basicLogin();
call.enqueue(new Callback<User >() {
#Override
public void onResponse(Call<User> call, Response<User> response) {
if (response.isSuccessful()) {
// user object available
} else {
// error response, no access to resource?
}
}
#Override
public void onFailure(Call<User> call, Throwable t) {
// something went completely south (like no internet connection)
Log.d("Error", t.getMessage());
}
}
Retrofit 1.9
Interface
public interface LoginService {
#POST("/login")
void basicLogin(Callback<User> cb);
}
Requester
LoginService loginService =
ServiceGenerator.createService(LoginService.class, "user", "secretpassword");
loginService.basicLogin(new Callback<User>() {
#Override
public void success(User user, Response response) {
// user object available
}
#Override
public void failure(RetrofitError error) {
// handle errors, too
}
});
More information see here.
add header interceptor
public class HeaderInterceptor implements Interceptor {
private PreferencesRepository mPrefs;
private String mAuth;
public HeaderInterceptor(PreferencesRepository p) {
mPrefs = p;
}
#Override
public Response intercept(Chain chain) throws IOException {
mAuth = (mPrefs.getAuthToken() != null)?mPrefs.getAuthToken():"";
Request r = chain.request()
.newBuilder()
.addHeader("Accept", "application/json")
// authorization token here
.addHeader("Authorization", "Bearer" + mAuth)
.build();
return chain.proceed(r);
}
}
add cacheinterceptor (optional)
public class CacheInterceptor implements Interceptor {
Context mContext;
public CacheInterceptor(Context context) {
this.mContext = context;
}
#Override
public Response intercept(Chain chain) throws IOException {
Request request = chain.request();
if (request.method().equals("GET")) {
if (DeviceUtils.isConnected(mContext)) {
request = request.newBuilder()
.header(Constant.CACHE_CONTROL, "only-if-cached")
.build();
} else {
request = request.newBuilder()
.header(Constant.CACHE_CONTROL, "public, max-stale=2419200")
.build();
}
}
Response originalResponse = chain.proceed(request);
return originalResponse.newBuilder()
.header(Constant.CACHE_CONTROL, "max-age=600")
.build();
}
}
implement it
HttpLoggingInterceptor logger = new HttpLoggingInterceptor();
logger.setLevel(HttpLoggingInterceptor.Level.BODY);
long SIZE_OF_CACHE = 10 * 1024 * 1024; // 10 MiB
Cache cache = new Cache(new File(mContext.getCacheDir(), "http"), SIZE_OF_CACHE);
new OkHttpClient.Builder()
.addInterceptor(logger)
.addInterceptor(new HeaderInterceptor(u))
.cache(cache)
.addNetworkInterceptor(new CacheInterceptor(mContext))
.connectTimeout(Constant.CONNECTTIMEOUT, TimeUnit.SECONDS)
.readTimeout(Constant.READTIMEOUT, TimeUnit.SECONDS)
.writeTimeout(Constant.WRITETIMEOUT, TimeUnit.SECONDS)
.build();
Of course using auth interceptor is correct way (as explained in other answers). Although, if you need basic authentication only for single call, then auth header can be added directly in Retrofit request:
import okhttp3.Credentials
// Create credentials
val login = "some login"
val password = "some password"
// Below code will create correct Base64 encoded Basic Auth credentials
val credentials = Credentials.basic(login, password)
// Then in your Retrofit API interface
interface MyApi {
#POST("get_user")
fun getUser(#Header("Authorization") credentials: String): ResponseBody
}
I'm not getting the same result I have in POSTMAN working with the Retrofit Android lib. Maybe I'm doing something wrong.
Below is my code that I use to call the API
#Override
protected Response doInBackground(Void... params) {
Response<UserModel> response;
try {
LoginModel loginModel = new LoginModel("password", mEmail, mPassword, "Mobile", "123#abc");
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(Constants.BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.build();
ServiceAPI serviceAPI = retrofit.create(ServiceAPI.class);
Call<UserModel> call = serviceAPI.getToken(loginModel);
try{
response = call.execute();
if (response.body() == null) {
Log.d(getString(R.string.app_name), response.errorBody().toString());
return response;
} else {
return response;
}
}catch ( IOException e){
Log.e(getString(R.string.app_name), e.getMessage());
}
Thread.sleep(2000);
} catch (InterruptedException e) {
return null;
}
return null;
}
Below the interface code
public interface ServiceAPI {
#POST("Token")
Call<UserModel> getToken(#Body LoginModel loginModel);
}
And the result is:
Class LoginModel.java
public class LoginModel {
#SerializedName("grant_type")
private String grantType;
private String username;
private String password;
#SerializedName("client_id")
private String clientId;
#SerializedName("client_secret")
private String clientSecret;
public LoginModel(String grantType, String username, String password, String clientId, String clientSecret) {
this.grantType = grantType;
this.username = username;
this.password = password;
this.clientId = clientId;
this.clientSecret = clientSecret;
}
}
With PostMan the result is different, getting the Token correction.
Update your api
#FormUrlEncoded
#Post("Token")
Call<UserModel> getToken(#Field("grant_type") String grantType),
#Field("username") String userName,
#Field("password") String password
// etc
);
And your api call
Call<UserModel> call = serviceAPI.getToken("password", mEmail, mPassword, ...);
I'm trying to consume a service by using retrofit 2. When I call it using a web browser or log the call using an interceptor, there're some results, but my pojo classes are always empty.
The json result content is similar to:
{
"similarartists": {
"artist": [
{
"name": "BarĂ£o Vermelho",
"mbid": "84ac395b-482b-48cb-b381-b9bc420b2dd3",
"match": "1",
"url": "https://www.last.fm/music/Bar%C3%A3o+Vermelho",
"image": [],
"streamable": "0"
},
"#attr": {
"artist": "Cazuza"
}
}
}
And these are my pojo classes:
public class Similarartists {
#SerializedName("artist")
private List<Artist> artist = new ArrayList<>();
#SerializedName("attr")
private Attr attr;
}
public class Artist {
#SerializedName("name")
private String name;
#SerializedName("mbid")
private String mbid;
#SerializedName("match")
private String match;
#SerializedName("url")
private String url;
#SerializedName("image")
private List<Object> image = new ArrayList<>();
#SerializedName("streamable")
private String streamable;
}
public class Attr {
#SerializedName("artist")
private String artist;
}
The service connection class:
public class ApiService {
private static final String BASE_URL = "http://ws.audioscrobbler.com/";
public static final String API_KEY = "XXXXXXXXXX";
private static OkHttpClient.Builder httpClient = new OkHttpClient.Builder()
.readTimeout(30, TimeUnit.SECONDS)
.connectTimeout(30, TimeUnit.SECONDS);
private static Retrofit.Builder builder =
new Retrofit.Builder()
.baseUrl(BASE_URL)
.addConverterFactory(GsonConverterFactory.create());
public static <S> S createService(Class<S> serviceClass) {
HttpLoggingInterceptor logging = new HttpLoggingInterceptor();
logging.setLevel(HttpLoggingInterceptor.Level.BODY);
httpClient.addInterceptor(logging);
httpClient.addInterceptor(new Interceptor() {
#Override
public Response intercept(Chain chain) throws IOException {
Request original = chain.request();
// Request customization: add request headers
Request.Builder requestBuilder = original.newBuilder()
.header("Accept", "application/json")
.header("Content-Type", "application/json")
.method(original.method(), original.body());
Request request = requestBuilder.build();
return chain.proceed(request);
}
});
Retrofit retrofit = builder.client(httpClient.build()).build();
return retrofit.create(serviceClass);
}
}
Ans this is my "button" action:
private void openSearchDialog() {
ArtistService artistService = ApiService.createService(ArtistService.class);
Call<Similarartists> call = artistService.getSimilar("nirvana", ApiService.API_KEY);
call.enqueue(new Callback<Similarartists>() {
#Override
public void onResponse(Call<Similarartists> call, Response<Similarartists> response) {
if (response.isSuccessful()) {
mAdapter.setValues(response.body().getArtist());
Log.i(TAG, "onResponse: " + response.body().toString());
}
}
#Override
public void onFailure(Call<Similarartists> call, Throwable t) {
Log.e(TAG, "onFailure: ", t);
}
});
}
The problem is response.body().getArtist() is always empty. Please help me.
And this's my log result:
-01 22:51:58.844 23843-24043/com.sample.pablo.hellomusic D/OkHttp: {"similarartists":{"artist":[{"name":"Hole","mbid":"1dcc8968-f2cd-441c-beda-6270f70f2863","match":"1","url":"https://www.last.fm/music/Hole","image":[{"#text":"https://lastfm-img2.akamaized.net/i/u/34s/6687f63408074388ae703eb3905e238f.png","size":"small"},{"#text":"https://lastfm-img2.akamaized.net/i/u/64s/6687f63408074388ae703eb3905e238f.png","size":"medium"},{"#text":"https://lastfm-img2.akamaized.net/i/u/174s/6687f63408074388ae703eb3905e238f.png","size":"large"},{"#text":"https://lastfm-img2.akamaized.net/i/u/300x300/6687f63408074388ae703eb3905e238f.png","size":"extralarge"},{"#text":"https://lastfm-img2.akamaized.net/i/u/6687f63408074388ae703eb3905e238f.png","size":"mega"},{"#text":"https://lastfm-img2.akamaized.net/i/u/arQ/6687f63408074388ae703eb3905e238f.png","size":""}],"streamable":"0"}],"#attr":{"artist":"Nirvana"}}}
Since there is a top-level key of similarartists in the response JSON I think you need another wrapper around this object, like:
public class SimilarArtistsResponse {
#SerializedName("similarartists")
private Similarartists similars;
}
And its this object you would specify in your Call<SimilarArtistsResponse>