How to remove last slash "/" from base url in Retrofit 2 - java

When I Type Base Url="https://www.bkashcluster.com:9081/dreamwave/merchant/trxcheck/sendmsg/" with last slash(/) then give me message like this:
Response{protocol=http/1.1, code=500, message=Internal Server Error, url=https://www.bkashcluster.com:9081/dreamwave/merchant/trxcheck/sendmsg/?user=XX&pass=r#12&msisdn=0160000000&trxid=6BM3KRWHLB}
After "sendmsg" slash(/) does not need
And When I Type Base Url="https://www.bkashcluster.com:9081/dreamwave/merchant/trxcheck/sendmsg" with out last slash(/) then apps unfortunately stop;
For this I Want to remove last "/" any way from Base Url.
private void requestDataForBkashTransaction() {
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("https://www.bkashcluster.com:9081/dreamwave/merchant/trxcheck/sendmsg/")
.addConverterFactory(GsonConverterFactory.create())
.build();
InstituteService api = retrofit.create(InstituteService.class);
String urlString=String.format("?user=Exampll&pass=12345&msisdn=0160000000&trxid=6BM3KRWHLB");
Call<List<Transaction>> call=api.getBkashTrasactionCode(urlString);
call.enqueue(new retrofit2.Callback<List<Transaction>>() {
#Override
public void onResponse(Call<List<Transaction>> call, retrofit2.Response<List<Transaction>> response) {
if(!response.isSuccessful()){
Toast.makeText(PaymentActivity.this, response.code(), Toast.LENGTH_LONG).show();
return;
}
List<Transaction> transactions=response.body();
for(Transaction transaction:transactions){
String content="";
content+=transaction.getTrxId();
textView.append(content);
}
}
#Override
public void onFailure(Call<List<Transaction>> call, Throwable t) {
}
});
}
#GET
Call<List<Transaction>> getBkashTrasactionCode(#Url String url);

This is not how you add query parameters to a call using retrofit. Response code 500 Internal Server Error indicates that. Please refer to this this and add queries properly, then it should work.

To remove last slash,
you have to remove last path from the baseUrl with ../ first, then append it at your urlStirng instead.
String urlString=String.format("../sendmsg?user=Exampll&pass=12345&msisdn=0160000000&trxid=6BM3KRWHLB");

First assign your baseUrl to a String variable and remove the last character as below.
String baseUrl = "https://www.bkashcluster.com:9081/dreamwave/merchant/trxcheck/sendmsg/";
if (baseUrl.endsWith("/")) {
String newBaseUrl = baseUrl.substring(0, baseUrl.length() - 1);
}

Related

Issues using Retrofit2 to call GitHub REST API to update existing file

I'm attempting to use Retrofit to call the GitHub API to update the contents of an existing file, but am getting 404s in my responses. For this question, I'm interested in updating this file. Here is the main code I wrote to try and achieve this:
GitHubUpdateFileRequest
public class GitHubUpdateFileRequest {
public String message = "Some commit message";
public String content = "Hello World!!";
public String sha = "shaRetrievedFromSuccessfulGETOperation";
public final Committer committer = new Committer();
private class Committer {
Author author = new Author();
private class Author {
final String name = "blakewilliams1";
final String email = "blake#blakewilliams.org";
}
}
}
**GitHubUpdateFileResponse **
public class GitHubUpdateFileResponse {
public GitHubUpdateFileResponse() {}
}
GitHubClient
public interface GitHubClient {
// Docs: https://docs.github.com/en/rest/reference/repos#get-repository-content
// WORKS FINE
#GET("/repos/blakewilliams1/blakewilliams1.github.io/contents/qr_config.json")
Call<GitHubFile> getConfigFile();
// https://docs.github.com/en/rest/reference/repos#create-or-update-file-contents
// DOES NOT WORK
#PUT("/repos/blakewilliams1/blakewilliams1.github.io/contents/qr_config.json")
Call<GitHubUpdateFileResponse> updateConfigFile(#Body GitHubUpdateFileRequest request);
}
Main Logic
// Set up the Retrofit client and add an authorization interceptor
UserAuthInterceptor interceptor =
new UserAuthInterceptor("blake#blakewilliams.org", "myActualGitHubPassword");
OkHttpClient.Builder httpClient =
new OkHttpClient.Builder().addInterceptor(interceptor);
Retrofit.Builder builder =
new Retrofit.Builder()
.baseUrl("https://api.github.com/")
.addConverterFactory(GsonConverterFactory.create());
Retrofit retrofit = builder.client(httpClient.build()).build();
client = retrofit.create(GitHubClient.class);
// Now make the request and process the response
GitHubUpdateFileRequest request = new GitHubUpdateFileRequest();
client.updateConfigFile(request).enqueue(new Callback<GitHubUpdateFileResponse>() {
#Override
public void onResponse(Call<GitHubUpdateFileResponse> call, Response<GitHubUpdateFileResponse> response) {
int responseCode = response.code();
// More code on successful update
}
#Override
public void onFailure(Call<GitHubUpdateFileResponse> call, Throwable t) {
Log.e("MainActivity", "Unable to update file" + t.getLocalizedMessage());
}
});
What currently happens:
Currently, the success callback is triggered, but with a response code of 404 like so:
Response{protocol=http/1.1, code=404, message=Not Found, url=https://api.github.com/repos/blakewilliams1/blakewilliams1.github.io/contents/qr_config.json}
Has anyone else encountered this? I first thought it was a problem with including '/content/' in the URL but I do the same thing for reading the file contents request and it works fine (also uses same URL just a GET instead of PUT).
For anyone interested in doing this in the future, I figured out the solution.
I needed to revise the request object structure
Rather than using an authentication interceptor, I instead added an access token to the header. Here is where you can create access tokens for Github, you only need to grant it permissions to the 'repos' options for this use case to work.
This is what my updated request object looks like:
public class GitHubUpdateFileRequest {
public String message;
public String content;
public String sha;
public final Committer committer = new Committer();
public GitHubUpdateFileRequest(String unencodedContent, String message, String sha) {
this.message = message;
this.content = Base64.getEncoder().encodeToString(unencodedContent.getBytes());
this.sha = sha;
}
private static class Committer {
final String name = "yourGithubUsername";
final String email = "email#yourEmailAddressForTheUsername.com";
}
}
Then from my code, I would just say:
GitHubUpdateFileRequest updateRequest = new GitHubUpdateFileRequest("Hello World File Contents", "This is the title of the commit", shaOfExistingFile);
For using this reqest, I updated the Retrofit client implementation like so:
// https://docs.github.com/en/rest/reference/repos#create-or-update-file-contents
#Headers({"Content-Type: application/vnd.github.v3+json"})
#PUT("/repos/yourUserName/yourRepository/subfolder/path/to/specific/file/theFile.txt")
Call<GitHubUpdateFileResponse> updateConfigFile(
#Header("Authorization") String authorization, #Body GitHubUpdateFileRequest request);
And I call that interface like this:
githubClient.updateConfigFile("token yourGeneratedGithubToken", request);
And yes, you do need the prefix "token ". You could hardcode that header into the interface, but I pass it in so that I can store it in locations outside of my version control's reach for security reasons.

Android Java: Retrofit2 + google api auth with email and password gives 404

I've implemented auth with Firestore and it works fine and now redoing it via Google API and get http status "404" and empty message:
D/RESPONSE FIREBASE: Response{protocol=h2, code=404, message=, url=https://identitytoolkit.googleapis.com/v1/accounts/signInWithPassword?key=000080511101}
Network service:
public class NetworkService {
private static NetworkService instance;
private static final String BASE_URL
= "https://identitytoolkit.googleapis.com/v1/";
private Retrofit retrofit;
private NetworkService() {
retrofit = new Retrofit.Builder()
.baseUrl(BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.build();
}
public static NetworkService getInstance() {
if (instance == null) {
instance = new NetworkService();
}
return instance;
}
public PlaceHolderApi getJsonApi() {
return retrofit.create(PlaceHolderApi.class);
}
}
Api
public interface PlaceHolderApi {
#FormUrlEncoded
#POST("accounts/signInWithPassword")
Call<Transaction.Result> loginWithEmail(
#Query("key") String key,
#Field("email") String email,
#Field("password") String password,
#Field("returnSecureToken") boolean returnSecureToken
);
}
Usage:
NetworkService.getInstance()
.getJsonApi().loginWithEmail("000080511101", email, password, true)
.enqueue(new Callback<Transaction.Result>() {
#Override
public void onResponse(Call<Transaction.Result> call, Response<Transaction.Result> response) {
Log.d("RESPONSE FIREBASE", response.toString());
Log.d("RESPONSE MESSAGE", response.message());
}
#Override
public void onFailure(Call<Transaction.Result> call, Throwable t) {
t.printStackTrace();
}
});
Documentation says that I should use Content type application/JSON, but how to use it here or pass it via http using retrofit?
Any directions will be helpful.
Thanks!
UPD: Console query result
The real issue was because of colon symbol inside url ":", so url should start from dot and slash symbols "./":
#POST("./accounts:signInWithPassword")
Found this on github and it helps https://github.com/square/retrofit/issues/2730
UPD: A little explanation why I used url like "accounts/signInWithPassword" with slash symbol inside instead of colon symbol: I tried with colon first, but got an error "Malformed url" so I dug a bit deeper with that mistake :)
You can add a header like this. But I think if you miss the header response, the error code wouldn't be 404.
Anyway, try this.
#FormUrlEncoded
#Headers({"Content-Type: application/json"})
#POST("accounts/signInWithPassword")
Call<Transaction.Result> loginWithEmail(
#Query("key") String key,
#Field("email") String email,
#Field("password") String password,
#Field("returnSecureToken") boolean returnSecureToken
);

Call Retrofit without having Value

how to call Retrofit GET method api in which no value will pass in GET(")
this is my code
#GET(" ")
fun fetchData(): Call<List<Data>>
this is my BASE URL https://abhi-debug.github.io/Caption/All
and it cant have backslash at end
#GET(".")
fun fetchData(): Call<List<Data>>
Pass "." as the parameter
My suggestion would be to have a base URL like: https://abhi-debug.github.io/
And then add this:
#GET("Caption/All")
fun fetchData(): Call<List<Data>>
Solution 1
You can use #GET(".") to indicate that your url is the same as the base url.
#GET(".")
Call<List<Data>> fetchData();
Solution 2
You can pass URL to reuest as you mention you got URL in json response
#GET()
Call<List<Data>> fetchData(#Url String url);
and call
Call<List<Data>> call = retrofitInterface.fetchData("https://abhi-debug.github.io/Caption/All");
call.enqueue(new Callback<List<Data>>() {
#Override
public void onResponse(Call<List<Data>> call, Response<List<Data>> response) {
Log.i(TAG, response.body().toString());
List<Data> body = response.body();
Log.i(TAG, body.get(0).getId()+"");
}
#Override
public void onFailure(Call<List<Data>> call, Throwable t) {
// Log error here since request failed
Log.e(TAG, t.toString());
}
});
In your Api Interface use this method
#GET
Call<JsonObject> fetchData(#Url String config);

whenever i acces data from network using retrofit it works fine but in 2nd time can't find data through network using retrofit

I am trying to access data from the network (data is in the form of gson and i am using WordPress rest API) using retrofit but can't access. it shows me an error like data is null looks like retrofit can't find data but everything is good... looks like code is good and i don't know how to solve this. please help me I am a new developer.. it takes my 3 days
whenever i call getRetrofit() method it works fine... but when i call getImageRetrofit() then looks like this method won't work...this method return null value as shown in the logcat :
ImageInfo: info: null
private void getRetrofit() {
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(baseUrl)
.addConverterFactory(GsonConverterFactory.create())
.build();
RetrofitArrayApi service = retrofit.create(RetrofitArrayApi.class);
Call<List<WPPost>> call = service.getPostInfo();
call.enqueue(new Callback<List<WPPost>>() {
#Override
public void onResponse(Call<List<WPPost>> call, Response<List<WPPost>> response) {
Log.e("Latest","response: "+response.body());
for (int i=0; i<response.body().size(); i++)
{
Log.e("main ","title "+response.body().get(i).getTitle().getRendered() + " " +
response.body().get(i).getId() );
String tempDate = response.body().get(i).getDate();
tempDate = tempDate.replace("T"," ");
String tempImageHref = response.body().get(i).getLinks().getWpFeaturedmedia().get(0).getHref();
Log.e("Href", "onResponse: "+tempImageHref);
String link = response.body().get(i).getLink();
Log.e("PostLink",link);
getImageRetrofit(tempImageHref);
list.add(new LatestModel(
response.body().get(i).getTitle().getRendered(),
tempDate,
tempImageHref,
LatestModel.IMAGE_TYPE,
response.body().get(i).getLink()
)
);
}
adapter.notifyDataSetChanged();
}
#Override
public void onFailure(Call<List<WPPost>> call, Throwable t) {
t.printStackTrace();
}
});
}
private void getImageRetrofit(String ImageHref) {
Log.e("getImageRetrofit","called "+ImageHref);
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(baseUrl)
.addConverterFactory(GsonConverterFactory.create())
.build();
RetrofitArrayApi service = retrofit.create(RetrofitArrayApi.class);
Call<List<WPPostImage>> callImage = service.getImageInfo(ImageHref);
callImage.enqueue(new Callback<List<WPPostImage>>() {
#Override
public void onResponse(Call<List<WPPostImage>> call, Response<List<WPPostImage>> response) {
Log.e("ImageInfo","info: "+response.body());
}
#Override
public void onFailure(Call<List<WPPostImage>> call, Throwable t) {
Log.e("Link Failed: ",": t.printStackTrace()" );
}
});
}
here is my RetrofitArrayApi Interface.:
public interface RetrofitArrayApi {
#GET("wp-json/wp/v2/posts?per_page=4")
Call<List<WPPost>> getPostInfo();
#GET("{id}")
Call<List<WPPostImage>> getImageInfo(#Path("id") String ImageHref); }
You said at comments that temImageHref: mubashirsaddique.com/wp-json/wp/v2/media/1780 and also your base url is baseUrl = "mubashirsaddique.com". So you send a request to this address mubashirsaddique.com/mubashirsaddique.com/wp-json/wp/v2/media/1780 when call getImageInfo.
Change your getPostInfo service. It should return just id(1780 in your case) as href value and modify RetrofitArrayApi.
#GET("wp-json/wp/v2/media/{id}")
Call<List<WPPostImage>> getImageInfo(#Path("id") String ImageHref);

Passing one parameter reffering to another - accessing REST method from Android

In my Android app I connect through REST to Delphi application on Firebird server using Retrofit.
There is REST method "SelectSQL" which takes two parameters: String and TJSONObject.
For example:
select name from employee where employee_id=:id
{"id":10001}
This is part of interface where I declare methods: I used string and JSONObject.
#POST("datasnap/rest/TstBaseMethods/SelectSQL/{param,param2}")
Call<Logowanie> selectSQL(#Header("Authorization") String credentials, #Query("param") String param, #Query("param2") JSONObject param2 );
In my MainActivity.java I use:
Gson gson = new GsonBuilder()
.setLenient()
.create();
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(BASE_URL)
.addConverterFactory(GsonConverterFactory.create(gson))
.build();
StreamREST gerritAPI = retrofit.create(StreamREST.class);
String dane = Credentials.basic("admin","admin");
JSONObject obj = new JSONObject();
try {
obj.put("NAGL",11101);
String dd = obj.toString();
Call<Logowanie> sql = gerritAPI.selectSQL(dane,"select n.datadok from nagl n where n.id_nagl=:NAGL",obj);
sql.enqueue(new Callback<Logowanie>() {
#Override
public void onResponse(Call<Logowanie> call, Response<Logowanie> response) {
if(response.isSuccessful()) {
Logowanie log = response.body();
String result = log.result[0];
intent.putExtra(EXTRA_MESSAGE,generujWynik(log));
startActivity(intent);
} else {
System.out.println(response.toString());
}
}
#Override
public void onFailure(Call<Logowanie> call, Throwable t) {
System.out.println(t.getMessage() );
}
});
} catch (JSONException e) {
e.printStackTrace();
}
The problem is Retrofit doesn't properly encodes second parameter. When I launch app, I get message about bad second parameter and URL looks like that:
http://192.168.94.155:9000/datasnap/rest/TstBaseMethods/SelectSQL/%7Bparam,param2%7D?param=select%20n.datadok%20from%20nagl%20n%20where%20n.id_nagl%3D:NAGL&param2={%22NAGL%22:11101}
You can see: "param2={%22NAGL%22:11101}" where param2 looks like:
{"NAGL":11101}
Brackets and "" aren't encoded. Where is my mistake? I admit these are my first steps with Android and REST with Stackoverflow as well, but I've already made basics: I launched basic REST method and it worked. Now is problem for me.
If I didn't include important parts of my code, just tell me and I will do it.
I can add that it's about DataSnap REST from Embarcadero.
Problem solved. It turned out that I had to use #Body Retrofit annotation as this parameter should go in body of the request.

Categories

Resources