Spring and Gson - Expose fields only on certain conditions

1k Views Asked by At

I'm using Spring with Gson to object serialization.

I have model objects that use @Expose annotation e.g.:

public class Zone {
    @Expose
    private String name;
    @Expose
    private String description;
    @Expose
    private List<String> longList;

    private String someIrrelevantVar;
}

I'm have 2 controllers which serves Zone objects list to user e.g.:

@RestController
class ZoneController {
    @GetMapping(value = "fullData")
    List<Zone> getFullZones() {
        return zoneService.getZones();
    }
}

@RestController
class SimpleZoneController {
    @GetMapping(value = "simpleData")
    List<Zone> getSimpleZones() {
        return zoneService.getZones();
    }
}

The problem is List<String> longList var - it usually has a lot of entries (String is only example, in code it could be complex object).

In my getFullZones() I want to serve to user zones with this longList but in getSimpleZones() I want ot serve zones without longList (it's not used in any way on the client side).

How to do that?

I could iterate list with zones and set longList to null but it's not very elegant solution.

I'm setting up Spring to use Gson like this:

@Configuration
public class WebMvcConfig extends WebMvcConfigurerAdapter {
    @Override
    public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
        converters.add(createGsonHttpMessageConverter());
        super.configureMessageConverters(converters);
    }
    private GsonHttpMessageConverter createGsonHttpMessageConverter() {
        Gson gson = new GsonBuilder()
                .excludeFieldsWithoutExposeAnnotation()
                //.registerTypeAdapter - register some deserializers
                .create();
        GsonHttpMessageConverter gsonConverter = new GsonHttpMessageConverter();
        gsonConverter.setGson(gson);

        return gsonConverter;
    }
}
1

There are 1 best solutions below

6
StanislavL On

Create a base class ZoneSimple and extend another class Zone extends ZoneSimple. Move the @Expose from fields to methods.

In the base class the method has no annotation. In the Zone the method is annotated.

Alternatively you can add a ProxyZone class which keeps zone instance and delegates all the calls to the instance. Annotate the Proxy as you need.

Another way is

 Gson gson = new GsonBuilder()
        .addSerializationExclusionStrategy(new ExclusionStrategy() {
            @Override
            public boolean shouldSkipField(FieldAttributes f) {
                return f.getName().toLowerCase().contains("fieldName");
            }

            @Override
            public boolean shouldSkipClass(Class<?> aClass) {
                return false;
            }
        })
        .create();

Got from the answer