PHP - convert JAVA / JS Object to PHP array - java

I am requesting some data from Facebook over JAVA in android and sending it to the server:
Address[addressLines=[0:"Königspl., 86150 Augsburg, Germany"],feature=Königsplatz,admin=Bayern,sub-admin=Schwaben,locality=Augsburg,thoroughfare=Königsplatz,postalCode=86150,countryCode=DE,countryName=Germany,hasLatitude=true,latitude=48.366384499999995,hasLongitude=true,longitude=10.8943626,phone=null,url=null,extras=null]
I don't know what exactly this is, JAVA Object or I don't know..
I already tried: $array = json_decode($data, true); and it returns NULL
What is it and how do I convert it to PHP Array?
EDIT:
This is the JAVA (actually kotlin) code I use to generate the data:
val geocoder = Geocoder(this, Locale.ENGLISH)
try {
val addresses = geocoder.getFromLocation(48.366512, 10.894446, 1)
if (addresses != null)
{
val returnedAddress = addresses[0]
val strReturnedAddress = StringBuilder("Address:\n")
for (i in 0 until returnedAddress.maxAddressLineIndex) {
strReturnedAddress.append(returnedAddress.getAddressLine(i)).append("\n")
}
geocoderStuff = returnedAddress.toString()
} else
{
// NO ADDRESS
}
} catch (e: IOException) {
e.printStackTrace()
}
And this how I send it:
val params = RequestParams()
params.put("geocoder", geocoderStuff)
letsDoSomeNetworking(params)
private fun letsDoSomeNetworking(params: RequestParams) {
// AsyncHttpClient belongs to the loopj dependency.
val client = AsyncHttpClient()
client.get("http://www.bla.com/android/fb_access.php", params, object : JsonHttpResponseHandler()
{
override fun onSuccess(statusCode: Int, headers: Array<Header>?, response: JSONObject?)
{
// success
}
override fun onFailure(statusCode: Int, headers: Array<Header>?, e: Throwable, response: JSONObject?)
{
// error
}
})
}

The solution is to use gson library on JAVA/Kotlin side after getting the data:
val returnedAddress = addresses[0]
val strReturnedAddress = StringBuilder("Address:\n")
for (i in 0 until returnedAddress.maxAddressLineIndex) {
strReturnedAddress.append(returnedAddress.getAddressLine(i)).append("\n")
}
val gson = Gson() // HERE
val json = gson.toJson(returnedAddress) // HERE
geocoderStuff = json

Related

Retrofit response is not shown

I want to fetch data from the server using Retrofit but it shows me HTTP 500 server error I know it is due to a null value in parameters but I don't where is the null value comes from. I try my best to find the null value but can't find it. If any other reason then please tell me.
Here is my Fragment Code
#RequiresApi(Build.VERSION_CODES.M)
override fun inOnCreateView(mRootView: ViewGroup, savedInstanceState: Bundle?) {
val homeActivity = activity as HomeNavHostActivity
homeActivity.toolbar_id?.visibility = View.VISIBLE
homeActivity.toolbar_search_icon_id.visibility = View.VISIBLE
homeActivity.toolbar_add_icon_id.visibility = View.GONE
homeActivity.home_view_layout?.visibility = View.VISIBLE
homeActivity.bottom_layout?.visibility = View.VISIBLE
homeActivity.toolbar_title_tv.text = "Home"
homeActivity.toolbar_search_icon_id.setOnClickListener() {
showSearchDialog(mRootView)
}
homeActivity.cancel_text.setOnClickListener() {
homeActivity.search_layout.visibility = View.GONE
homeActivity.toolbar_title_tv.visibility = View.VISIBLE
homeActivity.search_view?.setQuery("", false)
homeActivity.search_view?.clearFocus()
}
val dialogHelper by inject<MaterialDialogHelper>()
setupProgressDialog(viewModel.showHideProgressDialog, dialogHelper)
if (isNetworkAvailable(requireContext())) {
var area:String = "20"
var zipcode:String = "WC2N5DU"
viewModel.getSkipFilterList(zipcode, area)
} else {
showAlertDialog(getString(R.string.no_internet))
}
attachViewModel()
}
Here is my ViewModel Code
var filterSkipList: MutableLiveData<SkipListResponse> = MutableLiveData()
fun getSkipFilterList(zipcode: String, area: String) {
viewModelScope.launch {
_showHideProgressDialog.value = true.wrapWithEvent()
sharedWebServices.getFilterSkip(zipcode, area).run {
onSuccess {
_showHideProgressDialog.value = false.wrapWithEvent()
if (it.code == VALID_STATUS_CODE) {
filterSkipList.value = it
}else {
showSnackbarMessage(it.message)
}
}
onFailure {
_showHideProgressDialog.value = false.wrapWithEvent()
it.message?.let { it1 -> showSnackbarMessage(it1) }
}
}
}
}
Here is my data class
#Serializable
data class SkipFilterList(
val zipcode:String,
val area:String
)
Here is my Post
#POST("search-skip")
suspend fun skipListing(
#Header("Authorization") token: String?,
#Body body: SkipFilterList): SkipListResponse
Here is My Repostry
suspend fun getFilterSkip(
zipcode: String,
area: String
) = withContext(dispatcher) {
val token = SharePrefrenceHelper.getInstance(app).getToken()
val body = SkipFilterList(zipcode, area)
safeApiCall {
Result.success(apiServices.skipListing("Bearer" + token, body))
}
}
By passing json object in the body this was solved.
val jsonObject = JsonObject()
jsonObject.addProperty("zipcode", zipcode)
jsonObject.addProperty("radius", area)

Extract QueryParameters from deeplink Url in Kotlin

Please help guys, Im using firebase dynamic links, i want to know how we can extract our pass string queryparameters in kotlin. this is the generated deeplink:
deeplink = https://demo.com/?roomCode=myroomtest%3FroomToken%3DOiJIUzI1NiJ
how to extract roomCode=myroomtest, roomToken=OiJIUzI1NiJ this string values from deeplink url.
private fun handleDynamicLink() {
Firebase.dynamicLinks
.getDynamicLink(intent)
.addOnSuccessListener { pendingDynamicLinkData ->
val deepLink: Uri?
if (pendingDynamicLinkData != null) {
deepLink = pendingDynamicLinkData.link
what queryparameter should i use here to extract the strings from deeplink?
}
}
.addOnFailureListener { _ ->
toast(getString(R.string.main_error_fetch_dynamic_link))
}
}
I need the strings so that i can start meeting using the following code:
private fun joinMeeting (roomCode:String, roomToken:String) {
MeetingUtils.startMeeting(
this,
roomCode,
roomToken)
}
Finally it is resolved:
private fun handleDynamicLink() {
Firebase.dynamicLinks
.getDynamicLink(intent)
.addOnSuccessListener { pendingDynamicLinkData ->
val deepLink: Uri?
if (pendingDynamicLinkData != null) {
deepLink = pendingDynamicLinkData.link
val roomCode = deepLink?.getQueryParameter("roomCode")?.substringBefore("?roomToken=","")
val roomToken = deepLink?.getQueryParameter("roomCode")?.replace("roomToken","roomToken")?.substringAfter("?roomToken=","")
if(roomCode !=null && roomToken != null) {
joinMeeting(roomCode, roomToken)
}
}
}
.addOnFailureListener { _ ->
toast(getString(R.string.main_error_fetch_dynamic_link))
}
}

what can be used as an alternative to Object in Kotlin?

I am writing the following Kotlin code but when I compile it gives the error
Null can not be a value of a non-null type ByteArray
this is my code
fun myKafkaProducer(): MessageBusProducer<UUID?, Any>? {
return if (serverProperties().isWAPKafkaSet) {
val uuidSerializer = UUIDSerializer()
val uuidDeserializer = UUIDDeserializer()
val topic = serverProperties().hmsTopic
val serializer = KafkaProperties.Serializers(Function<UUID, ByteArray> { uuid: UUID? -> uuidSerializer.serialize(null, uuid) }, label# Function<Any, ByteArray> { sapMessage: Any ->
try {
return#label ObjectMappers.getObjectMapper().writeValueAsString(sapMessage).toByteArray()
} catch (e: JsonProcessingException) {
e.printStackTrace()
}
null /*showing error here */
}, null,
null
)
// set WapKafkaHostPortAddress in env (configuration repo)
return KafkaMessageBusProducerFactory.Builder<UUID, Any>()
.kafkaAddressPropertyName("portAddress")
.topic(topic)
.messageBusTypeSerializers(serializer)
.build().create(true)
} else {
return null
}
}
I am trying to code the equivalent of Serializers<UUID, Object>
what other datatype can I use ?
The equivalent of Object in Kotlin is the type Any?. Only then are you able to return null, because the type Any is non-nullable and Any? can be null.

Retrofit 2 response body to custom class

Currently, I use retrofit2 to call restful apis and get response. Because the response body can be multiple types, I wrote the code following.
//Interface
#FormUrlEncoded
#POST("payments/events/{id}")
fun postPayment(#Path("id") id: String): Call<Any>
//Api Manager
fun postPayment(id: String): Observable<Any> {
return Observable.create {
subscriber ->
val callResponse = api.postPayment(id)
val response = callResponse.execute()
if (response.isSuccessful) {
if (response.body() is MyClass1) {
// never success...
} else if (response.body() is MyClass2) {
// never success...
}
subscriber.onNext(response.body())
subscriber.onCompleted()
} else {
subscriber.onError(Throwable(response.message()))
}
}
}
So I'm not able to cast response.body() to MyClass1 or MyClass2.
response.body() as MyClass1 occurs error too.
MyClass1 and MyClass2 are normal template classes.
class MyClass1( val id: String, val data: String)
Is there any smart way to cast response body to my custom classes?
Small update for MyClass2
class MyClass2( val token: String, val url: String, val quantity: Int)
As mentioned by #Miha_x64, Retrofit doesn't know about your classes (MyClass1 and MyClass2) because your Call uses the Any type. Therefore, Retrofit is not creating an instance of MyClass1 or MyClass2, instead it is just creating an instance of the Any class.
The simplest solution would just be to combine the two classes:
data class MyClass(
val id: String?,
val data: String?,
val token: String?,
val url: String?,
val quantity: Int
)
Then you can specify the response type in your interface:
#FormUrlEncoded
#POST("payments/events/{id}")
fun postPayment(#Path("id") id: String): Call<MyClass>
In the case your response does not have an id or data element, they will just be null. Then you can check which type of response was received simply by checking which values are null:
if (response.body().id != null) {
// Handle type 1 response...
} else if (response.body().token != null) {
// Handle type 2 response...
}
A slightly more complex solution would be to write a wrapper for your two classes, and a type adapter to populate the wrapper. This would avoid the nullability of each of the fields, as well as keep your data structure separated.
This would differ based on the ConverterFactory you are using but if, for example, you are using Gson, it would look something like this:
data class ApiResponse(
val val1: MyClass1? = null,
val val2: MyClass2? = null
)
class ApiResponseAdapter : TypeAdapter<ApiResponse> {
#Throws(IOException::class)
override fun write(out: JsonWriter, value: ApiResponse?) {
if (value != null) {
out.beginObject()
value.val1?.id? let { out.name("id").value(it) }
value.val1?.data? let { out.name("data").value(it) }
value.val2?.token? let { out.name("token").value(it) }
value.val2?.url? let { out.name("url").value(it) }
value.val2?.quantity? let { out.name("quantity").value(it) }
out.endObject()
} else {
out.nullValue()
}
}
#Throws(IOException::class)
override fun read(in: JsonReader): ApiResponse {
reader.beginObject()
var id: String? = null
var data: String? = null
var token: String? = null
var url: String? = null
var quantity: Int = 0
while(in.hasNext()) {
val name = in.nextName()
if (name.equals("id", true)) {
id = in.nextString()
} else if (name.equals("data", true)) {
data = in.nextString()
} else if (name.equals("token", true)) {
token = in.nextString()
} else if (name.equals("url", true)) {
url = in.nextString()
} else if (name.equals("quantity", true)) {
quantity = in.nextInt()
}
}
reader.endObject()
if (id != null && data != null) {
return ApiResponse(MyClass1(id, data), null)
} else if (token != null && url != null) {
return ApiResponse(null, MyClass2(token, url, quantity))
} else {
return ApiResponse()
}
}
}
Then you can add this type adapter to your Gson instance:
val gson = GsonBuilder().registerTypeAdapter(ApiResponse::class.java, ApiResponseAdapter()).create()
Then replace the Call<Any> type with Call<ApiRepsone> and you can then check which response was received by checking which value is null:
if (response.body().val1 != null) {
// Handle MyClass1 response...
} else if (response.body().val2 != null) {
// Handle MyClass2 response...
}
First of all, thanks #Bryan for answer. Your answer was perfect but finally I did something tricky way.
...
if (response.isSuccessful) {
val jsonObject = JSONObject(response.body() as Map<*, *>)
val jsonString = jsonObject.toString()
if (jsonObject.has("id")) {
val myclass1Object = Gson().fromJson(jsonString, MyClass1::class.java)
...
} else {
val myclass2Object = Gson().fromJson(jsonString, MyClass2::class.java)
...
}
}
...

"Response has already been written" with Vertx

I am brand new to Vertx and trying to create my first HTTP Rest Server. However, I have been running into this issue. Here is the error I'm getting when I try to send a response.
Jan 07, 2017 3:54:36 AM io.vertx.ext.web.impl.RoutingContextImplBase
SEVERE: Unexpected exception in route
java.lang.IllegalStateException: Response has already been written
at io.vertx.core.http.impl.HttpServerResponseImpl.checkWritten(HttpServerResponseImpl.java:559)
at io.vertx.core.http.impl.HttpServerResponseImpl.putHeader(HttpServerResponseImpl.java:156)
at io.vertx.core.http.impl.HttpServerResponseImpl.putHeader(HttpServerResponseImpl.java:54)
at com.themolecule.utils.Response.sendResponse(Response.kt:25)
at com.themolecule.api.UserAPI.addUser(UserAPI.kt:52)
at TheMoleculeAPI$main$3.handle(TheMoleculeAPI.kt:50)
at TheMoleculeAPI$main$3.handle(TheMoleculeAPI.kt:19)
at io.vertx.ext.web.impl.RouteImpl.handleContext(RouteImpl.java:215)
at io.vertx.ext.web.impl.RoutingContextImplBase.iterateNext(RoutingContextImplBase.java:78)
at io.vertx.ext.web.impl.RoutingContextImpl.next(RoutingContextImpl.java:94)
at io.vertx.ext.web.handler.impl.AuthHandlerImpl.authorise(AuthHandlerImpl.java:86)
at
And this is how I have set up my routes.
// setup verx
val vertx = Vertx.vertx()
val router = Router.router(vertx)
val allowHeaders = HashSet<String>()
allowHeaders.add("x-requested-with")
allowHeaders.add("Access-Control-Allow-Origin")
allowHeaders.add("origin")
allowHeaders.add("Content-Type")
allowHeaders.add("accept")
val allowMethods = HashSet<HttpMethod>()
allowMethods.add(HttpMethod.GET)
allowMethods.add(HttpMethod.POST)
allowMethods.add(HttpMethod.DELETE)
allowMethods.add(HttpMethod.PATCH)
router.route().handler(CorsHandler.create("*")
.allowedHeaders(allowHeaders)
.allowedMethods(allowMethods))
router.route().handler(BodyHandler.create())
val config = JsonObject().put("keyStore", JsonObject()
.put("path", "keystore.jceks")
.put("type", "jceks")
.put("password", "password"))
// protect the API, login outside of JWT
router.route("/them/*").handler(JWTAuthHandler.create(jwt, "/them/login"))
//login routes
router.post("/them/login").handler { it -> loginAPI.login(it, jwt) }
//user routes
router.get("/them/user/getusers").handler { it -> userAPI.getUsers(it) }
router.post("/them/user/addUser").handler { it -> userAPI.addUser(it) }
This is the code that it seems to have the problem with.
fun sendResponse(responseCode: Int, responseMsg: String, context: RoutingContext) {
val userResponse = JsonObject().put("response", responseMsg)
context
.response()
.putHeader("content-type", "application/json")
.setStatusCode(responseCode)
.end(userResponse.encodePrettily())
}
Am I doing something wrong with the handlers? I tried to change the method for the response up a bunch of times, but nothing seems to work. This is written in Kotlin. If I need to add more context, just say the word!
edit: addUser method added
fun addUser(context: RoutingContext) {
val request = context.bodyAsJson
val newUser = NewUserRequestDTO(request.getString("userID").trim(), request.getString("password").trim())
newUser.userID.trim()
if (!newUser.userID.isNullOrEmpty() && !newUser.password.isNullOrEmpty()) {
//check user ID
if (userDAO.userIdInUse(newUser.userID)) {
Response.sendResponse(400, Response.ResponseMessage.ID_IN_USE.message, context)
return
}
//check password valid
val isValid: Boolean = SecurityUtils.checkPasswordCompliance(newUser.password)
if (!isValid) {
Response.sendResponse(400, Response.ResponseMessage.PASSWORD_IS_NOT_VALID.message, context)
return
}
val saltedPass = SecurityUtils.genSaltedPasswordAndSalt(newUser.password)
userDAO.addUser(newUser.userID, saltedPass.salt.toString(), saltedPass.pwdDigest.toString())
} else {
Response.sendResponse(401, Response.ResponseMessage.NO_USERNAME_OR_PASSWORD.message, context)
return
}
Response.sendResponse(200, Response.ResponseMessage.USER_CREATED_SUCCESSFULLY.message, context)
}

Categories