Yii2 REST DB Geometry field serialization - json

I have a table in mySQL with fields of GEOMETRY and POLYGON types. And the Yii2 RESTful app. Here is a standart ActiveController:
<?php
namespace backend\modules\v1\controllers;
use common\models\Geo;
class GeoController extends ActiveController
{
public $modelClass = 'common\models\Geo';
}
When I have any records in my table with spatial data JSON response breaks with message:
code: 5
file: "/vendor/yiisoft/yii2/helpers/BaseJson.php"
line: 120
message: "Malformed UTF-8 characters, possibly incorrectly encoded."
name: "Exception"
Should I write custom json serializer or somehow override ActiveProvider select with something like "AsText(geometry_field_name)"?

I think you should change field types supported by JSON (http://www.tutorialspoint.com/json/json_data_types.htm).
For example, if you use MySQL field with type CHAR, you will get the same error

Basically the issue was solved by extending ActiveQuery class with adding additional column using SQL command AsText(geomery_field_name) as geometry_text.

Related

How to display Blob /Json data field in Liferay 7.2?

I am using a service builder that is retrieving the form data fine from mysql db. I have a field that has the json data and I tried to map it using object mapper and using com.fasterxml.jackson.databind.ObjectMapper to display the json content. However, the Blob Data is shown as: com.mysql.cj.jdbc.Blob#4ca74f7f
How do I actually get/extract the data from the storing link above? Here is my code snippet:
for (ddmcontent MyTemp : myList) {
System.out.println("Content ID : "+myList.getContentId());
System.out.println("User Blob Data : "+myList.getData());
Blob responseBody =myList.getData();
ObjectMapper objectMapper = new ObjectMapper();
List<ModelData> myDat = objectMapper.readValue((DataInput)
responseBody,objectMapper.getTypeFactory().constructCollectionType
(List.class,ModelData.class));
for (ModelData dt : myDat) {
System.out.println("User Name : "+dt.Name);
System.out.println("Users Email : "+dt.Email);
}
}
Please note, I have defined my ModelData elements as all String.
Any suggestion? What am I missing?
Thanks in advance!
The toString() representation hints at the object's type com.mysql.cj.jdbc.Blob. If you look up its javadoc (or the interface it implements) you'll see the options that you have to decode the contents of the Blob, namely getting an InputStream or a byte[] representation, which you'd have to subject to the correct character set decoding to turn it into a String.
Make sure you nail the character set by testing it with all kinds of Unicode content, so that you don't have to fix badly encoded database content later when your table contains a lot of data in unknown encodings.
As you're using Liferay's Service Builder, you might want to share the relevant parts of your service.xml (optional model-hints.xml) to check for an easier implementation.
I finally got this working by changing the field in question to String and addining a max length to certain number of Char
Thanks!

Serialize/deserialize a Dictionary with a comma-separated entry

I am developing a ASP.NET Core 3.1 website and I have data in a Dictionary<string, object> that I want to Serialize/Deserialize using Microsoft System.Text.Json (I am new to Json serialize/deserialize in fact). The data comes from a PostgreSQL DB query and one of the returned values is a comma-separated list of integers (converted to string) that results from the STRING_AGG function. The image below shows one of the entries of the Dictionary:
I serialize it using the following code. Please note that I have tried both Microsoft System.Text.Json and Newtonsoft.
jsonResult = Newtonsoft.Json.JsonConvert.SerializeObject(result);
//jsonResult = JsonSerializer.Serialize(result);
The data in the Dictionary should be deserialized according to the following class structure:
I use the following code:
//IEnumerable<SeccGralContenidoViewModel> seccGralContenido = JsonSerializer.Deserialize<IEnumerable<SeccGralContenidoViewModel>>(_seccGralContenidoRepository.Read());
IEnumerable<SeccGralContenidoViewModel> seccGralContenido = Newtonsoft.Json.JsonConvert.DeserializeObject <IEnumerable<SeccGralContenidoViewModel>>(_seccGralContenidoRepository.Read());
However, an exception is thrown when deserializing no matter if I use Newtonsoft or System.Text.Json:
I am originally using System.Text.Json namespace but I also tried using Newtonsoft. After analyzing a bit deeper, I see that the problem could be the way in which data is saved to the Dictionary but I have not found a workaround.
If you don't want to write a custom converter then the simplest solution is to introduce another property:
public string CategoriasContenidolds {get; set;}
private static char delimiter = ',';
[JsonIgnore]
public string[] CategoriasContenidolds_Collection
{
get => CategoriasContenidolds.Split(delimiter).Select(item => item.Trim()).ToArray();
set => CategoriasContenidolds = string.Join(delimiter, value);
}
The serializer will use the CategoriasContenidolds property during serialization and deserialization
You should use CategoriasContenidolds_Collection (or name whatever you want) in your business logic
By explicitly marking this property with JsonIgnore the serializer will ignore that
I could solve my issue by directly getting JSON formatted results from queries. PostgreSQL does an excellent job. This way I also avoid performing a 2-step process: first, getting the query result; second, serializing to JSON.

Getting No converter found error

Query(value = "SELECT * FROM test where id = :key", nativeQuery=true)
public User findById(#Param("key") String key);
The above query working is fine.
Query(value = "SELECT * FROM test where id = :key", nativeQuery=true)
public localhost._8080.ws.User findId(#Param("key") String key);
But the above query getting the error as below :
No converter found capable of converting from type [org.springframework.data.jpa.repository.query.AbstractJpaQuery$TupleConverter$TupleBackedMap] to type [localhost._8080.ws.User]
SOAP XSD created auto generated classes and expecting output localhost._8080.ws.User type due to that getting error.
Please suggest on this error.
Spring Data JPA is not intended to map arbitrary results of SQL statements to arbitrary objects.
It maps results into DTOs or projections.
Most likely you generated class has properties it doesn't know how to handle.
Probably the most sensible way to solve this is to have the repository return something it can handle (User or a Map should work) and create your desired type from there using your own code or a library intended for such conversion.
Dozer seems a popular choice for that.

java.util.Date unmarshalling form grails json request

I'm facing following error while trying unmarshal java.util.Date from JSON in grails controller.
org.codehaus.groovy.runtime.typehandling.GroovyCastException: Cannot cast object '2011-10-07 10:24:40' with class 'java.lang.String' to class 'java.util.Date'**
Also, I've tried the following method but still no luck, actually I've doubt wether I've implemented following in right way or not because when i put println statements in following method:
public CustomDateBinder(List formats)
Nothing prints on console.
Grails Date unmarshalling
According to the description of your error message you are trying to convert a String to Date, if you want to do it manually you can use the following method in your Controller (since Grails 2)
def val = params.date('myDate', 'dd-MM-yyyy') //Obviously you need to change the format
Check the following post for more info: http://mrhaki.blogspot.com/2012/01/grails-goodness-date-request-parameter.html

How to serialize transient fields in the model via FlexJson?

I am using Play Framework to expose REST API, which returns some JSON objects.
To simplify the API usage, I would like to return a "calculated" field in the response.
Unfortunately, in my tests, while FlexJson does not ignore the transient model fields completely, but always sets them to 'null'.
More details:
In the model class, I define:
#Transient
public String currencyName;
The only constructor of the class set the value to "dollar" (for debugging purposes):
this.currencyName = "dollar";
When serializing the class using FlexJson, when the 'currencyName' field is not specified in the include/ exclude - the result always looks like:
"currencyName":null
Any idea what got wrong, and how to get the field value serialized into JSON?
Thanks in advance.
By definition if your field is transient it will not be serialized. Perhaps this field should not be transient in your application if the state matters.