How to stop null value fields from being marshalled in Grails - json

I am using Grails 1.3.7 and have the following DTO
class Result {
String key
List errors
}
Now either the key or the errors will be present, but not both. If the Result has a key, I don't want the marshalled JSON to have the errors field with a null value as shown below
{"errors":null,"key":"abcde"}
I looked at configuration options for the converter and it does not have an option for suppressing null values. I also looked at the last section on that page titled 'Customizing Converters Results' and registered an object marshaller as follows
class Result {
static {
grails.converters.JSON.registerObjectMarshaller(Result) {
return it.properties.findAll {k,v -> v != null}
}
}
}
But still the result contains errors with the null value. I am looking for the cleanest way to achieve this for both XML and JSON.

Trying this Grails 2.0.3 results in an error indicating conflict between the errors field and GORM's automatically-added grails.validation.ValidationErrors field (also named errors). Your marshaller looks OK, so you may just need to change your field name to something other then errors?

Related

Elasticsearch 8.0.0 mapper_parsing_exception of a string literal for field type "flattened"

I have a Problem to insert a document via Api to my ES 8.0.0.
In my IndexTemplate I defined a mapping of a property called [Data] of type "flattend".
For "normal" JSON-Objects it works fine. But when I try to insert a plain string literal (for example "test") or a number (for example 4) I get a "400 Bad Request". JSONLint says it's a valid JSON!!
{
....
"Data": "test",
....
}
Can i configure ES to accept such kind of JSON for type "flattened"??
As Elasticsearch document mentions:
The flattened type provides an alternative approach, where the entire
object is mapped as a single field. Given an object, the flattened
mapping will parse out its leaf values and index them into one field
as keywords.
So, the value provided for the "flattened" field type should be a JsonObject.
Hence, below works as where "full_name" is of type "flattened"
"full_name":{
"name":"nishikant"
}
But below does not
"full_name":"nishikant".
Same has been given in exception
"reason" : "Failed to parse object: expecting token of type [START_OBJECT] but found [VALUE_STRING]"

Array to string conversion in EasyAdmin 3 (Symfony 5)

I'm trying to display a json array on the EasyAdmin detail page. I read here Is there a way to represent a JSON field in EasyAdmin 3? that you can use ArrayField in EasyAdmin 3 to display a json array, which would make sense to me as that is the only field in EasyAdmin that could display it so I added it like this:
public function configureFields(string $pageName): iterable
{
return [
ArrayField::new('status', $this->translator->trans('form.label.status'))->onlyOnDetail(),
];
}
But it gives me this error:
An exception has been thrown during the rendering of a template ("Notice: Array to string conversion"). Do I need to add something else to it or does it not work at all?
change "status" to a multiplicity "statuses"
Worked for me with changing "print" to "prints"
I found a workaround that resolved the issue in my situation where I wanted just to show JSON on details page
So in your entity add a get function as an unmapped field as indicated in the official documentaiton
https://symfony.com/bundles/EasyAdminBundle/current/fields.html#unmapped-fields
for example
public function getJsonField() {
return json_encode($this->yourEntityJsonAttribute);
}
then in configureFields function in your CrudController add your field like this
TextAreaField::new('jsonField')->onlyOnDetail()
You can also read the json attribute and generate an HTML string in the getJsonField function then in configure field just add renderAsHtml in th field like this
TextAreaField::new('jsonField')->onlyOnDetail()->renderAsHtml()
Wish this suits your case too, Good luck

how to apply custom validation on json value

I have a json data coming via api. I have set of policies that I need to validate over coming json data.
For Example I have a json like
{
"users_id":"x",
"is_user_logged_in":"true",
"checkin_date":"2018-12-12",
"checkout_date":"2019-12-13"
}
Now I want to apply validation like checkin_date should be less than checkout_data or let say if is-user_logged_in is true then user_id should not be null.
I cant deserialize the json as i need to pass it to different application to consume
I am using Scala any idea how can i implement this. The catch is there can be multiple policies or rules i need to validate and i can only get the rules in runtime.
Thanks
Most easier way is to add validation to the default constructor and just use the JSON parser as a validator (no need to use parsed data):
import java.time.LocalDate
case class UserData(
user_id: Option[String],
is_user_logged_in: Boolean,
checkin_date: LocalDate,
checkout_date: LocalDate
) {
require(!is_user_logged_in || user_id.isDefined, "missing `user_id` for logged in user")
require(checkout_date.isAfter(checkin_date), "`checkout_date` should be after `checkin_date`")
}
For more complicated cases please consider to use some handy validation library, like:
https://github.com/jto/validation

How to process null value inside json string using lua?

I am using lua in asterisk pbx. I encounter following problem while processing json string.
json "null" value converted to function type in lua. why?
how to handle this scenario? because i am expecting nil because no value means null in json and nil means nothing in lua.
local json = require( "json" )
local inspect = require("inspect")
local myjson_str='{"Sms":{"key":"xxxxxxxxxxxxxxxxxxxxx","to":"{caller}","senderid":null,"type":"Simple","content":"Your request has been accepted in Previous Miss call. We get back to you very soon."}}'
local myjson_table = json.decode(myjson_str)
print(type(myjson_table["Sms"]["senderid"]))
print(myjson_table)
print(inspect(myjson_table))
print(json.encode(myjson_table))
out put for above is
function
table: 0xf5e770
{
Sms = {
content = "Your request has been accepted in Previous Miss call. We get back to you very soon.",
key = "xxxxxxxxxxxxxxxxxxxxx",
senderid = <function 1>,
to = "{caller}",
type = "Simple"
}
}
{"Sms":{"type":"Simple","key":"xxxxxxxxxxxxxxxxxxxxx","senderid":null,"content":"Your request has been accepted in Previous Miss call. We get back to you very soon.","to":"{caller}"}}
It is up to specific library to decide how to represent null value.
Using nil has its own problem because its not possible find either
original JSON has key with null value or there no such key at all.
So some libraries just return some unique value. Some provide
a way to pass this value like json.deconde(str, NULL_VALUE).
So answer is just read the doc/source of library you use.
Most likely it provide something like json.null value to check
either value is null. But function is really strange choice because
they have some undetermined rules of uniqueness.
Or try another library.
First of all, #moteus is right:
It is up to specific library to decide how to represent null value
If you're using the JSON library by Jeffrey Friedl the solution is to use a placeholder instead of null and serializing the table structure to a json string using designated encode options:
-- define a placeholder
NullPlaceholder = "\0"
-- use it in an internal table
tableStructure = {}
tableStructure['someNullValue'] = NullPlaceholder
-- pass the placeholder to the encode methode
encode_options = { null = NullPlaceholder }
jsonString = JSON:encode(tableStructure, nil, encode_options)
which leads to
{"someNullValue": null}

Key Value Pair Datatype in FB 4.6

I have a JSON response form HTTP request.
"AdditionalData": {
"default" : "checked",
"example" : "empty"
}
This specific response would ideally be interoperated as a dictionary type (Key value pair). But when I auto-detect the return type of the JSON, FB 4.6 makes it of type Object. This does not work for me. For some reason the AdditionalData object in the model that I'm mapping is always null. What data type can I manually set this response to?
I don't know if you can force the result of a complex grouping to be anything but an Object when it gets returned. Once it arrives you could convert it into an ArrayCollection (of Objects or other ArrayCollections) though.