gpt4 book ai didi

java - 在 @OneToMany Set 上使用 @JsonSerialize(using=MySerializer.class)
转载 作者:行者123 更新时间:2023-12-05 07:46:40 24 4
gpt4 key购买 nike

在 Spring Boot/Spring Data Rest 项目中,我在使用自定义 JsonSerializer<Set<Object>> 时遇到问题在 @OneToMany 属性上。当我执行 HTTP GET/collection 请求时,出现以下错误:

Failed to write HTTP message: org.springframework.http.converter.HttpMessageNotWritableException: Could not write content: Can not override serializer (through reference chain: org.springframework.hateoas.Resources["_embedded"]->java.util.UnmodifiableMap["analogParameters"]->java.util.ArrayList[0]); nested exception is com.fasterxml.jackson.databind.JsonMappingException: Can not override serializer (through reference chain: org.springframework.hateoas.Resources["_embedded"]->java.util.UnmodifiableMap["analogParameters"]->java.util.ArrayList[0])

下面是我的实体类的摘录:

@OneToMany(cascade=CascadeType.ALL)
@JoinColumn(name="output_parameter_id")
@JsonSerialize(using=InputParametersSerializer.class)
//@Transcient
private Set<InputParameter> inputParameters = new HashSet<InputParameter>();

public Set<InputParameter> getInputParameters() {
return inputParameters;
}

public void setInputParameters(Set<InputParameter> inputParameters) {
this.inputParameters = inputParameters;
}

还有 JsonSerializer<Set<InputParameter>>

public class InputParametersSerializer 
extends JsonSerializer<Set<InputParameter>> {

static final long serialVersionUID = 123L;

public void serialize (Set<InputParameter> ips, JsonGenerator jg,
SerializerProvider sp)
throws IOException {

jg.writeString("Yeah");

}

}

如果我删除@OneToMany 并将该属性定义为@transient,它将按预期工作。

InputParameter 实体没有关联的 Repository(它不作为 rest 资源导出)。

如何在@OneToMany 属性上使用 JsonSerializer?

最佳答案

我在使用 Spring Boot 2.1.0 时遇到了一个非常相似的问题。添加自定义序列化器,同时使用 usingkeyUsing,工作正常,但是带有 @OneToMany 注释字段的自定义反序列化器抛出相同的 JsonMappingException: Can not override serializer 消息,而使用 @ElementCollection 它只是简单地被忽略。我怀疑 Spring Data Rest 做了一些未记录的魔术,以便处理这些类型的字段的(反)序列化,这些字段在添加自定义反序列化器时效果不佳。我的解决方法是通过带注释的 getter 和 setter 添加一个额外的 JSON 字段。对于您的示例,它看起来像:

@OneToMany(cascade=CascadeType.ALL)
@JoinColumn(name="output_parameter_id")
private Set<InputParameter> inputParameters = new HashSet<InputParameter>();

public Set<InputParameter> getInputParameters() {
return inputParameters;
}

public void setInputParameters(Set<InputParameter> inputParameters) {
this.inputParameters = inputParameters;
}


@JsonSerialize(using=InputParametersSerializer.class)
public Set<InputParameter> getInputParametersSet() {
return getInputParameters();
}


@JsonDeserialize(using=InputParametersDeserializer.class)
public void setInputParametersSet(Set<InputParameter> inputParameters) {
setInputParameters(inputParameters);
}

这会输出类似的东西

{
...
"inputParameters" : ...,
"inputParametersSet" : ...,
...
}

虽然不理想,但该字段的序列化和反序列化按预期工作。或者,为了保留字段名称,类似的解决方法适用于 @ElementCollection不适用于 @OneToMany:

@OneToMany(cascade=CascadeType.ALL)
@JoinColumn(name="output_parameter_id")
@JsonIgnore
private Set<InputParameter> inputParameters = new HashSet<InputParameter>();

public Set<InputParameter> getInputParameters() {
return inputParameters;
}

public void setInputParameters(Set<InputParameter> inputParameters) {
this.inputParameters = inputParameters;
}


@JsonProperty("inputParameters")
@JsonSerialize(using=InputParametersSerializer.class)
public Set<InputParameter> getInputParametersSet() {
return getInputParameters();
}

@JsonProperty("inputParameters")
@JsonDeserialize(using=InputParametersDeserializer.class)
public void setInputParametersSet(Set<InputParameter> inputParameters) {
setInputParameters(inputParameters);
}

最后我不得不采用第一种方法。

关于java - 在 @OneToMany Set<Object> 上使用 @JsonSerialize(using=MySerializer.class),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40490867/

24 4 0