【问题标题】:Spring and Gson - Expose fields only on certain conditionsSpring 和 Gson - 仅在特定条件下公开字段
【发布时间】:2017-08-08 12:35:14
【问题描述】:

我正在使用带有 Gson 的 Spring 进行对象序列化。

我有使用 @Expose 注释的模型对象,例如:

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

    private String someIrrelevantVar;
}

我有 2 个控制器,它们为用户提供 Zone 对象列表,例如:

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

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

问题是List&lt;String&gt; longList var - 它通常有很多条目(String 只是示例,在代码中它可能是复杂对象)。

在我的getFullZones() 中,我想使用这个longList 为用户区域提供服务,但在getSimpleZones() 中,我想为没有longList 的区域提供服务(它不会以任何方式在客户端使用)。

怎么做?

我可以使用区域迭代列表并将 longList 设置为 null,但这不是非常优雅的解决方案。

我正在设置 Spring 以像这样使用 Gson

@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;
    }
}

【问题讨论】:

    标签: java spring serialization gson spring-json


    【解决方案1】:

    创建一个基类 ZoneSimple 并扩展另一个类 Zone extends ZoneSimple。将 @Expose 从字段移动到方法。

    在基类中,方法没有注释。在区域中,方法被注释。

    或者,您可以添加一个 ProxyZone 类,该类保留区域实例并将所有调用委托给该实例。根据需要对代理进行注释。

    另一种方法是

     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();
    

    来自the answer

    【讨论】:

    • @Expose 仅适用于字段,不适用于方法。你能用ProxyZone解释解决方案吗?第三种解决方案在我的情况下如何工作?
    • 对不起,我错过了 @Expose 仅​​应用于字段。然后您可以尝试基于addSerializationExclusionStrategy 的方法
    • 但在这种情况下如何使用ExclusionStrategy?我只有一个Gson 实例(在WebMvcConfigurerAdapter 中创建),如果我在Zone 类的某些字段中添加ExclusionStrategy,它将在任何地方生效。或者我应该在我的getSimpleZones() 方法中创建新的Gson 实例并在那里添加ExclusionStrategy
    • 动态创建 GsonBuilder 而不是使用自动装配。
    • 我不是指@Autowired Gson,而是Gson注册为HttpMessageConverter,在序列化任何数据时默认使用
    猜你喜欢
    • 2016-09-23
    • 2021-12-16
    • 2020-07-23
    • 1970-01-01
    • 2021-11-16
    • 1970-01-01
    • 2022-11-27
    • 2021-01-24
    • 1970-01-01
    相关资源
    最近更新 更多