Могут ли сгенерированные Avro классы использоваться напрямую с Spring HATEOAS EntityModel? - PullRequest
0 голосов
/ 08 октября 2019

Я пытаюсь использовать классы модели предметной области, сгенерированные из схемы с использованием avro-maven-plugin 1.8.2 с spring-hateoas 1.0.0.RELEASE (через Spring Boot 2.2.0.RC1). Среда Spring MVC 5.2.0.RELEASE выдает org.springframework.http.converter.HttpMessageNotWritableException во время сериализации EntityModel, созданного @RestController. EntityModel собирается с использованием подкласса SimpleIdentifiableRepresentationModelAssembler .

Отображение объектов Avro в POJO перед передачей их ассемблеру модели представления работает, как и ожидалось, во время сериализации, но дублирует модель доменане будет масштабироваться для этого приложения в долгосрочной перспективе. Я читал о пользовательских типах мультимедиа и, возможно, я мог бы сделать что-то подобное, скажем, для application/hal+avro+json, но это глубокая кроличья нора, чтобы спуститься для набора объектов, которые вне представлениямодели, легко сериализуются в простой JSON. Тем более что REST-клиентам на самом деле не нужна схема Avro, встроенная в эти объекты ... пока. Внутренние потребители Avro действительно нуждаются в этом.

FundController.java:

@Autowired
private final FundRepresentationModelAssembler assembler;

...

@GetMapping(value = "/funds/{id}")
public ResponseEntity<EntityModel<Fund>> findOne(@PathVariable final String id) {
  return this.repo.findById(id)
    .map(this.assembler::toModel)
    .map(ResponseEntity::ok)
    .orElse(ResponseEntity.notFound().build());
}

FundRepresentationModelAssembler.java:

@Component
public class FundRepresentationModelAssembler extends SimpleIdentifiableRepresentationModelAssembler<Fund> {
    public FundRepresentationModelAssembler() {
        super(FundController.class);
    }
}

Модель pom.xml:

<plugins>
  <plugin>
    <groupId>org.apache.avro</groupId>
    <artifactId>avro-maven-plugin</artifactId>
    <version>1.8.2</version>
    <executions>
      <execution>
        <phase>generate-sources</phase>
        <goals>
          <goal>schema</goal>
        </goals>
      </execution>
    </executions>
  </plugin>
  ...
</plugins>

Схема модели:

{"namespace": "org.example.model",
 "type": "record",
 "name": "Fund",
 "fields": [
     {"name": "id", "type": "string"},
     {"name": "description",  "type": "string"}
 ]
}

Хорошо отформатированная ошибка:

org.springframework.http.converter.HttpMessageNotWritableException:
  Could not write JSON:
    Not an array: {"type":"record","name":"Fund","namespace":"org.example.model","fields":[{"name":"id","type":"string"},{"name":"description","type":"string"}]}

nested exception is com.fasterxml.jackson.databind.JsonMappingException: 
  Not an array: {"type":"record","name":"Fund","namespace":"org.example.model","fields":[{"name":"id","type":"string"},{"name":"description","type":"string"}]} 

through reference chain: org.springframework.hateoas.EntityModel["content"]
  ->org.example.model.Fund["schema"]
    ->org.apache.avro.Schema$RecordSchema["elementType"]

Я надеюсь, что существует способ пропустить "подсказки сериализации" черезрамки HATEOAS Джексону.

...