InvalidDefinitionException: No serializer found for class


# 事象 : 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で受け取ろうとした。

```java
@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();
	}
```

```java: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>();
}
```

<details><summary>処理を動かしたら怒られた(クリックでConsoleのログ参照)</summary><div>

```bash
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
```

</div></details>

## 原因 : 普通のGetterとSetterを使ってシリアライズできないから
参考

- [jacksonで正体不明のJSONを読み込む - Qiita](https://qiita.com/kivatek/items/5e2bee93419ec9bda289)
- [Java : Jackson : ちょっと特殊なケースにおけるJSONシリアライズ／デシリアライズ | TECHSCORE BLOG](https://www.techscore.com/blog/2016/12/18/java-jackson-serialize-deserialize/)

### 対応 : @JsonAnyGetterと@JsonAnySetterを使う
```java
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);
	}
}
```