Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/spring/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java JsonTypeInfo不';不能使用Hateoas EntityModel_Java_Spring_Jackson_Spring Hateoas_Hateoas - Fatal编程技术网

Java JsonTypeInfo不';不能使用Hateoas EntityModel

Java JsonTypeInfo不';不能使用Hateoas EntityModel,java,spring,jackson,spring-hateoas,hateoas,Java,Spring,Jackson,Spring Hateoas,Hateoas,我使用了两个具有继承性的类: @Entity @Data @Inheritance(strategy = InheritanceType.JOINED) @JsonIdentityInfo(generator = JSOGGenerator.class, property = "material_id", scope = Long.class) @EqualsAndHashCode(exclude = {"materialComme

我使用了两个具有继承性的类:

@Entity
@Data
@Inheritance(strategy = InheritanceType.JOINED)
@JsonIdentityInfo(generator = JSOGGenerator.class,
        property  = "material_id",
        scope = Long.class)
@EqualsAndHashCode(exclude = {"materialCommentaries"})
@ToString(exclude = {"materialCommentaries"})
@JsonTypeInfo(use = JsonTypeInfo.Id.CLASS)
public abstract class Material {
    @Id
    @Setter(AccessLevel.NONE)
    @GeneratedValue(strategy = GenerationType.SEQUENCE)
    private Long id;
    
    @ManyToOne(optional = false)
    private Lesson lesson;

    @NotNull
    private String title;

    @OneToMany(fetch = FetchType.LAZY, mappedBy = "material")
    private Set<MaterialCommentary> materialCommentaries;
}

@EqualsAndHashCode(callSuper = true)
@Entity
@Data
@ToString(callSuper = true)
public class VideoMaterial extends Material {
    private String summary;

    @JsonIgnore
    @ContentId
    private String contentId;

    @JsonIgnore
    @ContentLength
    private long contentLength;

    @JsonIgnore
    @MimeType
    private String mimeType;
}
和JSON作为回应:

{
    "@class": "ru.sstu.online_studying.entities.material.hierarchy.VideoMaterial",
    "material_id": "1",
    "id": 11,
    "lesson": {/*A lot of fields here*/},
    "title": "Title",
    "materialCommentaries": null,
    "summary": "Summary"
}
但当我尝试返回EntityModel时,我得到了不带@class字段的JSOn,并得到了异常:

com.fasterxml.jackson.databind.exc.InvalidTypeIdException: Missing type id when trying to resolve subtype of [simple type, class ru.sstu.online_studying.entities.material.hierarchy.VideoMaterial]: missing type id property '@class' (for POJO property 'content')
 at [Source: (String)"{"material_id":"1","id":11,"lesson":{"type":"Lesson","lesson_id":"2","id":10,"title":"TestLesson","description":"Test description","section":{"section_id":"3","id":9,"name":"Test","description":"Test descr","startDate":null,"closeDate":null,"course":{"course_id":"4","id":8,"title":"TestCourse","description":null,"maxNumStudents":null,"requirements":null,"image":null,"teachers":[{"user_id":"5","id":2,"username":"7LAWWtL","password":"$2a$10$o8FNl6krC/gEmXxNfI3ByOlmU7cmJoF9h4jWPztOIZB5opwhd59DK","f"[truncated 1554 chars]; line: 1, column: 2054]

    at com.fasterxml.jackson.databind.exc.InvalidTypeIdException.from(InvalidTypeIdException.java:43)
    at com.fasterxml.jackson.databind.DeserializationContext.missingTypeIdException(DeserializationContext.java:1771)
    at com.fasterxml.jackson.databind.DeserializationContext.handleMissingTypeId(DeserializationContext.java:1300)
    at com.fasterxml.jackson.databind.jsontype.impl.TypeDeserializerBase._handleMissingTypeId(TypeDeserializerBase.java:299)
    at com.fasterxml.jackson.databind.jsontype.impl.AsPropertyTypeDeserializer._deserializeTypedUsingDefaultImpl(AsPropertyTypeDeserializer.java:164)
    at com.fasterxml.jackson.databind.jsontype.impl.AsPropertyTypeDeserializer.deserializeTypedFromObject(AsPropertyTypeDeserializer.java:105)
    at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.deserializeWithType(BeanDeserializerBase.java:1196)
    at com.fasterxml.jackson.databind.deser.SettableBeanProperty.deserialize(SettableBeanProperty.java:527)
    at com.fasterxml.jackson.databind.deser.impl.ObjectIdReferenceProperty.deserializeSetAndReturn(ObjectIdReferenceProperty.java:94)
    at com.fasterxml.jackson.databind.deser.impl.ObjectIdReferenceProperty.deserializeAndSet(ObjectIdReferenceProperty.java:87)
    at com.fasterxml.jackson.databind.deser.impl.UnwrappedPropertyHandler.processUnwrapped(UnwrappedPropertyHandler.java:62)
    at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserializeWithUnwrapped(BeanDeserializer.java:673)
    at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserializeFromObject(BeanDeserializer.java:321)
    at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:159)
    at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:4218)
    at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:3214)
    at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:3197)
    at ru.sstu.online_studying.integration.controller.material.VideoMaterialControllerTest.save(VideoMaterialControllerTest.java:65)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.base/java.lang.reflect.Method.invoke(Method.java:567)
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
    at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
    at org.springframework.test.context.junit4.statements.RunBeforeTestExecutionCallbacks.evaluate(RunBeforeTestExecutionCallbacks.java:74)
    at org.springframework.test.context.junit4.statements.RunAfterTestExecutionCallbacks.evaluate(RunAfterTestExecutionCallbacks.java:84)
    at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
    at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:75)
    at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:86)
    at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:84)
    at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:251)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:97)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
    at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
    at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:190)
使用此JSON:

{
    "material_id": "1",
    "id": 11,
    "lesson": {/*a lot of fields here*/},
    "title": "Title",
    "materialCommentaries": null,
    "summary": "Summary",
    "_links": {
        "self": {
            "href": "http://localhost/api/video_materials/11"
        },
        "delete": {
            "href": "http://localhost/api/video_materials/11"
        },
        "updateContent": {
            "href": "http://localhost/api/video_materials/11/content"
        },
        "updateSummary": {
            "href": "http://localhost/api/video_materials/11/summary"
        }
    }
}
我认为,JsonIdentityInfo'material_id'仍然在这个JSON中,但@class消失了,这很奇怪。 返回EntityModel的My controller方法:

@PostMapping("video_materials")
public EntityModel<VideoMaterial> save(@RequestAttribute("material") VideoMaterial videoMaterial,
                                       @RequestParam("content") MultipartFile multipartFile,
                                       @AuthenticationPrincipal User creator) throws IOException {
    validateSavingRequest(videoMaterial, creator);
    return videoAssembler.toModel(videoMaterialService.save(videoMaterial, multipartFile));
}
@PostMapping("video_materials")
public EntityModel<VideoMaterial> save(@RequestAttribute("material") VideoMaterial videoMaterial,
                                       @RequestParam("content") MultipartFile multipartFile,
                                       @AuthenticationPrincipal User creator) throws IOException {
    validateSavingRequest(videoMaterial, creator);
    return videoAssembler.toModel(videoMaterialService.save(videoMaterial, multipartFile));
}
public EntityModel<VideoMaterial> toModel(VideoMaterial entity) {
    return new EntityModel<>(entity,
            linkTo(methodOn(controllerClass).getVideoContent(entity.getId(), null)).withSelfRel(),
            linkTo(methodOn(controllerClass).deleteVideoMaterial(entity.getId(), null)).withRel("delete"),
            linkTo(methodOn(controllerClass).updateVideoContent(entity.getId(), null, null)).withRel("updateContent"),
            linkTo(methodOn(controllerClass).updateSummary(entity.getId(), null, null)).withRel("updateSummary")

    );
}
mockMvc.perform(
                multipart("/api/video_materials/")
                        .file(mockMultipartFile)
                        .requestAttr("material", videoMaterial)
                        .with(user(sender))
        )
.andExpect(status().isOk())
.andExpect(content().contentType(MediaTypes.HAL_JSON)
.andReturn()
.getResponse()
.getContentAsString()