I'm testing API endpoints. The problem is when I check on Swagger, it returns a valid token, but in my testing it returns NULL. Can you point out where I'm doing the wrong thing?
public static void createOrganization() {
Map<String, String> org = new HashMap();
org.put("directorName", "name");
org.put("email", "email#gmail.com");
org.put("website", "www.site.com");
org.put("phoneNumber", "000111");
String registrationToken = given().
contentType("application/json").
body(org).
when().
post("/v3/organizations").
then().
extract().path("registrationToken");
System.out.println("Token: "+ registrationToken);
Output: Token: null
UPDATE:
Maybe I'm using extract() incorrectly, maybe there's a different solution to use the generated values later. Since for registerDevice() I'm getting NULL as well.
public static void registerDevice(){
String clientDeviceId =
given().
param("phoneNumber", "000111").
param("model", "samsung").
param("platform", "0").
param("push_token",SenimEnvironmentVars.testPushToken).
param("uuid", SenimEnvironmentVars.testUUID).
param("version", "7.1").
when().
post("/v3/user-devices").
then().
contentType("application/json").
extract().path("clientDeviceId");
System.out.println("Device ID: "+ clientDeviceId); //also prints NULL
}
Is there any other ways to generate tokens, device IDs etc. and use them later?
As documentation says
You can extract values from the response or return the response
instance itself after you've done validating the response by using the
extract method
So try to write after then some validating method like contentType(JSON).
Related
I am trying to automate twitter API. when tried to print "js.get("text") using
System.out.println(js.get("text")); I am getting error as
"The method println(boolean) is ambiguous for the type PrintStream"
I downloaded jars and passed in Build path as well "scribejava-apis-2.5.3" and "scribejava-core-4.2.0"
Below code is not allowing me use println for ------>js.get("text")
public class Basicfunc {
String Consumerkeys= "**************";
String Consumersecretkeys="*******************";
String Token="*******************";
String Tokensecret="***************************";
#Test
public void getLatestTweet(){
RestAssured.baseURI = "https://api.twitter.com/1.1/statuses";
Response res = given().auth().oauth(Consumerkeys, Consumersecretkeys, Token, Tokensecret).
queryParam("count","1").
when().get("/home_timeline.json").then().extract().response();
String response = res.asString();
System.out.println(response);
JsonPath js = new JsonPath(response);
System.out.println(js.get("text"));
}
}
Use System.out.println(js.getString("text")); instead of System.out.println(js.get("text"));, because get returns any primitive value.
I think your problem is that your twitter response is actually a list.
Try to use System.out.println(js.getList()[0].get("text")); and be aware that you are only using the first [0] entry and ignoring the rest.
I tried to send POST request with some parameters. For this I form MultivaluedMap
if I make this adding to MultivaluedMap
String ban = subscriber.getBan();
String username = user.getUsername();
postData.add("agent", username);
postData.add("datasource", "online");
postData.add("accountId", ban);
String json = RESTUtil.doPost(url, postData);
All work fine
but if I make this
postData.add("agent", user.getUsername());
postData.add("datasource", "online");
postData.add("accountId", subscriber.getBan());
String json = RESTUtil.doPost(url, postData);
I have error:
com.sun.jersey.api.client.ClientHandlerException: java.lang.ClassCastException: java.lang.String cannot be cast to java.util.List
It is my post method
public static String doPost(String url, MultivaluedMap formData) {
try {
Client client = Client.create();
WebResource wr = client.resource(url);
client.setConnectTimeout(CONNECTION_TIMEOUT);
client.setReadTimeout(READ_TIMEOUT);
ClientResponse response2 = wr
.accept("application/json;")
.type("application/x-www-form-urlencoded; charset=UTF-8")
.post(ClientResponse.class, formData);
if (response2.getStatus() != 200) {
throw new RuntimeException("Failed : HTTP error code : " + response2.getStatus());
}
return response2.getEntity(String.class);
} catch (Exception e) {
LOG.log(Level.WARNING, "callRestUrl:", e);
JsonObject jo = new JsonObject();
jo.addProperty("resultCode", "EXCEPTION");
jo.addProperty("details", e.getMessage());
return GSON.toJson(jo);
}
}
And in second case I get error after .post(ClientResponse.class, formData);
I do not understand what is wrong. subscriber.getBan() and user.getUsername() return String like ban and username, but if I use the getter, a have error.
And part 2. I found this article this article
but I do not understand when to use add or put and their difference?
Can you explicit how you create your instance of MultivaluedMap? How are you using it?
MultivaluedMap is a couple of key (single value) and value (list of objects). See the declaration:
public interface MultivaluedMap<K,V> extends Map<K,List<V>>
I suppose both of your snippets are used sequentially in the same piece of code. I the first case, you initialise the value for the key 'ban' (that's mean: the value is a list of one element), in the second case, you add a value to the list to the same key 'ban'. It happens exactly the same for the key 'username'.
I your first case, Java automatically catch the list (of one value) to a string, after the second add, this cannot be the case.
To verify it, you can simply change the order (do first your second case, then the first one). You should get the same error, after the second.
To resolve your case, consider using the method putSingle instead of add if you want to "update/replace" the value, or re-initiate your instance of formData (formData = new ...) before using it another time.
I finally figured out how to get the List out of the XML. The Rest Assured site however didn't go over how to make a assertion for the list I got. How do I assert This movie has bruce willis as a actor with the rest assured format of given, when, then? Do I use the List in the given()?
#Test
public void verifyBruceWillisIsInDieHard() {
String xmlPath = get(
"http://www.omdbapi.com/?t=Die+Hard&y=&plot=short&r=xml")
.andReturn().body().asString();
XmlPath actor = new XmlPath(xmlPath);
actor.setRoot("movie");
List<String> nameOfFirstActor = actor.getList("movie.#actors");
System.out.println(nameOfFirstActor);
Something like this perhaps?
when().
get("http://www.omdbapi.com/?t=Die+Hard&y=&plot=short&r=xml").
then().
body("movie.#actors", hasItem("bruce willis"));
With a little tweaking to your answer this worked.
when().
get("http://www.omdbapi.com/?t=Die+Hard&y=&plot=short&r=xml").
then().
body("root.movie.#actors", containsString("Bruce Willis"));
public interface UserService {
#POST(Constants.Api.URL_REGISTRATION)
#FormUrlEncoded
BaseWrapper registerUser(#Field("first_name") String firstname, #Field("last_name") String lastname, #Field("regNumber") String phone, #Field("regRole") int role);
public BaseWrapper registerUser(User user) {
return getUserService().registerUser(user.getFirstName(), user.getLastName(), user.getPhone(), user.getRole());
}
This create Exception
com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected BEGIN_OBJECT but was STRING at line 1 column 1 path $
Big thanks for help.
Let's look at the error you are receiving.
Expected BEGIN_OBJECT
Your JSON is an object, and all JSON objects are enclosed in curly braces ({}). BEGIN_OBJECT is therefore {. And it's expecting it somewhere.
but was STRING
But instead he found a string "Something". Still doesn't tell us where.
at line 1 column 1 path $
Ah, perfect. At line 1 column 1. Which is the start of the JSON. So you have forgotten to enclose the whole thing in {} (or at least you have forgotten the first one, but I bet you've forgotten them both).
Recently i'd faced similiar issue and solutioned only by adding "Accept: application/json" into header section. So, if you're using retrofit 2.0;
1st solution: For post method add headers parameter like below;
#Headers({"Accept: application/json"})
#POST(Constants.Api.URL_REGISTRATION)
#FormUrlEncoded
BaseWrapper registerUser(#Field("first_name") String firstname,
#Field("last_name") String lastname,
#Field("regNumber") String phone,
#Field("regRole") int role);
2nd solution: Add header into your interceptor class like this;
NB: Code is in kotlin
private fun getInterceptor(): Interceptor {
try {
return Interceptor {
val request = it.request()
it.proceed(
request.newBuilder()
.header("Accept", "application/json")
.header("Authorization", "$accessTokenType $accessToken")
.build()
)
}
} catch (exception: Exception) {
throw Exception(exception.message)
}
}
}
Hope it helps, happy coding :)
Cleaning and rebuilding the project works for me.
If you want to add the ArrayList in the json object and parse in GSON then make sure the ArrayList should be like below.
ArrayList<JSONObject>
Instead of
ArrayList<String>
and Parse like this.
ArrayList<JSONObject> mItem = new ArrayList<JSONObject>();
mItem.add(jsonObject);
// and Use like this.
JSONArray list = new JSONArray(mItem);
jsonObject.put("Item",list);
If your app was using stored data from previous version and you changed the data type, you may encounter this error.
For example: I had something stored as a String in my previous version. I later updated the class that had the data stored in it to an object type. When I ran it, I got this error. After clearing the app-data or re-installing it, the error cleared.
Clearing the app-data might be an easy fix.
SOLUTION
In Kotlin we can use Response of ResponseBody and manage the initial response within it.
viewModelScope.launch(Dispatchers.IO) {
mainRepository.getAPIData(
Constants.getRequestBody(requestBody.toString())
).let { it ->
if (it.isSuccessful && it.code() == 200) {
val responseBody = it.body()
val res: String? = responseBody?.string()
try {
val main = JSONObject(res!!)
Log.e("TAG", "onSuccess: " + main.toString())
if (main.getInt("StatusCode") == 200) {
val type = object : TypeToken<Response>() {}.type
val response: Response = Gson().fromJson(
main.toString(), type
)
Log.e("TAG", "onSuccess: " + response.toString())
} else {
apiResponseData.postValue(Resource.error(main.getString("Message"), null))
Log.e("TAG", "onFail: " + main.toString())
}
} catch (exception: JSONException) {
Log.e("TAG", "Exception: " + exception.message)
}
}
}
}
Response - Retrofit
ResponseBody - okHttp
Response is actual model Response e.g. UserResponse
Here, getAPIData() is API call which returns Response of ResponseBody
apiResponseData is MutableLiveData
using this you can avoid JSON type cast error in response.
It's a proguard problem. In release minifyEnabled true broke the API models.
You need to add Serializable in ResponseModel and in RequestModel API
https://i.stack.imgur.com/uHN22.png
i would like to make a simple HTTP GET with the PlayFramework (java) but it doesn't work. I've googled a lot an read in the documentation of play 2.x but nothing helped me. The examples in the documentation also did not help.
i would like to write a method which calls the reverse geoconding service (for example this) and gives the JSON data back. I need the response data as JsonNode or something like that.
i tried the following piece of code from the play homepage which should give back the name of a road, but it did not work.
public static Promise<Result> reverseLookup() {//String lat, String lon
final Promise<Result> resultPromise = WS.url("http://nominatim.openstreetmap.org/reverse?format=json&lat=51.510809&lon=-0.092875").get().map(
new Function<WS.Response, Result>() {
public Result apply(WS.Response response) {
return ok("Road:" + response.asJson().findPath("road"));
}
}
);
return resultPromise;
}
I got this error here:
[RuntimeException: com.fasterxml.jackson.core.JsonParseException: Unexpected character ('<' (code 60)): expected a valid value (number, String, array, object, 'true', 'false' or 'null') at [Source: org.jboss.netty.buffer.ChannelBufferInputStream#6a43dbaf; line: 1, column: 2]]
there isn't any character like "<" in the JSON data if this url is called manually in the browser.
Please help me. I don't get it.
EDIT 10:25 PM:
i tried response.getBody() but the output is the same.
I don't understand where the error could be...
Here is more code:
routes:
POST /other/function controllers.myController.anotherFunction()
myController:
private static String reverseLookupData;
#BodyParser.Of(play.mvc.BodyParser.Json.class)
public static Result anotherFunction() {
// the gps coordinates are passed to this method (this works up to this point)
reverseLookup(String lat, String lon); // reverse lookup starts
System.out.println("Response 1: " + reverseLookupData);
System.out.println("Response 2: " + reverseLookup().toString());
// some code ...
}
public static Promise<String> reverseLookup(String lat, String lon) {
final Promise<String> resultPromise = WS.url("http://nominatim.openstreetmap.org/reverse?format=json&lat="+ lat +"&lon=" + lon).get().map(
new Function<WS.Response, String>() {
public String apply(WS.Response response) {
reverseLookupData = response.getBody();
return "Data:" + reverseLookupData;
}
}
);
return resultPromise;
}
If i run this code the output to the command-line window is:
Response 1: null
Response 2: play.libs.F$Promise#51ebebed
EDIT
(...)
public String apply(WS.Response response) {
System.out.println("Body: " + response.getBody());
return "";
}
(...)
Now i got this error message here:
Body: <?xml version="1.0" encoding="UTF-8" ?>
<reversegeocode timestamp='Sun, 06 Apr 14 21:31:45 +0000' attribution='Data ┬® OpenStreetMap contributors, ODbL 1.0. http://www.openstreetmap.org/copyright' querystring=''>
<error>Unable to geocode</error></reversegeocode>
Anybody an idea why this appears or where the error could be?
As I said, when I put the geocoding address in the browser, then I get a correct answer.
i tried googles reverse geocoding but that also does not work
url:
"http://maps.googleapis.com/maps/api/geocode/json?latlng=51.510809,-0.092875&sensor=false&key={myServerKey}",
"http://maps.googleapis.com/maps/api/geocode/json?latlng=51.510809,-0.092875&sensor=false"
sensor true or false, nothing works:
Body: {
"error_message" : "The 'sensor' parameter specified in the request must be set to either 'true' or 'false'.",
"results" : [],
"status" : "REQUEST_DENIED"
}
I'm grateful for any help :)
WS.url("http://nominatim.openstreetmap.org/reverse")
.withQueryParameter("format", "json")
.withQueryParameter("lat", lat)
.withQueryParameter("lon", lon)