事象 : InvalidDefinitionException: No serializer found for class
- 環境
- Windows10 Pro バージョン1909
- Spring Tool Suite 4 Version: 4.7.2.RELEASE
- java version "1.8.0_251"
- spring-web 5.0.8
- jackson-annotations 2.9.0
- jackson-databind 2.9.6
APIのレスポンスのJSONをちゃんとBeanを定義しないでふわっとMapで受け取ろうとした。
@Service
public class HogeServiceImpl implements HogeService {
@Override
public HogeApiRes[] getData(HogeReq HogeReq) {
RestTemplate restTemplate = new RestTemplate();
ResponseEntity<HogeApiRes[]> responseEntity = restTemplate.getForEntity("http://example.com/api", HogeApiRes[].class);
return responseEntity.getBody();
}
GetterとSetterはlombokの@Dataでいいや的な。
import com.fasterxml.jackson.annotation.JsonIgnore;
import lombok.Data;
@Data
public class HogeApiRes {
@JsonIgnore
protected Map<String, Object> additionalProperties = new HashMap<String, Object>();
}
処理を動かしたら怒られた(クリックでConsoleのログ参照)
Caused by: com.fasterxml.jackson.databind.exc.InvalidDefinitionException: No serializer found for class com.sample.HogeApiRes and no properties discovered to create BeanSerializer (to avoid exception, disable SerializationFeature.FAIL_ON_EMPTY_BEANS) (through reference chain: com.sample.HogeRes["responses"]->com.sample.HogeApiRes[0])
at com.fasterxml.jackson.databind.exc.InvalidDefinitionException.from(InvalidDefinitionException.java:77) ~[jackson-databind-2.9.6.jar:2.9.6]
at com.fasterxml.jackson.databind.SerializerProvider.reportBadDefinition(SerializerProvider.java:1191) ~[jackson-databind-2.9.6.jar:2.9.6]
at com.fasterxml.jackson.databind.DatabindContext.reportBadDefinition(DatabindContext.java:312) ~[jackson-databind-2.9.6.jar:2.9.6]
at com.fasterxml.jackson.databind.ser.impl.UnknownSerializer.failForEmpty(UnknownSerializer.java:71) ~[jackson-databind-2.9.6.jar:2.9.6]
at com.fasterxml.jackson.databind.ser.impl.UnknownSerializer.serialize(UnknownSerializer.java:33) ~[jackson-databind-2.9.6.jar:2.9.6]
at com.fasterxml.jackson.databind.ser.std.ObjectArraySerializer.serializeContents(ObjectArraySerializer.java:249) ~[jackson-databind-2.9.6.jar:2.9.6]
at com.fasterxml.jackson.databind.ser.std.ObjectArraySerializer.serialize(ObjectArraySerializer.java:210) ~[jackson-databind-2.9.6.jar:2.9.6]
at com.fasterxml.jackson.databind.ser.std.ObjectArraySerializer.serialize(ObjectArraySerializer.java:22) ~[jackson-databind-2.9.6.jar:2.9.6]
at com.fasterxml.jackson.databind.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:727) ~[jackson-databind-2.9.6.jar:2.9.6]
at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:719) ~[jackson-databind-2.9.6.jar:2.9.6]
at com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:155) ~[jackson-databind-2.9.6.jar:2.9.6]
at com.fasterxml.jackson.databind.ser.DefaultSerializerProvider._serialize(DefaultSerializerProvider.java:480) ~[jackson-databind-2.9.6.jar:2.9.6]
at com.fasterxml.jackson.databind.ser.DefaultSerializerProvider.serializeValue(DefaultSerializerProvider.java:319) ~[jackson-databind-2.9.6.jar:2.9.6]
at com.fasterxml.jackson.databind.ObjectWriter$Prefetch.serialize(ObjectWriter.java:1396) ~[jackson-databind-2.9.6.jar:2.9.6]
at com.fasterxml.jackson.databind.ObjectWriter.writeValue(ObjectWriter.java:913) ~[jackson-databind-2.9.6.jar:2.9.6]
at org.springframework.http.converter.json.AbstractJackson2HttpMessageConverter.writeInternal(AbstractJackson2HttpMessageConverter.java:288) ~[spring-web-5.0.8.RELEASE.jar:5.0.8.RELEASE]
... 87 common frames omitted
原因 : 普通のGetterとSetterを使ってシリアライズできないから
参考
対応 : @JsonAnyGetterと@JsonAnySetterを使う
import com.fasterxml.jackson.annotation.JsonAnyGetter;
import com.fasterxml.jackson.annotation.JsonAnySetter;
import com.fasterxml.jackson.annotation.JsonIgnore;
public class HogeApiRes {
@JsonIgnore
protected Map<String, Object> additionalProperties = new HashMap<String, Object>();
@JsonAnyGetter
public Map<String, Object> getAdditionalProperties() {
return this.additionalProperties;
}
@JsonAnySetter
public void setAdditionalProperty(String name, Object value) {
this.additionalProperties.put(name, value);
}
}