Java validator for String - json

How do I validate using Hibernate validator for elements appearing more than once in a JSON payload bound to a Java class annotated with validator annotations?
Let's say I have the following:
class Person {
String name;
int age;
}
I am binding JSON to Person.
The JSON payload looks like the following:
{
"name":"someName",
"age":30
}
Let's say the payload has 2 "name" fields repeated as below.
{
"name":"someName",
"name" : "otherName",
"age":30
}
Then I like to use the validator to validate this. It will work for Collection objects if I use #Size(min=1, max=1).
I am wondering how I make this work for String. With String #Size tries to look for the length of the string content and not the number of times the string content in the payload.
Thanks for your time!

This is not possible. JSON deserialization and Bean validation are two entirely different things. By the time your Hibernate validation kicks in all it sees is a Person object, with a single name field.
It is the behavior of your JSON library that will determine which of the "name" fields will be deserialized into the Java bean (or if an exception will be thrown). For the most part, if you want to validate that no duplicates are supplied then you are going to need to write some custom deserialization code.

Related

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.

Expression serialization/deserialization in C#

I try to realize database access decorator based on Expression types. So, I've already tried many different json serializing libraries, started from Newtonsoft Json till DataContractJsonSerializator and etc.
1) Most of serializators crash on Expression type serialization (including System.Text.Json.Serialization).
2) Newtonsoft.JsonSerializer successfully serialize Expression<Func<User, bool>> test = e => e.Id == sameUser.Id, where User is the class like:
public class User
{
public Guid Id { get; set; }
public string Fullname { get; set; }
}
and sameUser is an object of User class.
But Newtonsoft.JsonSerializer produces string of ~169-200 millions symbols. I don't know does Newtonsoft.JsonSerializer correctly deserialize this json of the other side becauseof the size. Ofcourse, I've tried to use different serializing options.
3) ServiceStack.Text.JsonSerializer successfully serialize Expression<Func<User, bool>> test = e => e.Id == sameUser.Id with normal json size (approx 2-3 thousands symbols), but on the deserialization Expression.Body always null after deserialization (and this really strange - serialized json has it well-serialized).
4) Serialize.Linq successfully passed the test.
I want to understand, what the reason of this strange behavior of main serializers like Newtonsoft, ServiceStack, Microsoft, etc?
P.S. I'ven't tested protobuf-net and MessagePack yet, I'll do this soon,but think they have the same troubles with Expression class object serialization/deserialization.
Expression has cyclical dependencies an non serializable references that is not suitable for serialization. If you want to serialize the debug string representation of an Expression do that in your code and serialize the string, don’t expect serialization libraries to attempt to serialize a non-serializable class that’s impossible to deserialize.
If you want to serialize code, send raw source code and use Roslyn or Code DOM to execute the source code received, you’ll need to validate any untrusted user code for potential security vulnerabilities or unwanted behavior before evaluating it.

JSON Jackson flat json to composite java object

I was wondering if someone could suggest the recommended way to covert flat JSON into a complex java object.
Example JSON
{account_id: 1, user_id:3, user_name:john ... }
But my java class needs to be
class Account {
int account_id;
User user;
}
And here is the user object...
class User {
int user_id;
String user_name;
}
It looks like I could go from JSON to java using the Jackson constructor to create the object the way I need but I also need to covert the java object into a flat JSON.
Do I need to use a serializer/deserializer for each class or is there a way I can do it with simple annotations... By maybe telling it to ignore the user object but not what's inside it..
Let me know what your ideas are. Thanks

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.

Changing Field Name Value in ViewModel

Is there any way to change the FieldName Value for a property in a Viewmodel? I would like to use the standard naming convention for the property, but have the viewmodel return something else. This is important, because I have a json request that requires the properties to be in lowercase.
I have tried using both XMLAttributes, and DataMembers, but neither of those soultions worked. Those came from the following questions.
Serialize .Net object to json, controlled using xml attributes
JavaScriptSerializer.Deserialize - how to change field names
So, to reiterate, I need something like this
public string Start { get; set; }
to show up as
viewmodel.start
instead of
viewmodel.Start
when I am passing my viewmodel to the callback inside the getJson request
What about adding an extra property to your model?
public string start {get {return Start;}}