Retrofit PUT doesn't work - java

I am developing an Android application using "Discord API".
First, if I call the same API in Postman, it works fine.
But in my android application, it doesn't work.
The API what I want to use is this: "https://discordapp.com/developers/docs/resources/guild#add-guild-member"
And I want to do the same thing in my Android application using "Retrofit Library".
Below is the interface.
#PUT("guilds/{guildId}/members/{userId}")
Call<RespUser> joinGuild(#Path("guildId") String guildId, #Path("userId") String userId, #Header("Authorization") String token, #Header("Content-Type") String contentType, #Body String body);
And below is implement:
#Override
public void joinGuild(DUser dUser, String authorization) {
Log.d(TAG, "[CHICKEN] joinGuild: " + dUser + ", " + authorization);
Gson gson = new Gson();
String body = gson.toJson(new DJoinBody(authorization, dUser.getUsername()));
Log.d(TAG, "[CHICKEN] joinGuild - body: " + body);
Call<RespUser> guildCall = mDiscordService.joinGuild(BuildConfig.DISCORD_GROUP_ID, dUser.getId(), BuildConfig.DISCORD_BOT_TOKEN, "application/json", body);
Log.d(TAG, "[CHICKEN] joinGuild - request method: " + guildCall.request().method());
Log.d(TAG, "[CHICKEN] joinGuild - request headers: " + guildCall.request().headers().toString());
Log.d(TAG, "[CHICKEN] joinGuild - request body.contentType: " + guildCall.request().body().contentType().toString());
Log.d(TAG, "[CHICKEN] joinGuild - request body.: " + guildCall.request().body().toString());
Log.d(TAG, "[CHICKEN] joinGuild - request: " + guildCall.request().toString());
guildCall.enqueue(new Callback<RespUser>() {
#Override
public void onResponse(Call<RespUser> call, Response<RespUser> response) {
if (response.isSuccessful()) {
RespUser result = response.body();
Log.d(TAG, "[CHICKEN] joinGuild - result: " + result);
} else {
try {
Log.e(TAG, "[CHICKEN] joinGuild - failed: " + response.code() + ": " + response.errorBody().string());
Log.d(TAG, "[CHICKEN] joinGuild - failed: " + response.raw().toString());
Log.d(TAG, "[CHICKEN] joinGuild - failed: " + response.headers().toString());
} catch (IOException e) {
e.printStackTrace();
}
}
}
#Override
public void onFailure(Call<RespUser> call, Throwable t) {
}
});
}
And the error is:
{"_misc": ["Only dictionaries may be used in a DictType"]}
Could you tell me what I do mistake, please?

I found the solution.
I changed the "Body" parameter's type from "String" to "Object".
Before code:
#PUT("guilds/{guildId}/members/{userId}")
Call<RespUser> joinGuild(#Path("guildId") String guildId,
#Path("userId") String userId,
#Header("Authorization") String token,
#Header("Content-Type") String contentType,
#Body String body);
After code:
#Headers({"Content-Type: application/json"})
#PUT("guilds/{guildId}/members/{userId}")
Call<RespUser> joinGuild(#Path("guildId") String guildId,
#Path("userId") String userId,
#Header("Authorization") String token,
#Body DJoinBody joinBody);

Related

ApolloQueryCall Test in java

I am trying to test onResponse method. If I understand korrectly, when I call apolloQueryCall.enqueue , it should return response as response. When I run this code, it does not enter neither onResponse or onFailere. What am I missing? I could not find examples that work for me on the internet for Java.
String body = "{\n" +
" \"data\": {\n" +
" \"message\": \"kedi\"\n" +
" }\n" +
"}";
MockWebServer webServer = new MockWebServer();
MockResponse response = new MockResponse().setResponseCode(200).setBody(body);
webServer.enqueue(response);
var apolloClient = ApolloClient.builder()
.serverUrl(webServer.url("http://localhost/mock"))
.okHttpClient(okHttpClient)
.build();
var apolloQueryCall = apolloClient.query(query);
apolloQueryCall.enqueue(new ApolloCall.Callback<MyClass.Data>() {
#Override
public void onResponse(#NotNull Response<MyClass.Data> response) {
System.out.println("response:" + response);
}
#Override
public void onFailure(#NotNull ApolloException e) {
System.out.println(e.getMessage());
}
});
webServer.close();

How do I get a value from such a JSON Response

This is What i get as a response from the PlacesApi after making a request.
But the issue is that i cant get the value of "photo_reference".
The issue is also the Objects being in Arrays and all , the whole response looks confusing.
Below is what i have tried in android studio Java
private void getUserLocationImage(String mLocationName) {
String url = "https://maps.googleapis.com/maps/api/place/findplacefromtext/json?input="+mLocationName+"&inputtype=textquery&fields=photos&key="+R.string.google_api;
// prepare the Activities Request
JsonObjectRequest getWeatherRequest = new JsonObjectRequest(Request.Method.GET, url, null,
new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
try {
JSONArray dataArray = response.getJSONArray("candidates");
JSONObject photosObj = dataArray.getJSONObject(0);
JSONArray photosArray = photosObj.getJSONArray("photos");
JSONObject photoRefObj = photosArray.getJSONObject(0);
String imageRef = photoRefObj.get("photo_reference").toString();
Toast.makeText(HomeLandingPageActivity.this, ""+imageRef, Toast.LENGTH_SHORT).show();
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Log.d("Error.Response", error.toString());
}
});
// add it to the RequestQueue
queue.add(getWeatherRequest);
}
This is the Error
org.json.JSONException: Index 0 out of range [0..0)
This is what the response is in the Web
{
"candidates" : [
{
"photos" : [
{
"height" : 4160,
"html_attributions" : [
"\u003ca href=\"https://maps.google.com/maps/contrib/111684034547030396888\"\u003eCaroline Wood\u003c/a\u003e"
],
"photo_reference" : "CmRaAAAAQkMptoZgWJHING5qIR5_abXvnxjhHHEOHmDRH3ZpXUrar5PfpN5tQhhPoPwYmTDjpdVmXeT3T9klnrdK4xMvuudPm309UxMcx_ddbiu6E4shWYaPFn4gO4Diq4mOM46EEhCoo3TLpUbrWhInjelgVtYZGhSDJPyoRefWJ8WIcDs8Bk8VXAwHyQ",
"width" : 3120
}
]
}
],
"status" : "OK"
}
Try to use Gson library for deserilization your response. http://tutorials.jenkov.com/java-json/gson.html
It's very simple way to get any values from response
At first need create class with response model
import java.util.List;
public class ResponseBody {
public List<Candidates> candidates;
public static class Candidates {
public List<Photos> photos;
public static class Photos {
public int height;
public int width;
public String photo_reference;
public List<String> html_attributions;
}
}
}
Then just get your response as String and deserilize it:
String json = "{\n" +
" \"candidates\" : [\n" +
" {\n" +
" \"photos\" : [\n" +
" {\n" +
" \"height\" : 4160,\n" +
" \"html_attributions\" : [\n" +
" \"\\u003ca href=\\\"https://maps.google.com/maps/contrib/111684034547030396888\\\"\\u003eCaroline Wood\\u003c/a\\u003e\"\n" +
" ],\n" +
" \"photo_reference\" : \"CmRaAAAAQkMptoZgWJHING5qIR5_abXvnxjhHHEOHmDRH3ZpXUrar5PfpN5tQhhPoPwYmTDjpdVmXeT3T9klnrdK4xMvuudPm309UxMcx_ddbiu6E4shWYaPFn4gO4Diq4mOM46EEhCoo3TLpUbrWhInjelgVtYZGhSDJPyoRefWJ8WIcDs8Bk8VXAwHyQ\",\n" +
" \"width\" : 3120\n" +
" }\n" +
" ]\n" +
" }\n" +
" ],\n" +
" \"status\" : \"OK\"\n" +
"}";
Gson gson = new Gson();
ResponseBody responseBody = gson.fromJson(json, ResponseBody.class);
System.out.println("responseBody = " + responseBody.candidates.get(0).photos.get(0).photo_reference);
I got this:
responseBody = CmRaAAAAQkMptoZgWJHING5qIR5_abXvnxjhHHEOHmDRH3ZpXUrar5PfpN5tQhhPoPwYmTDjpdVmXeT3T9klnrdK4xMvuudPm309UxMcx_ddbiu6E4shWYaPFn4gO4Diq4mOM46EEhCoo3TLpUbrWhInjelgVtYZGhSDJPyoRefWJ8WIcDs8Bk8VXAwHyQ

How to read JSON from file and replace objects with value?

I need to read JSON from file and replace few objects.
For example, I have class User.java
public class User {
String username;
String email;
String city;
String code;
}
and JSON:
{
"variables":
{
"user":
{
"value":
{
"username": "$USERNAME",
"email": "$EMAIL",
"city": "$CITY"
}
}
}
}
I have two questions:
How can I read JSON from file? Read JSON will be send by WebClient POST API.
How can I replace $USERNAME, $EMAIL and $CITY? I won't hardcode it.
I have register form. When someone complete form, it will be replaced for $...
Firsty, I got hardcode JSON to string but I need read it from file
class JSONClass {
static String toFormat(User user) {
String jsonUserRegister = "{\n" +
" \"variables\":\n" +
" {\n" +
" \"user\": \n" +
" {\n" +
" \"value\":\n" +
" {\n" +
" \"username\": \"" + user.getUsername() + "\",\n" +
" \"email\": \"" + user.getEmail() + "\",\n" +
" \"city\": \"" + user.getCity() + "\",\n" +
" \"code\": \"" + user.getCode() + "\"\n" +
" } }\n" +
" }\n" +
"}";
return jsonUserRegister;
This can be achieved using Spring Boot to set up the backend to receive client calls. So to get Task 1a working, we need below
#RestController
public class JsonReaderController {
#Autowired
private ResourceLoader resourceLoader;
#PostMapping(value = "/read-json")
public String fileContent() throws IOException {
return new String(Files.readAllBytes(
resourceLoader.getResource("classpath:data/json- sample.json").getFile().toPath()));
}
}
Above code simply reads file content and returns as String. Note default response is Json.
Now that we have the backend done, we need Task 1b - Sending the POST request.
private String readJsonFile() throws IOException {
final OkHttpClient client = new OkHttpClient();
final String requestUrl = "http://localhost:8080/read-json";
Request request = new Request.Builder()
.url(requestUrl)
.post(RequestBody.create(JSON, ""))
.build();
try (Response response = client.newCall(request).execute()) {
//we know its not empty given scenario
return response.body().string();
}
}
readJsonFile method makes a POST request - using OkHttp to our backend bit (done in Task 1a) and returns the content of the file as json.
And for Task 2 - replacing $USERNAME, $EMAIL and $CITY with appropriate values. For this, we will use the Apache commons-text library.
public static void main(String[] args) throws IOException {
String fileContent = new ReadJsonFromFile().readJsonFile();
User user = new User("alpha", "alpha#tesrt.com", "Bristol", "alpha");
Map<String, String> substitutes = new HashMap<>();
substitutes.put("$USERNAME", user.getUsername());
substitutes.put("$EMAIL", user.getEmail());
substitutes.put("$CITY", user.getCity());
substitutes.put("$CODE", user.getCode());
StringSubstitutor stringSubstitutor = new StringSubstitutor(substitutes);
//include double quote prefix and suffix as its json wrapped
stringSubstitutor.setVariablePrefix("\"");
stringSubstitutor.setVariableSuffix("\"");
String updatedContent = stringSubstitutor.replace(fileContent);
System.out.println(updatedContent);
}
Hope this helps.

Edit message contents in OneSignal notification Android

I am trying to change the current 'Test Message' String in a OneSignal push notification. I simply want to use a variable defined in my code, but cannot figure out how to do it.
try {
OneSignal.postNotification(new JSONObject("{'contents': ['en': 'Test Message'], 'include_player_ids': ['" + selectedUser.getOneSignalId() + "']}"),
new OneSignal.PostNotificationResponseHandler() {
#Override
public void onSuccess(JSONObject response) {
Log.i("OneSignalExample", "postNotification Success: " + response.toString());
}
#Override
public void onFailure(JSONObject response) {
Log.e("OneSignalExample", "postNotification Failure: " + response.toString());
}
});
} catch (JSONException f) {
e.printStackTrace();
}
I was able to achieve something similar in sending the notification to a selected user. Now I just want to change the text of the actual message.
Use this
String yourVaribale = " what ever you want to send"
OneSignal.postNotification(new JSONObject("{'contents': ['en': " + yourVariable + "], 'include_player_ids': ['" + selectedUser.getOneSignalId() + "']}"),
new OneSignal.PostNotificationResponseHandler() {
#Override
public void onSuccess(JSONObject response) {
Log.i("OneSignalExample", "postNotification Success: " + response.toString());
}
#Override
public void onFailure(JSONObject response) {
Log.e("OneSignalExample", "postNotification Failure: " + response.toString());
}
});
} catch (JSONException f) {
e.printStackTrace();
}
or you can try this way
String strJsonBody = "{"
+ " \"app_id\": \"ef42157d-64e7-4ce2-9ab7-15db224f441b\","
+ " \"included_segments\": [\"All\"],"
+ " \"data\": {\"foo\": \"bar\"},"
+ " \"contents\": {\"en\": \""+ description +"\"},"
+ " \"headings\": {\"en\": \""+ title +"\"},"
+ " \"big_picture\":\""+ imageurl +"\""
+ "}";
for second method follow this link
The solution below worked for me. The full name of the current user is concatenated to the string message " wants you to follow them." and is then sent to the selectedUser with the specific OneSignalID.
OneSignal.postNotification(new JSONObject("{'contents': {'en': \""+ currentUser.getFullName() +" wants you to follow them." +"\"}, 'include_player_ids': ['" + selectedUser.getOneSignalId() + "']}"),
new OneSignal.PostNotificationResponseHandler() {
#Override
public void onSuccess(JSONObject response) {
Log.i("OneSignalExample", "postNotification Success: " + response.toString());
}
#Override
public void onFailure(JSONObject response) {
Log.e("OneSignalExample", "postNotification Failure: " + response.toString());
}
});

Call WS Rest Java with AngularJS

I've a problem with call WS Rest Java. I call the WS but the parameters isn't passed.
My java code:
#POST
#Produces(MediaType.APPLICATION_JSON)
#Consumes(MediaType.APPLICATION_FORM_URLENCODED)
public Response setUser(#FormParam("name") String name, #FormParam("surname") String surname, #FormParam("email") String email,
#FormParam("phone") String phone, #FormParam("skype") String skype, #FormParam("password") String password){
try {
FileOutputStream fis = new FileOutputStream("/home/File.txt");
PrintStream ps = new PrintStream(fis);
String s = "name: "+name+"\nSurname: "+surname+"\nEmail: "+email+"\nPhone: "+phone+"\nSkype: "+skype+"\nPassword: "+password;
ps.println(s);
ps.close();
fis.close();
UserDAO userdao = new UserDAO(0,name,surname,email,phone,skype);
userdao.save();
...
return Response.status(200).entity(new ObjectMapper().writeValueAsString("OK!")).header("Access-Control-Allow-Origin", "*").build();
} catch (Exception e) {
e.printStackTrace();
return Response.status(500).entity("ERROR!").header("Access-Control-Allow-Origin", "*").build();
}
}
Angular call:
data = {
name: $scope.reg_name,
surname: $scope.reg_surname,
email: $scope.reg_email,
phone: $scope.reg_phone,
skype: $scope.reg_skype,
password: $scope.reg_password
}
$http.post(baseUrl+'user/',data,{
headers: { 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'}
});
If i log data on angular data are set, the call working but i've an error when i create AccountDAO object because the parameters are null. To test the parameters values i create a file and put here the value, the content are this:
name: null
Surname: null
Email: null
Phone: null
Skype: null
Password: null
Any one have idea why not pass the parameters?
Thanks!
Solved:
data = "name=" + $scope.reg_name +
"&surname=" + $scope.reg_surname +
"&email=" + $scope.reg_email +
"&phone=" + $scope.reg_phone +
"&skype=" + $scope.reg_skype +
"&password=" + $scope.reg_password;
}
$http.post(baseUrl+'user/',data,{
headers: { 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'}
})
Thanks grizzly!
You are sending data as JSON. Change it to form data string:
data = "name=" + $scope.reg_name +
"&surname=" + $scope.reg_surname +
"&email=" + $scope.reg_email +
"&phone=" + $scope.reg_phone +
"&skype=" + $scope.reg_skype +
"&password=" + $scope.reg_password;
}
$http.post(baseUrl+'user/',data,{
headers: { 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'}
})

Categories

Resources