Most of the json serializations work using object property accessors like getter and setter methods. I am trying to serialize third party object with no get/set methods(and I don't have control to modify source) to json and send over REST service.
But the final json produced doesn't have all the properties data as like in my object. This is obvious due to no accessor methods.
Is there any other way I can prepare JSON in this scenario?
Otherwise, is there any other way I can send this 3rd party object over my rest service as is without compromising on it's properties values? (I considered like object serialization and send using streams, but that looks like unconventional).
Maybe most. GSON on the other hand uses reflection to directly setup fields. You actually have to force it to not use reflection (see Gson avoid reflection).
So one solution would be to use that library. And just to be precise: gson uses reflection to identify the fields in your bean classes directly, without relying on getters/setters.
Related
I need to make a DTO class that represents a JSON request body.
I’d like to make it fully immutable with final fields. I’ve already seen implementations based on #JSONCreator all args constructor but I also require one more feature.
The DTO class should be flexible and tolerate some missing fields in a request meanwhile ensure that all necessary properties are in-place.
Could you provide me an example of such DTO, please?
Jackson will automatically handle missing fields and just set those fields to null.
It also has some configuration options on whether when serializing responses, null fields should be omitted or set to the special value null.
objectMapper.setSerializationInclusion(Include.NON_NULL);
On another note, if you are designing an API, you might want to look at Swagger / OpenAPI and define your API declaratively from there (you can specify whether a field is optional or required). Then use the codegen tools to automaticlly generate your DTOs. (They will follow the best patterns and also offer Fluent API style setters).
As #jbx pointed out that Jackson automatically handles missing fields and sets it to null.
If you want to ensure that required fields are populated, you need to mark those as #javax.annotation.Nonnull or lombok.NonNull.
Using this Jackson throws a NullPointerException if that field in null while de-serialization of request to DTO class.
What serializer is Entity.json(T entity) using to serialize/deserialize objects? Is it somehow possible to use a custom serializer?
In my case the serialization is wrong because my object contains fields with the Guava Optional data type and absent values are returned as {"present":false} instead of null.
The JSON serializer isn't specified by JAX-RS, it depends on your configuration. For example, Jersey JAX-RS allows several (https://jersey.java.net/documentation/latest/media.html), including
MOXy
Java API for JSON Processing (JSON-P)
Jackson
Jettison
But a better solution is not to use Optional (either Guava or Java 8) for fields. See http://blog.joda.org/2014/11/optional-in-java-se-8.html
My only fear is that Optional will be overused. Please focus on using
it as a return type (from methods that perform some useful piece of
functionality) Please don't use it as the field of a Java-Bean.
Not directly solving your problem. I suggest you use Googles Gson as a parser. It is very flexible and configurable.
Tutorial
It also skips blank fields so the json size is not too large.
I am writing a REST API with a Java/Jersey/Jackson stack. All JSON parsing and generating is done with Jackson. The REST layer is handled by Jersey. It will be embedded in a Grizzly container.
In my API, I accept JSON in my endpoints. For example:
#POST
public Response post(final SomeObject input) {
return ...;
}
What is the best way to validate the input? There are certain things I would like to validate:
input must be not null
certain fields of input must be not null
certain fields of input must follow a regular expression (text fields)
certain fields of input must be in a range (numeric fields)
...
If possible, I would like to change my code as less as possible. That is, I prefer to annotate my classes, methods and parameters to integrate the validation.
You can use a JSON Schema.
And since you use Jackson, you can use my library which does exactly that.
However this means you'd need to change your logic so that you receive the JSON (as a JsonNode) instead of the serialized POJO, and only then serialize to your POJO.
You can also BeanValidationApi (javax.validation.constraints) and then annotate your fields with #NotNull,#Pattern, etc. Jersey also provides Bean Validation Support
I am using Axis to call a SOAP-based web service. I'm then trying to serialize the returned remote object as JSON, using the Google Gson library.
The serialization to JSON fails, with Gson complaining that "there are multiple elements with the name __equalsCalc()).
When I inspect the returned object in my IDE (Eclipse), I can see that this is true -- the returned object has three members called __equalsCalc() and another three called __hashCode.
I know from looking around that these are added by WSDL2Java (I think) in order to avoid recursion. My question is, why are there THREE of each? And how can I get the serializer to ignore these? They're not actually part of the object's definition (it's called a RemoteProject, for reference). Can I do something hackish like cast the RemoteProject to a RemoteProject to get it to drop those members?
This turns out to be not too hard to solve. I have multiple copies of the same instance var because the class being serialized is shadowing fields of the same name from superclasses. Since I don't care about these fields, the best approach in Gson is to write a custom ExckusionStrategy which can selectively ignore fields based on their name:
http://google-gson.googlecode.com/svn/trunk/gson/docs/javadocs/com/google/gson/ExclusionStrategy.html
I don't know GSon.
With Jackson, you can annotate properties (i.e - fields that have getters/setters according to Java bean convention) with #JsonIgnore.
This way you can prevent issues like recursion/no matching setter or getter and so on...
Try to find out if you have the same at GSon or use Jackson.
Why does GSON use ONLY fields(private,public,protected)?
Is there a way to tell GSON to use only getters and setters?
Generally speaking when you serialize/deserialize an object, you are doing so to end up with an exact copy of the state of the object; As such, you generally want to circumvent the encapsulation normally desired in an OO design. If you do not circumvent the encapsulation, it may not be possible to end up with an object that has the exact same state after deserialization as it had prior to serialization. Additionally, consider the case where you do not want to provide a setter for a particular property. How should serialization/deserialization act if you are working through the getters and setters?
Is there a way to tell GSON to use only getters and setters?
Not yet.
From the design doc:
[T]here are good arguments to support properties as well. We intend to enhance Gson in a latter version to support properties as an alternate mapping for indicating Json fields. For now, Gson is fields-based.
It is possible to to patch Gson to use getters.
The vague outline of how this works in our app is that we have a lot of TypeAdapter implementations - some for specific value-like objects and some for bean-style objects where we know that JavaBeans logic will work. We then jam all of these onto a GsonBuilder before creating the Gson object.
Unfortunately, GSON is really crap at handling types like Object[]. We mostly saw this when we were trying to make a JSON object to represent method parameters. The workaround for that was to make custom TypeAdapter instances which reflect the methods. (This does mean that you end up using one Gson instance per method you intend to call...)