Exclusion on Value. (Kind of ExclusionStrategy)

1,389 views
Skip to first unread message

Jean-Marc Spaggiari

unread,
Jul 3, 2012, 2:08:01 PM7/3/12
to googl...@googlegroups.com
Hi,

With the interface ExclusionStrategy it's possible to exclude a field to be serialized based on it's title. But is there a way to filter based on the value?

Let's take this example:

public class MyData
{
  private temperature = -1;

...
}

-1 is the default value for this field. It can be update if required.

If this value is not updated, Gson will generate this: {"temperature":"-1"}
If I parse it, that's fine, I get temperature == -1.
But if Gson generates this: {}
I will still get temperature == -1 because it's the default value, which is correct too.

So my goal is to exclude from the stream the fields which contain specific values (Default values).

I took a look at the code and I don't really see how I can add that easily.

The filters are applied in ReflectiveTypeAdapterFactory.getBoundFields but we don't have acces to values there. I had to go up to Gson.toJson to find the values.

So one option will be to pass "src" to the getAdapter method to have access to the values and to implement another interface for the ValueBased exclusion. But is there any other way do achieve this goal? If not, is that a good idea and should it be implemented in Gson or should I do that on my own if I need that?

The goal i to reduce the size of the stream and so reduce the bandwidth usage (i.e. inscrease of the speed).

Thanks,

JM

Inderjeet Singh

unread,
Jul 12, 2012, 8:14:55 PM7/12/12
to googl...@googlegroups.com
You dont have the option to exclude based on the value in an exclusion strategy. Gson tries to achieve efficiency by making decisions to include/exclude fields once per class (while finding its type adapter). Providing you ability to select based on value would run counter to that.

BTW, You can write a custom type adapter for MyData that excludes temperature if it is -1. Is that not a good enough option?

HTH
Inder

Jean-Marc Spaggiari

unread,
Jul 13, 2012, 11:38:37 AM7/13/12
to googl...@googlegroups.com
Hi Inder,

I'm not sure this will really be helpfull. I don't want to
re-implement all what Gson is already doing in the Serializer just to
remove one value. I will take a look at the default serializer and see
if I can extend it to add some customization. That might be an option,
but I will still try to investigate other options.(like simply
removing "temperature=-1" from the output string, etc.)

Thanks,

JM

2012/7/12, Inderjeet Singh <inde...@gmail.com>:
> --
> You received this message because you are subscribed to the Google Groups
> "google-gson" group.
> To view this discussion on the web visit
> https://groups.google.com/d/msg/google-gson/-/srk_TiKgW6cJ.
> To post to this group, send email to googl...@googlegroups.com.
> To unsubscribe from this group, send email to
> google-gson...@googlegroups.com.
> For more options, visit this group at
> http://groups.google.com/group/google-gson?hl=en.
>
>

Maaartin

unread,
Jul 19, 2012, 11:27:48 AM7/19/12
to googl...@googlegroups.com
On Tuesday, July 3, 2012 8:08:01 PM UTC+2, Jean-Marc Spaggiari wrote:
> With the interface ExclusionStrategy it's possible to exclude a field to be serialized based on it's title. But is there a way to filter based on the value?

+1, that's what I just wanted to ask. My case is nearly the same, except for `{sizeLimit: 9223372036854775807}` looking even worse. I don't want to use -1 there as `Long.MAX_VALUE` is the natural choice here, nor I want to use null as `Long` instead of `long`.

On Friday, July 13, 2012 2:14:55 AM UTC+2, Inderjeet Singh wrote:
> You dont have the option to exclude based on the value in an exclusion strategy. Gson tries to achieve efficiency by making decisions to include/exclude fields once per class (while finding its type adapter). Providing you ability to select based on value would run counter to that.

Concerning the efficiency I beg to differ. Sure, excluding fields on the class basis is good for efficiency, but I don't think you lose any when you do an additional check if a field not-excluded on the per-class bases could be excluded based on its value.

> BTW, You can write a custom type adapter for MyData that excludes temperature if it is -1. Is that not a good enough option?

I'd strongly prefer something like

class MyData {
    @GsonExcludeIfValue(Long.MAX_VALUE)
    private long sizeLimit = Long.MAX_VALUE;
    @GsonExcludeIfValue(-1)
    private int temperature = -1;
}

or maybe

class MyData {
    @GsonDefaultValuesProvider
    private static defaultInstance = new MyData();
    private sizeLimit = Long.MAX_VALUE;
    private int temperature = -1;
}

where each value would be tested against the value in defaultInstance, or maybe

@GsonExcludeDefaultValue
class MyData {
    private sizeLimit = Long.MAX_VALUE;
    private int temperature = -1;
}

where GSon would determine the default values by deserializing an object with missing values. The last idea mightn't work.

Jean-Marc Spaggiari

unread,
Jul 19, 2012, 4:45:15 PM7/19/12
to googl...@googlegroups.com
I like options 1 and 3.

I think the 3rd one will really be a good enhancement.

Regarding the efficiency, if those data has to be transfered over a
network, you might loose checks time what you are going to save in
transfert and storage time.

For now, what I'm doing is "simply" parsing the output string to
remove the default values by comparing them from a brand new instance
Gson string. So having something like @GsonExcludeDefaultValue might
help a lot.

2012/7/19, Maaartin <maaar...@gmail.com>:
> --
> You received this message because you are subscribed to the Google Groups
> "google-gson" group.
> To view this discussion on the web visit
> https://groups.google.com/d/msg/google-gson/-/wPmRfO1CZDkJ.

Inderjeet Singh

unread,
Jul 25, 2012, 4:49:51 PM7/25/12
to googl...@googlegroups.com
Can you file a feature request on the Gson project page with the following options?
We will evaluate it for our next release.

Thanks
Inder

Maaartin

unread,
Jul 29, 2012, 9:29:32 PM7/29/12
to googl...@googlegroups.com
Actually, this feature is strongly related to serializeNulls:

Quite often, nulls needn't be serialized as they're there anyway. But sometimes the default value differs and then there's a (probably well-known) problem:

public static class N {
String s = "NON NULL";
}

final N original = new N();
original.s = null;
final String json = gson.toJson(original);
final N fromJson = gson.fromJson(json, N.class);
Assert.assertEquals(original.s, fromJson.s);

Here, `GsonBuilder.serializeNulls()` helps, but this is no solution, it's a workaround. The proper condition for a field being excluded is not the test if it's null, but the test that it has its default value.

So I don't think we need any annotation, something like `GsonBuilder.serializeNonDefault()` could do the right thing: serialize a field IFF it differs from its default value.

Here, the default value should be taken from the object created by the `ObjectConstructor`. This way it should work even when a custom `InstanceCreator` gets used.

Put differently:
- A newly constructed object is considered empty, no matter what it contains.
- The natural representation for an empty object is "{}".
- Any difference from the empty object must be recorded in JSON, changes to null are no exception here.
- What didn't change should be omitted, nulls are no exception here either.

I've attached a small patch (unfortunatelly, written before I realized that no annotation is needed). The test can be found here:

0001-Implement-OmitDefaultValue.patch

Maaartin

unread,
Aug 9, 2012, 7:15:35 PM8/9/12
to googl...@googlegroups.com
Just in case somebody's interested: I've implemented `GsonBuilder.omitDefaultValue()` which makes the annotation from the previous patch mostly useless. This setting works for all classes, the annotation can be used for switching the behavior on or off on per class or field basis - if needed. I did only few rudimentary tests - use with caution and at own risk.

0001-Add-GsonBuilder.omitDefaultValue.patch

Jean-Marc Spaggiari

unread,
Nov 21, 2012, 8:54:15 PM11/21/12
to googl...@googlegroups.com
Hi Maaartin,

Any chance for your last patch to be integrated on the main branch for
the next release? Or I will have to build a "customed" version of GSon
if I want to deploy this on production servers?

JM

2012/8/9, Maaartin <maaar...@gmail.com>:
> --
> You received this message because you are subscribed to the Google Groups
> "google-gson" group.
> To view this discussion on the web visit
> https://groups.google.com/d/msg/google-gson/-/_gpcau0adxsJ.
> To post to this group, send email to googl...@googlegroups.com.
> To unsubscribe from this group, send email to
> google-gson...@googlegroups.com.

Maaartin

unread,
Nov 21, 2012, 11:01:17 PM11/21/12
to googl...@googlegroups.com
On Thursday, November 22, 2012 2:54:17 AM UTC+1, Jean-Marc Spaggiari wrote:
Hi Maaartin,

Any chance for your last patch to be integrated on the main branch for
the next release? Or I will have to build a "customed" version of GSon
if I want to deploy this on production servers?

Hi Jean-Marc,

I argued[1] that the suggested workaround is very impractical and that's about all I can do here.

Regards, Maaartin.


Jean-Marc Spaggiari

unread,
Nov 22, 2012, 7:58:13 AM11/22/12
to googl...@googlegroups.com
Yep, I saw your comment on the defect. I thought there will have been
some movement around that but saw nothing...

So I will try to add your patch on my jar. Today I'm using GSon 2.2.2
but on SVN I have extracted the trunk only and I don't know how to
extract a specific 2.2.2 snapshot and build it.

svn checkout http://google-gson.googlecode.com/svn/trunk/

Is there some documentation anywhere that I can followup to locally
build 2.2.2 so I can add your patch in my jar?

Thanks,

JM

2012/11/21, Maaartin <maaar...@gmail.com>:
> --
> You received this message because you are subscribed to the Google Groups
> "google-gson" group.
> To view this discussion on the web visit
> https://groups.google.com/d/msg/google-gson/-/dW5_HK-UxTsJ.

Maaartin

unread,
Nov 22, 2012, 9:20:07 PM11/22/12
to googl...@googlegroups.com
On Thursday, November 22, 2012 1:58:15 PM UTC+1, Jean-Marc Spaggiari wrote:
Yep, I saw your comment on the defect. I thought there will have been
some movement around that but saw nothing...

So I will try to add your patch on my jar. Today I'm using GSon 2.2.2
but on SVN I have extracted the trunk only and I don't know how to
extract a specific 2.2.2 snapshot and build it.

svn checkout http://google-gson.googlecode.com/svn/trunk/

I looked at the URL with browser, went one step up, and found

In case you love SVN as much as I do, you could try

to get it into a usable system (it takes ages and might or might not give you all the tags).
 
Is there some documentation anywhere that I can followup to locally
build 2.2.2 so I can add your patch in my jar?

No idea, but looking how I imported it into my eclipse, I'd say it should simply work as is.
When you leave out gson/src/test, you'll need no dependencies at all.
However, running the test might be a good idea given the changes.

Reply all
Reply to author
Forward
0 new messages