Jackson: avoid deserialization of some fields but not ignoring them - java

i need to carry all the json data (to store them, log, return) but i will never access them from code. is there any way to avoid deserializing them but still use them during serialization?
class MyObject {
int importantField; // i want this field to be properly deserialized
String notImportantJsonGarbage; // i don't care what's here. it must be a valid json
}
So now i'd like to be able to deserialize it from
{"importantField":7, "notImportantJsonGarbage":{"key1":3, "key2":[1,2,3]}}
and later serialize it to the same string
UPDATE
i don't want to ignore this property. i need this data. but as a string, not fully deserialized object
i need to be able to do:
json1 -> object -> json2
json1 == json2

Take a look at: JsonProperty.Access
AUTO - Access setting which means that visibility rules are to be used to automatically determine read- and/or write-access of
this property.
READ_ONLY - Access setting that means that the property may only be read for serialization, but not written (set) during
deserialization.
READ_WRITE - Access setting that means that the property will be accessed for both serialization (writing out values as
external representation) and deserialization (reading values from
external representation), regardless of visibility rules.
WRITE_ONLY - Access setting that means that the property may only be written (set) for deserialization, but will not be read
(get) on serialization, that is, the value of the property is not
included in serialization.
So in your case you could use it like this:
#JsonProperty(access = Access.READ_ONLY)
private String notImportantJsonGarbage;

You can use annotation #JsonIgnoreover the property that you wish to ignore

You can use the type JSONObject for the Json field.
private JSONObject notImportantJsonGarbage;
And when you need to read that, you can convert it to a String (or other type). You can use jackson or gson libraries to achieve that.
Note that when you convert the JsonObject back to String, the resulting string might have the quotes escaped.
Using JSONObject also solves your requirement of 'must be a valid json object'.

Related

How to serialize proto3 message to a string and back?

In Java, I want to convert a proto3 message into a string that:
I can send over HTTP
As more fields get added to the proto, it's still able to deserialize old strings?
If you are wondering why I need to serialize into a string, I have a proto:
message Order {
...
}
and I want to create a string 'order_tag' out of it that I want to pass around.
I saw com.google.protobuf.TextFormat but it says it's for proto2 and also it doesn't say anything about backward compatibility.
You can serialize the message to bytes, and use base64 encoding to convert the serialized value to string. In this way even if the fields change, you should be able to deserialize the string as long as the schema change happens within the restrictions defined in https://developers.google.com/protocol-buffers/docs/proto3#updating.
Don't use text encoding except for debugging purposes. It doesn't provide the same backward compatibility guarantee that the binary format provides (e.g. changing a field name will break existing serialized data).
To serialize to string:
BaseEncoding.base64().encode(order.toByteArray())
and to deserialize:
Order.parseFrom(BaseEncoding.base64().decode(orderStr))

How to print JSON object by Gson without sensitive attributes?

I am using Gson to print objects as JSON but I realise that it prints all things and it also exposes sensitive datas. Anyway to prevent that easily?
You can use #Expose(serialize = false, deserialize = true) over fields that you do not want to expose as JSON. This way you do not convert some fields when converting to JSON format but they are available when you receive a JSON object over the network and want to use those fields.
If you take a look at the Gson-doc here you can see the answer to your question. Do not forget to invoke GsonBuilder.excludeFieldsWithoutExposeAnnotation()
I just have another way to do it:
Just write the keyword "transient" before the field you want to remove. For example:
private transient String emailAddress;
"transient" works like just #Expose(serialize = false, deserialize = false). That field will not be present during the serialization as well as the deserialization of your object.

Automatic Conversion of JSON to Java Object

I was wondering if there is any way or library which allows the automatic conversion of json strings to java objects ?
i.e. similar functionality provided by Backbone for javascript.
I am fully aware you can do it step by step for each field using something like:
JSONObject json = new JSONObject(jsonString);
String body = json.get("body").toString;
However I have many json files to convert and manually typing out the code for ever object I need seems tedious. Is there anyway to do it autonomously ?
I.e. provide an object template which can be populated regardless of it's fields ?
Most frameworks that use ajax allow you to set a config that will do this for you.
MyClass a = Gson().fromJson(jsonString, MyClass.class)

Using reflection to set property values where types are unknown

I am using reflection to set value object properties at runtime. If everything were a string, I may not be asking this question, but that's not the case. I have a web service that returns json and I want to use the json returned by the service to populate the object. I have an ArrayList of strings called alphabeticalKeys that contains sorted keys in the json string. Here is the code I am using to dynamically populate the object (user):
for(String fieldName : alphabeticalKeys){
Log.d("JSON:" + fieldName, json.getString(fieldName));
Field f = userClass.getDeclaredField(fieldName);
f.setAccessible(true);
f.set(user, jsonObject.get(fieldName));
}
In the json data set, there are strings, doubles and more. This is part of a factory class where the type of object being returned is unknown at compile time. Also, the json fields' data types may vary depending on the type of object needed.
The json output matches the field names in the returned object, so I am looking for a way to handle the different data types returned in the json output. Can somebody offer up a suggestion?
Thx! Vivian
There are libraries available to aid in setting property values using reflection, converting to the appropriate type if necessary. For example, Spring Framework's BeanWrapper and Apache Commons BeanUtils.
There are also json libraries that will handle mapping json to/from java objects. For example, Gson and Jackson. This may make it easier, especially if the json structure closely matches the java object structure.

Jackson JSON converts integers into strings

I am using the object mapper to map into an object that has String variables. This works a little too well, because even integers and booleans from the JSON are converted into Strings.
Example:
{"my_variable":123}
class MyClass{
String my_variable;
}
I would like the object mapper to report an error in this kind of situation instead of converting 123 into a string for my_variable. Is this possible?
There is currently no such configuration, but you can override default deserializer with a custom one (see fasterxml wiki) and make that throw an exception?
If you would like a more convenient way you can file a Jira enhancement request; for example, new DeserializationConfig.Feature.COERCE_STRINGS_AS_NUMBERS (default to true) that one could disable to prevent such coercion.

Categories