**Hello! Here is the request to the server **
var stories: Story? =
given().log().all()
.contentType(ContentType.JSON)
.body(body)
.`when`().log().all()
.post(baseURI)
.then().log().all()
.extract().`as`(Story::class.java)
println (Story().title)
println (Story().id)
println (Story().items)
Here is POJO class
import com.fasterxml.jackson.annotation.JsonIgnoreProperties
#JsonIgnoreProperties(ignoreUnknown = true)
class Data {
var stories: String? = null
}
class Story() {
var id = 0
var title: String? = null
var description: String? = null
var imageUrl: String? = null
var imageUrlEco: String? = null
var images: String? = null
var style: String? = null
var styleWeb: String? = null
var link: String? = null
var linkWeb: String? = null
var linkEco: String? = null
var buttonText: String? = null
var dateFrom: String? = null
var dateTo: String? = null
var hidden: String? = null
var isAuth: String? = null
var onboardingType: String? = null
var sortOrder = 0
var type: String? = null
var items: String? = null
}
class Item {
var id = 0
var title: String? = null
var description: String? = null
var detailedDescription: String? = null
var imageUrl: String? = null
var imageUrlWeb: String? = null
var style: String? = null
var styleWeb: String? = null
var sortOrder = 0
}
**And here is the response itself **
{
"data": {
"stories": \[
{
"id": 1234,
"title": "AnyText",
"description": "AnyText",
"imageUrl": "AnyText",
"imageUrlEco": AnyText,
"images": \[
],
"style": "AnyText",
"styleWeb": "AnyText",
"link": AnyText,
"linkWeb": AnyText,
"linkEco": AnyText,
"buttonText": "AnyText",
"dateFrom": "2022-11-22T00:00:00Z",
"dateTo": "2023-01-08T00:00:00Z",
"hidden": AnyText,
"isAuth": AnyText,
"onboardingType": AnyText,
"sortOrder": 1234,
"type": "AnyText",
"items": [
{
"id": 1234,
"title": "AnyText",
"description": "AnyText",
"detailedDescription": "AnyText",
"imageUrl": "AnyText",
"imageUrlWeb": "AnyText",
"style": "AnyText",
"styleWeb": "AnyText",
"sortOrder": 1
}
]
}
]
}
}
So when I try this:
println (Story().title)
println (Story().id)
println (Story().items)
The result of running the program is:
null
0
null
What I did wrong?
I have not used RestAssured so I cannot comment on the syntax/correctness of that, but your error is incorrectly referencing the object you have deserialized from the GET request.
var stories: Story? =
this means assign the result to a variable named stories
Later you write
println (Story().title)
what this means it print the field title from a brand new Story object. You should be doing this:
println (stories.title)
println (stories.id)
println (stories.items)
(stories should be named story if it represents one)
Related
This is the response body of post method
"body":
{
"id": 538,
"Fname": "abc",
"Lname": "Xyz",
"Type": {
"Type": "tryrtyr",
"createdBy": "ytyryr",
"createdDate": "2022-07-22T09:24:37.616+00:00",
"lastModifiedBy": "rtyryry",
"lastModifiedDate": "2022-07-22T09:24:37.616+00:00"
}
}
I tried to fetch the Id value but it is showing null value.
Fname, Lname are passing from excel file.
String jsonString = response.asString();
jsonString = response.asString();
List<Map<String, Object>> body = JsonPath.from(jsonString).get("");
Object Id = null;
for (Map<String, Object> item: body) {
if (item.get("Fname").toString().equals(Fname) &&
item.get("Lname").toString().equals(Lname)); {
Id = Integer.parseInt(item.get("id").toString());
}
}
System.out.println(Id);
Since the body is json object, not array, so you don't need a List here. I think you just need.
int id = response.jsonpath().getInt("id");
I have recently started using Ktor and got stuck at the very beginning itself.
I have a very simple response, which could have content like below -
{
"result": true,
"data": [
{
"Name": "Danish",
"Credit": "80"
},
{
"Name": "Kumar",
"Credit": "310"
}
]
}
Or it could be like this -
{
"result": false,
"data": [],
"message": "No data available, use default user",
"default": [
{
"Name": "Default User",
"Credit": "100"
}
]
}
And my response class is like -
#Serializable
data class UserResponse(
#SerialName("result") var result: Boolean? = null,
#SerialName("data") var data: ArrayList<User?>? = null,
#SerialName("message") var message: String? = null,
#SerialName("default") var default: ArrayList<User?>? = null
)
#Serializable
data class UserResponse(
#SerialName("Name") var name: String? = null,
#SerialName("Credit") var credit: String? = null,
)
io.ktor.client.call.NoTransformationFoundException: No transformation found: class io.ktor.utils.io.ByteBufferChannel
And I am getting NoTransformationFoundException, I think it could be due to data object being empty, but how to fix this?
According to this, we can catch this exception, but I can't use this as I need other data to be used.
Exception looks like you haven't install Json content negotiation plugin, when creating ktor client. It should be like this:
val httpClient = HttpClient {
install(ContentNegotiation) {
json()
}
}
Then you can use this client like this:
val response: UserResponse = httpClient.get("URL").body()
How to make GroupBy result list to new Map in Webflux
There is my input list and expect result. then what should I do to make the result.
// expect
{
"timestamp": "2019-06-13T00:00:00.000",
"result": {
"first": 1,
"second": 2,
"third": 3
}
}
// input list
[
{
"timestamp": "2019-06-13T00:00:00.000",
"first": 1
},
{
"timestamp": "2019-06-13T00:00:00.000",
"second": 2
},
{
"timestamp": "2019-06-13T00:00:00.000",
"third": 3
}
]
val Flux.fromIterable(list)
.groupBy{it.timestamp}
.concatMap { groupItem ->
// here!! I want to make `group by result list to new Map``
Result(timestamp = groupItem.key()!!, Item(first = ?, second = ?, third =?))
}
I figured it out.
Flux.merge(first, second, thrid)
.groupBy { it.timestamp }
.concatMap {
it.map { item ->
val container = mutableMapOf<String, Any>()
if (item is firstEntity) {
container["first"] = item.result.count
container["timestamp"] = it.key()!!
}
if (item is secondEntity) container["second"] = item.result.count
if (item is thridEntity) container["thrid"] = item.result.count
container
}.reduce { acc, current ->
acc.putAll(current)
acc
}
}
.map {
val first = (it["first"] ?: 0) as Int
val second = (it["second"] ?: 0) as Int
val thrid = (it["thrid"] ?: 0) as Int
val timestamp = (it["timestamp"] ?: "") as String
// somthing!!
}
l am try to build simple app provide flight schedule . the problem is l have many object in json url and the array list inside of these object and l cant to get array list from objects because l got error fatal Caused by: org.json.JSONException: Value
my data json api
{
"result": {
"response": {
"airport": {
"pluginData": {
"schedule": {
"arrivals": {
"data": [
{
"flight": {
"identification": {
"id": null,
"row": 4832637003,
"number": {
"default": "ZP4801",
"alternative": null
},
"callsign": null,
"codeshare": null
}
}
}
]
}
}
}
}
}
}
}
my code for getting data json of array list
private fun handleJson (jsonString: String?){
val jsonArray = JSONArray(jsonString)
val list = ArrayList<FlightShdu>()
var x = 0
while (x < jsonArray.length()){
val jsonObject = jsonArray.getJSONObject(x)
list.add(FlightShdu(
jsonObject.getInt("id"),
jsonObject.getString("callsign")
))
x++
}
val adapter = ListAdapte(this#MainActivity,list)
flightShdu_list.adapter = adapter
}
I would normally suggest for a full structure of the JSON via data classes, as this methodology could potentially be expensive to run multiple times over and over... The following highlights a method to dig into the JSON through jsonObjects by name, and then take the final layer of "identification" and populates a data class that is serializable with the resulting object
import kotlinx.serialization.Serializable
import kotlinx.serialization.json.Json
import kotlinx.serialization.json.JsonConfiguration
import kotlinx.serialization.json.JsonDecodingException
import kotlinx.serialization.json.JsonElement
val data =
"""
{
"result": {
"response": {
"airport": {
"pluginData": {
"schedule": {
"arrivals": {
"data": [{
"flight": {
"identification": {
"id": null,
"row": 4832637003,
"number": {
"default": "ZP4801",
"alternative": null
},
"callsign": null,
"codeshare": null
}
}
}]
}
}
}
}
}
}
}
"""
#Serializable
data class FlightIdentification(
val id: Int?,
val row: String,
val number: IdentificationNumber,
val callsign: String?,
val codeshare: String?
) {
#Serializable
data class IdentificationNumber(
val default: String,
val alternative: String?
)
}
val json = Json(JsonConfiguration.Stable)
fun JsonElement?.get(name: String): JsonElement? {
return if (this == null) null
else this.jsonObject[name]
}
fun handleJson(jsonString: String) {
val obj = json.parseJson(jsonString)
val data = obj.get("result").get("response").get("airport").get("pluginData")
.get("schedule").get("arrivals").get("data")
if (data != null) {
val flight = data.jsonArray[0]
.get("flight").get("identification")
try {
val res = json.parse(FlightIdentification.serializer(), flight.toString())
println(res)
} catch (e: JsonDecodingException) {
println("Decode: ${e.message}")
}
}
}
handleJson(data)
I need to parse this information-
[
{
"artist": "12",
"image": "23"
},
{
"video_id": "12",
"video_title": "23"
},
{
"video_id": "12",
"video_title": "23"
},
{
"video_id": "12",
"video_title": "23"
},
{
"video_id": "12",
"video_title": "23"
},
{
"video_id": "12",
"video_title": "23"
}]
As you can see the first field is different, how to parse below information differently and the first field differently in Kotlin.
I am parsing 1st part as-
response ->
for (i in 0..(response.length() -1)){
/**
FIRST SONG
**/
val song = response.get(0).toString()
val listOfSongs = response.toString()
val parser = Parser()
val stringBuilder = StringBuilder(song)
val json: JsonObject = parser.parse(stringBuilder) as JsonObject
val firstArtist = json.string("artist")
val firstImage = json.string("image")
val intent = Intent(activity,ResultPage::class.java)
intent.putExtra("firstArtist",firstArtist)
intent.putExtra("firstImage",firstImage)
startActivity(intent)
/**
FIRST SONG
**/
}
}
and am also using KLAXON library here.
For your json, this should work :
fun parseResponse(response: String) {
var artist = ""
var image = ""
val videoList = ArrayList<Video>()
val jsonArray = JSONArray(response)
(0..5).forEach { index ->
val jsonObject = jsonArray.getJSONObject(index)
if (jsonObject.has("artist") && jsonObject.has("image")) {
artist = jsonObject.getString("artist")
image = jsonObject.getString("image")
}
else if (jsonObject.has("video_id") && jsonObject.has("video_title")) {
val newVideo = Video(jsonObject.getString("video_id"), jsonObject.getString("video_title"))
videoList.add(newVideo)
}
}
}
class Video(val id: String, val title: String)
But this way is very lengthy and unnecessary. I would suggest use an Object Mapping library like GSON or Moshi.
For that, the video list in your json should ideally be something like:
[
{
"artist": "12",
"image": "23",
"videos": [
{
"video_id": "12",
"video_title": "23"
},
{
"video_id": "12",
"video_title": "23"
},
{
"video_id": "12",
"video_title": "23"
},
{
"video_id": "12",
"video_title": "23"
},
{
"video_id": "12",
"video_title": "23"
}
]
}
]
Using this Json, you can easily create a class for this object, e.g.
class Artist(val id: String, val name: String, val image: String, val videos: List<Video>)
class Video(#field:Json(name = "video_id") val id: String, #field:Json(name = "video_title") val title: String)
And parse them easily like this:
Moshi.Builder().build().adapter(Artist::class.java).fromJson(response)
and then access this information like:
val artist = Moshi.Builder().build().adapter(Artist::class.java).fromJson(response)
intent.putExtra("firstArtist",artist?.name)
intent.putExtra("firstImage",artist?.image)
You can use below code to parse given json in kotlin
private fun parseJson(jsonResponse: String){
val jsonArray = JSONArray(jsonResponse)
for (i in 0..jsonArray!!.length() - 1) {
val jsonObj = jsonArray.optJSONObject(i)
val artist =jsonObj.optString("artist")
val image =jsonObj.optString("image")
val videosArray = jsonObj.optJSONArray("videos")
for (i in 0..videosArray!!.length() - 1) {
val videoObj = jsonArray.optJSONObject(i)
val video_id =videoObj.optString("video_id")
val video_title =videoObj.optString("video_title")
}
}
}