Trying to access an api with #POST and I already set my #Header("Authorization") String TOKEN.
I've tried it with #GET and it worked, but I'm passing a some form fields so I need to use #POST
#POST("details")
#FormUrlEncoded
Call<Play> playTrack(
#Header("Authorization") String TOKEN,
#Field("event_id") int event_id,
#Field("longitude") double longitude,
#Field("latitude") double latitude
);
Try to create a header interceptor and add it to OkHttpClient :
Interceptor headerIntercepter = new Interceptor() {
#Override
public okhttp3.Response intercept(Chain chain) throws IOException {
return chain.proceed( chain.request().newBuilder().addHeader("authorization-
client", accessToken).build());
}
};
OkHttpClient client = new OkHttpClient.Builder().connectTimeout(120, TimeUnit.SECONDS).readTimeout(120, TimeUnit.SECONDS)
.addInterceptor(headerIntercepter)
.build();
try {
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(Server_URL)
.client(client)
.addConverterFactory(GsonConverterFactory.create())
.build();
apiService = retrofit.create(Api.class);
try using Multipart on annotation
#Multipart
#POST("details")
Call<ResponseBody> playTrack(
#Header("Authorization") String token,
#Part("event_id") RequestBody eventId,
#Part("longitude") RequestBody longitude,
#Part("latitude") RequestBody latitude,
);
make sure to pass a RequestBody as params
val latitude = RequestBody.create(MediaType.parse("text/plain"), doubleLatitude.toString())
Seeing a 401 response means that the request was successfully executed
and the server returned that status code. This is not a problem with
Retrofit, but in whatever authentication information you are including
in the request that the server expects.
Try with postman with the same data and check
N.B: Don't forgot to add Token Type as prefix to your token
Related
I'm uploading a file using Retrofit to AWS S3, however the content-type is being overridden everytime I upload. I have the the CONTENT-TYPE audio/mp3 however the file on S3 is being overridden as content-type multiformpartbody/form-data. What am I doing incorrectly?
File file = new File(String.valueOf(Uri.parse(selectedImagesList.get(current_image_uploading))));
ProgressRequestBody requestFile = new ProgressRequestBody(file, "audio/mp3");
MultipartBody.Part body =
MultipartBody.Part.createFormData("audio", file.getName(), requestFile);
RetrofitInterfaces.IUploadMP3 service = RetrofitClientInstance.getRetrofitInstance()
.create(RetrofitInterfaces.IUploadMP3.class);
Call<Void> call = service.listRepos(uploadUrls.get(current_image_uploading), body);
Most likely you need to override the header when you send the request. You can either do it for each request:
OkHttpClient.Builder httpClient = new OkHttpClient.Builder();
httpClient.addInterceptor(new Interceptor() {
#Override
public Response intercept(Interceptor.Chain chain) throws IOException {
Request original = chain.request();
Request request = original.newBuilder()
.header("Content-Type"," audio/mpeg") //Set the content type here
.method(original.method(), original.body())
.build();
return chain.proceed(request);
}
}
OkHttpClient client = httpClient.build();
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(API_BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.client(client)
.build();
Or, if you don't want to override every request, you can do a static override for your call like so:
public interface YourService {
#Headers("Content-Type: audio/mpeg")
#GET("/your/path")
Call<List<Task>> myFunction();
}
Both examples can be found here:
I am using retrofit to make a POST call to AWS server. It gives me the following error
Response{protocol=h2, code=403, message=, url=https://9oe8xt95sj.execute-api.ap-southeast-1.amazonaws.com/voip-dev-wa/staging/Device/registerCustomer}
My Retrofit method is as below
Retrofit retrofit;
retrofit = new Retrofit.Builder()
.baseUrl(ApiService.API_BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.build();
apiService = retrofit.create(ApiService.class);
ApiService.java
String API_BASE_URL = "SOME String";
#POST("registerCustomer")
#Headers({"Content-Type: application/json", "accept: application/json"})
Call<RegisterResponse> register(#Body Register register);
How to solve this?
The problem is I did not pass the access token as the header. So it is responding forbidden error.
OkHttpClient.Builder client = new OkHttpClient.Builder();
client.addInterceptor(new Interceptor() {
#Override
public okhttp3.Response intercept(Chain chain) throws IOException {
Request.Builder ongoing = chain.request().newBuilder();
ongoing.addHeader("Content-Type", "application/json");
ongoing.addHeader("accept", "application/json");
ongoing.addHeader("Authorization", "Bearer " + AppSetting.getInstance().getSDKDataManager().getAccessToken());
return chain.proceed(ongoing.build());
}
});
I am trying to make a post request through Retrofit2 in which email is sent as key value pair (not as POJO like using #Body with Retrofit2), by using this #FormUrlEncoded I am able to hit the API but "#" sign gets converted to "%40" and same case for any other special symbols. Can anyone help sending the email to API server using Retrofit2 without using the #Body in Retrofit2.
My code is as below:
public RetroWrapper (Context context, Object listener) {
this.context = context;
this.listener = listener;
OkHttpClient.Builder builder = new OkHttpClient().newBuilder();
builder.readTimeout(40, TimeUnit.SECONDS);
builder.connectTimeout(20, TimeUnit.SECONDS);
if (BuildConfig.DEBUG) {
HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor();
interceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
builder.addInterceptor(interceptor);
}
builder.addInterceptor(new Interceptor() {
#Override
public Response intercept(Chain chain) throws IOException {
// Request request = chain.request().newBuilder().addHeader("Content-Type", "text/json").build();
Request request = chain.request().newBuilder().addHeader("Content-Type", "application/x-www-form-urlencoded").build();
return chain.proceed(request);
}
});
OkHttpClient client = builder.build();
retrofit= new Retrofit.Builder()
.baseUrl(BuildConfig.WEBSERVICE_BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.addConverterFactory(ScalarsConverterFactory.create())
.client(client).build();
}
public void loginCheckDirectPost(Map<String,String> stringStringMap){
RetroServices.RetroServicePostLoginReqDirectPost retroSrvcGetFeeds = retrofit.create(RetroServices.RetroServicePostLoginReqDirectPost.class);
Call<PostLoginResp> getFeedsCall = retroSrvcGetFeeds.CALL(stringStringMap);
getFeedsCall.enqueue((Callback<PostLoginResp>) listener);
}
public interface RetroServicePostLoginReqDirectPost{
#FormUrlEncoded
#POST("token")
Call<PostLoginResp> CALL(#FieldMap Map<String, String> params);
}
Your content is being URL encoded , so "#" becomes %40.
You will need to modify it at the server to decode %40 into "#";
I have to call an api using retrofit 2 in android. but with no values. When I does that, it shows that there must be at least 1 #field. Below is the code I am using.
public interface gitAPI {
#FormUrlEncoded
#POST("/MembersWS.svc/GetMemberAvailability/MBR0011581")
Call<Questions[]> loadQuestions();
}
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("http://192.168.1.99:82")
.addConverterFactory(GsonConverterFactory.create())
.build();
// prepare call in Retrofit 2.0
gitAPI stackOverflowAPI = retrofit.create(gitAPI.class);
Call<Questions[]> call = stackOverflowAPI.loadQuestions();
call.execute();
Declare body value in your interface with next:
#Body RequestBody body and wrap String JSON object:
RequestBody body = RequestBody.create(MediaType.parse("application/json"), (new JsonObject()).toString());
Can anyone tell the exact format to convert below code into retrofit
curl -X POST -d "grant_type=password&username=admin&password=admin&scope=read+write" -u"clientId:clientSecret" http://myserver/o/token/
I have tried something like this but it isn't working
#FormUrlEncoded
#POST("/o/token/")
AccessTokenResponse getToken(#Field("client_id") String client_id, #Field("client_secret") String client_secret,
#Field("grant_type") String grant_type, #Field("username") String username,
#Field("password") String password, #Field("scope") String scope);
Client credentials should be authenticated with Basic Authentication. i.e with header
Authorization: Basic base64encode(clientId:clientSecret)
where base64encode(clientId:clientSecret) is the actual base64 encoded string of clientId:clientSecret. So to update your interface it might look something more like
public interface OAuthTokenService {
#POST("/api/token")
#FormUrlEncoded
#Headers({
"Accept: application/json"
})
AccessTokenResponse getAccessToken(#Field("grant_type") String grantType,
#Field("username") String username,
#Field("password") String password,
#Header("Authorization") String authorization);
}
Then to set the header, do something like
public class Main {
public static void main(String[] args) {
RestAdapter restAdapter = new RestAdapter.Builder()
.setLogLevel(RestAdapter.LogLevel.FULL)
.setEndpoint("http://localhost:8080")
.setConverter(new JacksonConverter())
.build();
OAuthTokenService service = restAdapter.create(OAuthTokenService.class);
byte[] credentials = "clientId:clientSecret".getBytes();
String basicAuth = "Basic " + Base64.getEncoder().encodeToString(credentials);
AccessTokenResponse response = service
.getAccessToken("password", "admin", "admin", basicAuth);
System.out.println(response.getAccessToken());
}
}
Note the above uses Java 8 for the java.util.Base64 class. You may not be using Java 8, in which case you will need to find a different encoder.
I am also using Jackson for conversion, only because I don't use Gson. The above has been tested and should work for you also.
With OkHttp interceptors this is made easier.
Interceptor interceptor = chain -> {
Request original = chain.request();
Request request = original.newBuilder()
.header("Authorization", Credentials.basic(CLIENT_ID, CLIENT_SECRET))
.method(original.method(), original.body())
.build();
return chain.proceed(request);
};
OkHttpClient client = new OkHttpClient.Builder()
.addInterceptor(interceptor)
.build();
return new Retrofit.Builder()
.baseUrl(baseURL)
.client(client)
.addConverterFactory(GsonConverterFactory.create())
.build();
The Credentials.basic method will base 64 encode your client id and client secret. The interceptor is then attached to the OkHttpClient client and added to the Retrofit object.