How can I get all wrong fields names? For example, I have next input string as JSON format:
{
"name": "name#1",
"address": "address#1",
"pone": "000000000",
"ail": "mail#smth.ru"
}
Where 'pone' and 'ail' fields are wrong. It needs to use 'phone' and 'email'. I also use this property
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, true);
For catching exception. And I catch it inside of try/catch when deserializing JSON to an object, but there is info about only one field in the exception message.
I need to get all wrong fields at once.
Maybe somebody have an idea about it? I also tried use jsonSchema but I think it isn't good idea, because in the end I have this message $: string found, object expected by this code:
JsonSchemaFactory factory = JsonSchemaFactory.getInstance(VersionFlag.V201909);
InputStream stream=TestClass.class.getResourceAsStream("/file.json");
JsonSchema schema=factory.getSchema(stream);
JsonNode node =mapper.convertToJsonNode(MyObject.builder().build());
Set<ValidationMessage> validationResult = schema.validate(node);
Related
My REST API, which is build with Spring in Java, produces an invalid JSON object, because it contains multiple breaks in a string, which lead to the problem, that the string has an unexpected end and the rest doesn't count as part of the string anymore, example:
{
"status": "Success",
"message": "Lorem ipsum",
"data": {
"correct": [
{
"record": "ULTRA LONG
XML STRING
WITH BREAKS",
"code": 0,
"errors": []
}
]
}
}
The error arises in the data -> correct -> record string field, because it contains breaks which splits the original string.
My API endpoint serializes the above JSON like this:
#PostMapping(value="/check-records",
consumes=MediaType.APPLICATION_JSON_VALUE,
produces=MediaType.APPLICATION_JSON_VALUE)
public Response checkRecords(#RequestBody(required=true) Records records) {
// Check records
return new Response("Success", "Lorem ipsum", data);
}
Response is a class, which automatically gets serialized into a JSON object after returning. data is a map in order to create the above JSON structure.
I couldn't find any suitable solution for my problem yet. Does anybody has an idea how I could remove all breaks, spaces or control characters before I serialize the JSON object?
I appreciate any kind of help, sheers! :)
Thanks to #pringi. He suggested to use a regex to remove all control characters in Java before I serialize the JSON object.
String record = orginalRecord.replaceAll("[\\\\p{Cntrl}^\\r\\n\\t]+", "")
You can find more informations about regex in the original question: How to remove control characters from java string?
I am converting json response to Object type using jakson api and after i want to verify the property values .
ObjectMapper mapper = new ObjectMapper();
Object jsonobj = mapper.readValue(inputStream,Object.class);
i am getting correct mapped json response to Object type .
{fatalError=false,messages=[{code=1234,xyz=abcd}]}
using PropertyUtilbean class i want to get my object property value
String val =propertyutil.getProperty(jsonobj,"fatalError")--- this will give value as false, but if i want to get value using key messages.[0].code it is giving me no such method found. please help me out if i am using wrong key format. any help will be appreciated.!
this is nested arrayList object and messages is a arrayList ,can you try with index number---- messages[0]
proto is designed so that introduction of new fields should not break your code that runs on older version.
But if you're using json conversion in java using protobuf-java-util then your old code will break on new fields or new enum values unknown to existing code...
I've opened an issue on github but it does not get any attention. I hope to get some answers here.
Given message like this
message Msg {
required string sender = 1;
required string message = 2;
}
if we convert this to json and print using
JsonFormat.printer().print(msg)
we will have this result
{
"sender": "me",
"message": "message"
}
if we decode this json to Msg using its builder
JsonFormat.parser().merge(json, builder)
we will get expected result... But if we try to decode similar json with additional extra field
{
"sender": "me",
"message": "message",
"extra" : "some extra stuff"
}
we will fail with this exception
com.google.protobuf.InvalidProtocolBufferException: Cannot find field: extra in message proto.Msg
How is that nobody cares about this problem? So far my only solution to this is to write a parser from scratch that will ignore unknown fields and unknown enum values when parsing...
Is there something i overlooked or people simply dont use backwards compatibility features?
This is already fixed by google, the builder provides option to ignore unknown fields.
I have successfully created an index using elasticsearch, and can serialized those exact json payloads back to my java application.
for (SearchHit searchHit : searchResponse.getHits()) {
try {
result.getItems().add(objectMapper.readValue(searchHit.getSourceRef().streamInput(), Program.class));
} catch (IOException e) {
throw new IllegalArgumentException("Cannot marshall json", e);
}
}
The payload size that I export to elasticsearch is very large, but the response, I want to be very small. I also want to allow the client to dynamically include or exclude some fields. So I did this, where fields is an array of fields I want to include. This works well in that only the fields I ask for are returned, however the searchHit.getSourceRef is now null. Is there any way to get it to just copy the fields that I included via Jackson? Or must I always return the entire source object? Or do I have to write some sort of mapping code to translate (I would really like to avoid this) ?
SearchResponse searchResponse = transportClient.prepareSearch("programs")
.addFields(fields.toArray(new String[fields.size()]))
.setTypes("program")
.setQuery(query).setFrom(start).setSize(pageSize)
.execute().actionGet();
however the searchHit.getSourceRef is now null.
It is null because searchHit.getSource() is also null. As far as I know you have to add "_source" to your fields list when you do the search. Something like this:
ArrayList<String> fields = new ArrayList<String>();
fields. add("field1");
fields.add("field2");
fields.add("_source"); // add this field
SearchResponse response = transportClient.prepareSearch("programs")
.addFields(fields.toArray(new String[fields.size()]))
.execute().actionGet();
When Parsing JSON I normally just constuct an object and use the gsonlibrary to parse my String into that object.
However, I now find myself with a rather complex response which consists of many elements each with sub elements of objects and arrays and arrays of objects. It looks something like this...
{
"type": "thetype",
"object":{
"text": "texthere",
"moretext": "more here"
},
...,
...,
...,
...,
"fieldIwant": [
{
"object":"object!"
},
....
....
{
"object":"object!"
},
]
}
The thing is, I'm only really interested in fieldIwantand nothing else. Is there not a way in Java for me to just extract that field and work with it alone and not all this other dead weight I do not need?
According to this http://sites.google.com/site/gson/gson-design-document it looks like gson does this for you by default.
When you are deserializing a Json string into an object of desired type, you can either navigate the tree of the input, or the type tree of the desired type. Gson uses the latter approach of navigating the type of the target object. This keeps you in tight control of instantiating only the type of objects that you are expecting (essentially validating the input against the expected "schema"). By doing this, you also ignore any extra fields that the Json input has but were not expected.
In other words, it doesn't deserialize any of the fields you don't need. You should be good to go.
You can use the low level JsonParser API
JsonObject jsonObject = new JsonParser().parse(json).getAsJsonObject();
yourArray = new Gson().fromJson(jsonObject.get("fieldIwant"), yourArrayType);
Alternatively you can create an ExclusionStrategy to use with a GsonBuilder