Retrofit 2 - POST request became GET? - android

My POST request keeps sending as GET & got rejected by API endpoint
MyService class
#FormUrlEncoded
#POST("api/users/")
Call<List<User>> getUsers(#FieldMap HashMap<String, String> parameters);
Request code
Gson builder = new GsonBuilder().setLenient().create();
Retrofit client = new Retrofit.Builder()
.baseUrl(Constants.API_ENDPOINT_TEST_URL)
.addConverterFactory(GsonConverterFactory.create(builder))
.build();
mApiService = client.create(MyService.class);
Call<List<User>> call = mApiService.getUsers(mParameters);
call.enqueue(new Callback<List<User>>() {
#Override
public void onResponse(Call<List<User>> call, Response<List<User>> response) {
mResponse = response.body();
mResponseObserver.onFinish(mResponse);
}
#Override
public void onFailure(Call<List<User>> call, Throwable t) {
mResponseObserver.onFailure();
}
});
But server rejects it as it reached the server in GET request form !? Having checked with debugger, I saw that:
rawResponse.request.method = GET
Here is screenshot of watch window showing the retrofit's request object:
As you can see, the request method was GET. But the weird part is in the tag, it shows a request object with POST method?
Am i miss something here?
UPDATE
I added logging interceptor & here is the log:
D/OkHttp: --> POST http://***/api/users/ http/1.1
D/OkHttp: Content-Type: application/x-www-form-urlencoded
D/OkHttp: Content-Length: 56
D/OkHttp: --> END POST
D/OkHttp: <-- 200 OK https://***/api/users/ (388ms)
D/OkHttp: Date: Thu, 01 Sep 2016 11:50:23 GMT
D/OkHttp: Server: Apache
D/OkHttp: X-Powered-By: PHP/5.4.34
D/OkHttp: Cache-Control: max-age=2592000
D/OkHttp: Expires: Sat, 01 Oct 2016 11:50:23 GMT
D/OkHttp: Vary: Accept-Encoding
D/OkHttp: Content-Type: application/json; charset=UTF-8
D/OkHttp: Set-Cookie: SESSION_DEFAULT=***; expires=Sun, 04-Sep-2016 11:50:24 GMT; path=/; HttpOnly
D/OkHttp: Set-Cookie: COOKIE[***]=***; path=/; httponly
D/OkHttp: Connection: close
D/OkHttp: <-- END HTTP
looks like the request is a POST. But, the server still responds with error message, saying that the request method is a GET
Hmm, I'll dig a little bit more into it.

Actually, the issue is the combination of 2 factors:
Wrong request protocol has been made (http instead of https)
Server responded with a weird message on wrong protocol: "GET is not supported".
ANyway, thanks #nshmura for your assistant.

I checked your program with logging, and confirms the POST request is sent.
I recommend you to check like this:
class TestClass {
private void testRequest() {
HashMap<String, String> mParameters = new HashMap<>();
HttpLoggingInterceptor logging = new HttpLoggingInterceptor();
logging.setLevel(HttpLoggingInterceptor.Level.HEADERS);
OkHttpClient.Builder httpClient = new OkHttpClient.Builder();
httpClient.addInterceptor(logging); // <-- this is the important line!
Gson builder = new GsonBuilder().setLenient().create();
Retrofit client = new Retrofit.Builder()
.baseUrl(Constants.API_ENDPOINT_TEST_URL)
.addConverterFactory(GsonConverterFactory.create(builder))
.client(httpClient.build())
.build();
MyService mApiService = client.create(MyService.class);
Call<List<User>> call = mApiService.getUsers(mParameters);
call.enqueue(new Callback<List<User>>() {
#Override
public void onResponse(Call<List<User>> call, Response<List<User>> response) {
}
#Override
public void onFailure(Call<List<User>> call, Throwable t) {
}
});
}
interface MyService {
#FormUrlEncoded
#POST("api/users/")
Call<List<User>> getUsers(#FieldMap HashMap<String, String> parameters);
}
class User {
}
class Constants {
public static final String API_ENDPOINT_TEST_URL = "http://.........";
}
}
here is request log:
D/OkHttp: --> POST http://......... http/1.1
D/OkHttp: Content-Type: application/x-www-form-urlencoded
D/OkHttp: Content-Length: 0
D/OkHttp: --> END POST
Here is response:
D/OkHttp: <-- 200 OK http://.............../ (167ms)
D/OkHttp: Server: nginx
D/OkHttp: Date: Thu, 01 Sep 2016 11:30:32 GMT
D/OkHttp: Content-Type: text/html; charset=UTF-8
D/OkHttp: Connection: close
....
D/OkHttp: <-- END HTTP

I met a similar problem. In my case, I received in response to 301, redirect and change of method POST -> GET.
First, check your BASE_URL, it must be of the form "h ttps://www.YourSite.com/" www - very important. If everything is in place and the problem still exists, then you can change as described below:
From okhttp wiki and based on this image, you need to change something like this:
...
OkHttpClient.Builder httpClient = new OkHttpClient.Builder();
final RequestBody requestBody = new FormBody.Builder().build();
httpClient.addNetworkInterceptor(new Interceptor() {
#Override public Response intercept(Chain chain) throws IOException {
Request request = chain.request();
HttpUrl.Builder builder = request.url().newBuilder();
HttpUrl url = builder.build();
request = request.newBuilder()
.url(url)
.post(requestBody)
.build();
return chain.proceed(request);
}
})
httpClient.addInterceptor(logging);
...

Can u try
#POST("/api/users/")
With slash before "api"?
Also it would be helpful to double check request with Fiddler or smth.

That is partly correct a http client behavior. According to the HTTP spec
If the 307 status code is received in response to a request other than GET or HEAD, the user agent MUST NOT automatically redirect the request unless it can be confirmed by the user, since this might change the conditions under which the request was issued.
Sometime it is not possible to change backend API. So here a workaround you can add to you interceptor to manually redirect a request with correct method.
fun forceRedirectMethod(chain: Interceptor.Chain, originResponse: Response): Response {
/* TODO
one more request is made; disable followRedirect and make it manually?
*/
if (originResponse.priorResponse()?.code() == 302) {
val priorResponse: Response = originResponse.priorResponse() as Response
val redirectRequest = priorResponse.request()
val builder = originResponse.request().newBuilder()
.method(redirectRequest.method(), redirectRequest.body())
val newRequest = builder.build()
return chain.proceed(newRequest)
} else {
return originResponse
}
}

Related

Retrofit methods do not execute

I have an Android client and a Rest API built with ASP Web API. My problem is only in one request, the onSuccess() and onFailure() methods do not execute and the return value from API is Null. But the request works correctly(I checked it using OkHttp). But other requests work perfectly. I tried running it using execute() but I had NetworkOnMainThreadException.
Here is my OkHttp part:
OkHttpClient.Builder client = new OkHttpClient.Builder();
HttpLoggingInterceptor loggingInterceptor = new
HttpLoggingInterceptor();
loggingInterceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
client.addInterceptor(new Interceptor() {
#Override
public Response intercept(Chain chain) throws IOException {
Request request = chain.request();
Request.Builder requestBuilder = request.newBuilder();
requestBuilder.addHeader("Accept", "application/json");
requestBuilder.addHeader("Content-type", " application/json");
if (SharedPrefs.isAuthorized(CApplication.appContext)) {
String token = "bgbqdjsbfjsadnvas";
requestBuilder.addHeader("Authorization", token);
}
requestBuilder.method(request.method(), request.body());
return chain.proceed(requestBuilder.build());
}
}).addInterceptor(loggingInterceptor);
mRetrofit = new Retrofit.Builder()
.baseUrl(ClientConfig.BASE_URL)
.client(client.build())
.addConverterFactory(GsonConverterFactory.create())
.build();
restInterface = mRetrofit.create(RestInterface.class);
Here is my Request:
M_Contact mContact = new M_Contact();
Call<M_Contact> call = rest.getAllContacts(userId);
call.enqueue(new Callback<M_Contact>() {
#Override
public void onResponse(Call<M_Contact> call, Response<M_Contact> response) {
if (null != response) {
if (response.isSuccessful())
Toast.makeText(mContext, "Success: " + response.code(), Toast.LENGTH_SHORT).show()
else
Toast.makeText(mContext, "Something Happened: " + response.code(), Toast.LENGTH_SHORT).show();
}
else Toast.makeText(mContext, "No Data", Toast.LENGTH_SHORT).show();
}
#Override
public void onFailure(Call<M_Contact> call, Throwable t) {
Toast.makeText(mContext, "Failed: " + t.getMessage(), Toast.LENGTH_SHORT).show();
}
});
System.out.println("request finished");
Here is My build.gradle file:
compile('com.squareup.retrofit2:retrofit:2.2.0') {
exclude module: 'okhttp'
}
compile 'com.squareup.okhttp3:okhttp:3.6.0'
compile 'com.squareup.okhttp3:logging-interceptor:3.6.0'
compile 'com.squareup.retrofit2:converter-gson:2.2.0'
Here is my LogFile:
D/OkHttp: --> GET http://192.168.1.58:315/api/Main/RestoreContacts?userId=22 http/1.1
D/OkHttp: Accept: application/json
D/OkHttp: Authorization: upktW1SlDkq0vbl5AjtQeA==
D/OkHttp: --> END GET
D/OkHttp: <-- 200 OK http://192.168.1.58:315/api/Main/RestoreContacts?userId=22 (541ms)
D/OkHttp: Cache-Control: no-cache
D/OkHttp: Pragma: no-cache
D/OkHttp: Content-Type: application/json; charset=utf-8
D/OkHttp: Expires: -1
D/OkHttp: Server: Microsoft-IIS/10.0
D/OkHttp: X-AspNet-Version: 4.0.30319
D/OkHttp: X-Powered-By: ASP.NET
D/OkHttp: Date: Thu, 29 Jun 2017 06:55:40 GMT
D/OkHttp: Content-Length: 842
D/OkHttp: {"userId":22,"contactList":[{"id":4589,"name":"gholam","phoneNumberList":[{"id":6148,"phoneNumber":"+989114514225","isPrimary":"","type":null}]},{"id":4590,"name":"karim","phoneNumberList":[{"id":6149,"phoneNumber":"+9821444","isPrimary":"","type":null},{"id":6150,"phoneNumber":"+9822444","isPrimary":"","type":null}]},{"id":4591,"name":"test1","phoneNumberList":[{"id":6151,"phoneNumber":"+98911791","isPrimary":"","type":null},{"id":6152,"phoneNumber":"+9815246","isPrimary":"","type":null}]},{"id":4592,"name":"hamid","phoneNumberList":[{"id":6153,"phoneNumber":"1564164","isPrimary":"0","type":null},{"id":6154,"phoneNumber":"+619111158","isPrimary":"0","type":null}]}],"contactCount":4,"phoneNumberCount":7,"userDevice":{"model":"Genymotion Custom Phone - 4.2.2 - API 17 - 768x1280","serial":"000000000000000"},"isCacheAvailable":false}
D/OkHttp: <-- END HTTP (842-byte body)
I Really Appreciate Any Kind Of Help. Thanks
Update:
For Wrapping up again, the request result is Successful, But, The Two Methods(onSuccess() and onFailure()) does not work. they don't even start.
I just updated the request part. it's like, after the call.enqueue(... line starts, it suddenly jump to the System.out.println('...'); line without passing through the onSuccess() and onFailure();.
UPDATE
This is my Response Data Structure:
class M_Contact{
public int userId;
public List<ContactModel> contactList;
public int contactCount;
public int phoneNumberCount;
public M_Device userDevice;
public boolean isCacheAvailable;
}
class ContactModel{
public int id;
public String name;
public List<M_ContactPhoneNumber> phoneNumberList;
}
class M_ContactPhoneNumber{
public int id;
public String phoneNumber;
public String isPrimary;
public String label;
}
class M_Device{
public String model;
public String serial;
}
I Removed getter and setters and other methods for ease in reading.
I know it's silly but I just solve the problem with changing the request Execution line. At first, request execute at the last line of onCreate() but when I removed it to the first line of onCreate(), it solved :|
if Any body knows why this happened, I will appreciate to let me know too.
Thanks!

Retrofit 2 - delayed response

I have a problem with retrofit 2. I'm sending some data to Microsoft EAS server but a response is received after 20 sec. Why I know that this is a retrofit problem? Because without retrofit it is working correctly.
my logs:
D/OkHttp: --> POST https://{my_host}/Microsoft-Server-ActiveSync?Cmd=Provision&User={myuser}&DeviceId=837bc6c5690b40b98ab55f7a2231e50c&DeviceType={mydevicetype} http/1.1
D/OkHttp: Content-Type: application/vnd.ms-sync.wbxml
D/OkHttp: Content-Length: 456
D/OkHttp: Authorization: Basic XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
D/OkHttp: MS-ASProtocolVersion: 14.1
D/OkHttp: Connection: keep-alive
D/OkHttp: User-Agent: MyUserAgent
D/OkHttp: X-MS-PolicyKey: 0
D/OkHttp: [3,1,106,0,0,14,[...more here...],88,77,76,0,1,1,1,1] // <--- body
D/OkHttp: --> END POST (456-byte body)
after 20 sec (it seems like I receive response after 20 + normal receive time - in this case: 20596ms):
D/OkHttp: <-- 200 OK https://{my_host}/Microsoft-Server-ActiveSync?Cmd=Provision&User={myuser}&DeviceId=837bc6c5690b40b98ab55f7a2231e50c&DeviceType={mydevicetype} (20596ms)
D/OkHttp: Content-Type: application/vnd.ms-sync.wbxml
D/OkHttp: request-id: {request_id}
D/OkHttp: Set-Cookie: {cookie_data}
D/OkHttp: X-CalculatedBETarget: {target}.local
D/OkHttp: X-MS-BackOffDuration: L/-470
D/OkHttp: X-DiagInfo: EXCHANGEHA
D/OkHttp: X-BEServer: EXCHANGEHA
D/OkHttp: Set-Cookie: {cookie_data}
D/OkHttp: X-FEServer: EX01
D/OkHttp: Date: Fri, 07 Oct 2016 10:30:08 GMT
D/OkHttp: <-- END HTTP (binary 15-byte body omitted)
If I'm requesting it without retrofit, it sends me response immiedetaly.
My code:
Init:
OkHttpClient.Builder httpClient = new OkHttpClient.Builder();
httpClient.addInterceptor(chain -> {
Request original = chain.request();
Request.Builder requestBuilder = original.newBuilder()
.addHeader("Authorization", getAuth(account))
.addHeader("MS-ASProtocolVersion", getProtocolVersion())
.addHeader("Connection", getConnectionType())
.addHeader("User-Agent", getUserAgent())
.addHeader("X-MS-PolicyKey", getPolicyKey());
Request request = requestBuilder.build();
return chain.proceed(request);
});
if (EasConfig.isDebug()) {
HttpLoggingInterceptor logging = new HttpLoggingInterceptor();
logging.setLevel(HttpLoggingInterceptor.Level.BODY);
httpClient.addInterceptor(logging);
}
httpClient.readTimeout(30, TimeUnit.SECONDS);
httpClient.writeTimeout(30, TimeUnit.SECONDS);
OkHttpClient client = httpClient.build();
retrofit = new Retrofit.Builder()
.baseUrl(getBaseUrl(account))
.addConverterFactory(GsonConverterFactory.create())
.client(client)
.build();
Call:
ActiveSyncService service = retrofit.create(ActiveSyncService.class);
service.getData(getContentType(), command, getUser(account), getDeviceId(), getUserAgent(), serializer.toByteArray());
Endpoint:
#POST("Microsoft-Server-ActiveSync")
Call<ResponseBody> getData(#Header("Content-Type") String contentType, // <--- it has to be here -- it's not woking if I set it in incerteptor (don't know why)
#Query("Cmd") String command,
#Query("User") String user,
#Query("DeviceId") String deviceId,
#Query("DeviceType") String deviceType,
#Body byte[] data);

Retrofit returns Http code 400

Update There seems to be an issue with the way dates are interpreted by retrofit and spring. Request works when date is set to null.
I am trying to send a POST request from android using retrofit2 to my backend server running on Spring. I get a 400 Bad Request code and can't find the reason for it. I tried the spring controller with swagger UI and it worked ok, so I'm guessing the android side is the issue.
Android side:
//this is inside Async task, there's 1 more retrofit call above
UserTemplate template;
// fill template
UserService userService = (UserService) RetrofitBuilder.getService(UserService.class,
RetrofitBuilder.BASE_URL);
Call<User> userCall = userService.register(template);
Response<User> registeredUser;
try {
registeredUser = userCall.execute();
} catch (IOException e) {
e.printStackTrace();
return null;
}
Log.d("call", "call status " + registeredUser.code());
return registeredUser.body();
}
//---------------------------------------------------------
public class RetrofitBuilder {
public static final String BASE_URL = "http://my-backend-url.com/";
public static final String IMGUR_URL = "https://api.imgur.com/";
/**
* Added logging
*/
public static Retrofit build(String url) {
GsonBuilder builder = new GsonBuilder();
HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor();
interceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
OkHttpClient client = new OkHttpClient.Builder().addInterceptor(interceptor).build();
builder.registerTypeAdapter(Date.class, new JsonDeserializer<Date>() {
public Date deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
return new Date(json.getAsJsonPrimitive().getAsLong());
}
});
Gson gson = builder.create();
return new Retrofit.Builder()
.client(client)
.baseUrl(useLocalhost ? LOCALHOST : url)
.addConverterFactory(GsonConverterFactory.create(gson))
.build();
}
public static Object getService(Class<?> clas, String url) {
return build(url).create(clas);
}
}
//----------------------------------------------------
public interface UserService {
#POST("/register/")
Call<User> register(#Body UserTemplate userTemplate);
}
And spring side:
#RestController
public class RegisterController {
#Autowired
UserService userService;
#RequestMapping(value = "register", method = RequestMethod.POST)
public ResponseEntity<?> register(#RequestBody UserTemplate userTemplate) {
User user = UserMapper.map(userTemplate);
BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
user.setPassword(passwordEncoder.encode(user.getPassword()));
User u = userService.register(user);
return ResponseEntity.ok().body(u);
}
UserTemplate
public class UserTemplate {
String firstName;
String lastName;
String email;
String username;
String password;
float targetDistance;
String notifications;
Date dateOfBirth;
String description;
String profilePicture;
//getters, setters, toString
}
OkHttp log
D/OkHttp: --> POST http://mafia-test-env-java.eu-central-1.elasticbeanstalk.com/register http/1.1
D/OkHttp: Content-Type: application/json
D/OkHttp: Content-Length: 168
D/OkHttp: {"dateOfBirth":"Aug 21, 2016 12:00:00 AM","email":"a#a.aa","firstName":"A","lastName":"A","password":"a","profilePicture":"IyYD8uY","username":"a","targetDistance":0.0}
D/OkHttp: --> END POST (168-byte body)
D/OkHttp: <-- 400 Bad Request http://mafia-test-env-java.eu-central-1.elasticbeanstalk.com/register (192ms)
D/OkHttp: Server: nginx/1.8.1
D/OkHttp: Date: Sun, 21 Aug 2016 20:28:02 GMT
D/OkHttp: Content-Type: application/json;charset=UTF-8
D/OkHttp: Transfer-Encoding: chunked
D/OkHttp: Connection: keep-alive
D/OkHttp: Access-Control-Allow-Origin: *
D/OkHttp: Access-Control-Allow-Methods: POST, GET, PUT, OPTIONS, DELETE
D/OkHttp: Access-Control-Max-Age: 3600
D/OkHttp: Access-Control-Allow-Headers: Origin, X-Requested-With, Content- Type, Accept, ${cerberus.token.header}
D/OkHttp: X-Content-Type-Options: nosniff
D/OkHttp: X-XSS-Protection: 1; mode=block
D/OkHttp: Cache-Control: no-cache, no-store, max-age=0, must-revalidate
D/OkHttp: Pragma: no-cache
D/OkHttp: Expires: 0
D/OkHttp: X-Frame-Options: DENY
D/OkHttp: <-- END HTTP (binary 1408-byte body omitted)
D/call: call status =400, message =Bad Request
Please enlighten me.
The Web server (running the Web site) thinks that the data stream sent by the client (e.g. your Web browser or our CheckUpDown robot) was 'malformed' i.e. did not respect the HTTP protocol completely. So the Web server was unable to understand the request and process it.
I guess you pass not completely data to server.

Android - Sending .wav file using RETROFIT2 for Speaker Recognition

I'm trying to send a .wav file using Retrofit2 on Android in order to use the Create Enrollment request of the Microsoft Speaker Recognition API (https://dev.projectoxford.ai/docs/services/563309b6778daf02acc0a508/operations/56406930e597ed20c8d8549c)
But I always get the following Error 400:
com.mobile.cir.voicerecognition D/OkHttp: <-- 400 Bad Request https://api.projectoxford.ai/spid/v1.0/verificationProfiles/94BC205B-FACD-42A7-9D80-485403106627/enroll (3907ms)
com.mobile.cir.voicerecognition D/OkHttp: Cache-Control: no-cache
com.mobile.cir.voicerecognition D/OkHttp: Pragma: no-cache
com.mobile.cir.voicerecognition D/OkHttp: Content-Length: 123
com.mobile.cir.voicerecognition D/OkHttp: Content-Type: application/json; charset=utf-8
com.mobile.cir.voicerecognition D/OkHttp: Expires: -1
com.mobile.cir.voicerecognition D/OkHttp: X-AspNet-Version: 4.0.30319
com.mobile.cir.voicerecognition D/OkHttp: X-Powered-By: ASP.NET
com.mobile.cir.voicerecognition D/OkHttp: apim-request-id: e5472946-ec90-4662-a3c9-dda62c2c6b27
com.mobile.cir.voicerecognition D/OkHttp: Date: Fri, 12 Aug 2016 11:43:04 GMT
com.mobile.cir.voicerecognition D/OkHttp: }
com.mobile.cir.voicerecognition D/OkHttp: <-- END HTTP (123-byte body)
com.mobile.cir.voicerecognition D/EnableVoiceRecognition: Upload success
com.mobile.cir.voicerecognition D/errorĀ message: RequestError{code='null', message='null'}
Here is my Apiclient class:
public static Retrofit getClient() {
if (retrofit==null) {
HttpLoggingInterceptor logging = new HttpLoggingInterceptor();
logging.setLevel(HttpLoggingInterceptor.Level.BODY);
OkHttpClient httpClient = new OkHttpClient.Builder().addInterceptor(logging).build();
retrofit = new Retrofit.Builder()
.baseUrl(BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.client(httpClient)
.build();
}
return retrofit;
}
The POST request:
#Multipart
#POST("verificationProfiles/{VerificationProfileId}/enroll")
Call<EnrollmentResponse> createEnrollment(#Path("VerificationProfileId") String profileId,
#Header("Content-Type") String contentType,
#Header("Ocp-Apim-Subscription-Key") String subscriptionKey,
#Part("file") RequestBody audioFile);
}
And the action itself:
File audioFile = new File(fileDirectory + "my_voice.wav");
RequestBody requestAudioFile = RequestBody.create(MediaType.parse("application/octet-stream"), audioFile);
Call<EnrollmentResponse> call = apiService.createEnrollment(PROFILE_ID_TEST,"audio/wav; samplerate=1600",API_KEY,requestAudioFile);
call.enqueue(new Callback<EnrollmentResponse>() {
#Override
public void onResponse(Call<EnrollmentResponse> call, Response<EnrollmentResponse> response) {
Log.d(TAG,"Upload success");
RequestError error = ErrorUtils.parseError(response);
Log.d("error message", error.toString());
Log.d(TAG,"Response: " + response.body().toString());
}
#Override
public void onFailure(Call<EnrollmentResponse> call, Throwable t) {
Log.d(TAG,"Upload error: " + t.getMessage());
}
});
Where am I doing wrong?
* EDIT *
Microsoft developers released the Android library for this API
(https://github.com/Microsoft/Cognitive-SpeakerRecognition-Android)

API key is always missing when I try to access MailChimp's api using Retrofit

I'm sure this is a non issue for someone who knows what they're doing, but this is my first time using MailChimp's api and retrofit. Basically, my api key is always missing. I have no idea what MailChimp's proper url looks like when you are including an api key.
The url I am attempting is:
/3.0/lists/613cd953b2/members?user=email#gmail.com:apikey
And others of that variety
http://developer.mailchimp.com/documentation/mailchimp/reference/lists/members/#create-post_lists_list_id_members
curl --request GET \
--url 'https://.api.mailchimp.com/3.0/' \
--user 'anystring:your_apikey'
This says GET but I am attempting a post.
Here is my android / java code...
final OkHttpClient client = new OkHttpClient();
HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor();
interceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
client.interceptors().add(interceptor);
client.interceptors().add(new Interceptor() {
#Override
public com.squareup.okhttp.Response intercept(Chain chain) throws IOException {
Request original = chain.request();
Request.Builder requestBuilder = original.newBuilder()
// .header("Authorization", basic)
.header("user", "email#gmail.com:apikey");
Request request = requestBuilder.build();
return chain.proceed(request);
}
});
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(BASE_URL)
.client(client)
.addConverterFactory(GsonConverterFactory.create())
.build();
//Create interface instance
MailChimpAPI apiService = retrofit.create(MailChimpAPI.class);
Email chimpEmail = new Email("hi#hi.hi");
Call<Email> call = apiService.addUser(chimpEmail);
call.enqueue(new Callback<Email>() {
#Override
public void onResponse(Response<Email> response, Retrofit retrofit) {
int statusCode = response.code();
//Log.d("tag", "enter the void");
Log.d("tag", statusCode + "");
Log.d("tag", client.toString());
}
#Override
public void onFailure(Throwable t) {
Log.d("tag", t.toString());
}
});
And how I define my interface method
#POST("/3.0/lists/613cd953b2/members")
Call<Email> addUser(#Body Email email);
And my retrofit log...
D/OkHttp: --> POST /3.0/lists/613cd953b2/members HTTP/1.1
D/OkHttp: {"email_address":"hi#hi.hi","merge_fields":{"FNAME":"","LNAME":""},"status":""}
D/OkHttp: --> END POST (79-byte body)
D/OkHttp: <-- HTTP/1.1 401 (299ms)
D/OkHttp: OkHttp-Selected-Protocol: h2
D/OkHttp: server: nginx
D/OkHttp: content-type: application/problem+json; charset=utf-8
D/OkHttp: x-request-id: 6b6ca6a9-c141-45fc-8de7-ec0922892bbf
D/OkHttp: link: <https://us12.api.mailchimp.com/schema/3.0/ProblemDetailDocument.json>; rel="describedBy"
D/OkHttp: vary: Accept-Encoding
D/OkHttp: date: Tue, 05 Jan 2016 21:21:45 GMT
D/OkHttp: set-cookie: _AVESTA_ENVIRONMENT=prod; path=/
D/OkHttp: OkHttp-Sent-Millis: 1452028904738
D/OkHttp: OkHttp-Received-Millis: 1452028904830
D/OkHttp: {"type":"http://developer.mailchimp.com/documentation/mailchimp/guides/error-glossary/","title":"API Key Missing","status":401,"detail":"Your request did not include an API key.","instance":""}
D/OkHttp: <-- END HTTP (193-byte body)
I was not using basic authentication properly. I followed this tutorial
https://futurestud.io/blog/android-basic-authentication-with-retrofit
and it fixed my error! Yay for new errors!
Also for future people, maybe this might help you.
BASIC AUTHORIZATION isn't just a way to describe something! It's an actual concept and implementable! haha

Categories

Resources