[SPRING] 스프링 부트 @ResponseBody가 엔티티 ID를 직렬화하지 않습니다.
SPRING스프링 부트 @ResponseBody가 엔티티 ID를 직렬화하지 않습니다.
이상한 문제가있어서 그것을 처리하는 방법을 알 수 없습니다. 단순한 POJO :
@Entity
@Table(name = "persons")
public class Person {
@Id
@GeneratedValue
private Long id;
@Column(name = "first_name")
private String firstName;
@Column(name = "middle_name")
private String middleName;
@Column(name = "last_name")
private String lastName;
@Column(name = "comment")
private String comment;
@Column(name = "created")
private Date created;
@Column(name = "updated")
private Date updated;
@PrePersist
protected void onCreate() {
created = new Date();
}
@PreUpdate
protected void onUpdate() {
updated = new Date();
}
@Valid
@OrderBy("id")
@OneToMany(mappedBy = "person", fetch = FetchType.EAGER, cascade = CascadeType.ALL, orphanRemoval = true)
private List<PhoneNumber> phoneNumbers = new ArrayList<>();
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getMiddleName() {
return middleName;
}
public void setMiddleName(String middleName) {
this.middleName = middleName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public String getComment() {
return comment;
}
public void setComment(String comment) {
this.comment = comment;
}
public Date getCreated() {
return created;
}
public Date getUpdated() {
return updated;
}
public List<PhoneNumber> getPhoneNumbers() {
return phoneNumbers;
}
public void addPhoneNumber(PhoneNumber number) {
number.setPerson(this);
phoneNumbers.add(number);
}
@Override
public String toString() {
return ToStringBuilder.reflectionToString(this, ToStringStyle.SHORT_PREFIX_STYLE);
}
}
@Entity
@Table(name = "phone_numbers")
public class PhoneNumber {
public PhoneNumber() {}
public PhoneNumber(String phoneNumber) {
this.phoneNumber = phoneNumber;
}
@Id
@GeneratedValue
private Long id;
@Column(name = "phone_number")
private String phoneNumber;
@ManyToOne
@JoinColumn(name = "person_id")
private Person person;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getPhoneNumber() {
return phoneNumber;
}
public void setPhoneNumber(String phoneNumber) {
this.phoneNumber = phoneNumber;
}
public Person getPerson() {
return person;
}
public void setPerson(Person person) {
this.person = person;
}
@Override
public String toString() {
return ToStringBuilder.reflectionToString(this, ToStringStyle.SHORT_PREFIX_STYLE);
}
}
휴식 종점 :
@ResponseBody
@RequestMapping(method = RequestMethod.GET)
public List<Person> listPersons() {
return personService.findAll();
}
json 응답에는 ID를 제외한 모든 필드가 있습니다.이 필드는 편집 / 삭제하기 위해 프런트 엔드 측에서 필요합니다. ID를 직렬화하기 위해 스프링 부트를 어떻게 구성 할 수 있습니까?
이것이 바로 응답의 모습입니다.
[{
"firstName": "Just",
"middleName": "Test",
"lastName": "Name",
"comment": "Just a comment",
"created": 1405774380410,
"updated": null,
"phoneNumbers": [{
"phoneNumber": "74575754757"
}, {
"phoneNumber": "575757547"
}, {
"phoneNumber": "57547547547"
}]
}]
UPD 양방향 Hibernate 매핑을 가지고 있습니다. 어쩌면 문제와 관련이있을 수 있습니다.
해결법
-
==============================
1.나는 최근에 같은 문제가 있었는데, 그 이유는 스프링 부트 스타터 데이터 휴지가 기본적으로 어떻게 작동하는지 때문이다. 내 SO 질문보기 -> 응용 프로그램을 Spring Boot로 마이그레이션 한 후 Spring Data Rest를 사용하는 동안 @Id가있는 엔티티 속성이 더 이상 JSON에 마샬링되지 않는다는 것을 관찰했다.
나는 최근에 같은 문제가 있었는데, 그 이유는 스프링 부트 스타터 데이터 휴지가 기본적으로 어떻게 작동하는지 때문이다. 내 SO 질문보기 -> 응용 프로그램을 Spring Boot로 마이그레이션 한 후 Spring Data Rest를 사용하는 동안 @Id가있는 엔티티 속성이 더 이상 JSON에 마샬링되지 않는다는 것을 관찰했다.
동작 방식을 사용자 정의하려면 RepositoryRestConfigurerAdapter를 확장하여 특정 클래스의 ID를 표시 할 수 있습니다.
import org.springframework.context.annotation.Configuration; import org.springframework.data.rest.core.config.RepositoryRestConfiguration; import org.springframework.data.rest.webmvc.config.RepositoryRestConfigurerAdapter; @Configuration public class RepositoryConfig extends RepositoryRestConfigurerAdapter { @Override public void configureRepositoryRestConfiguration(RepositoryRestConfiguration config) { config.exposeIdsFor(Person.class); } }
-
==============================
2.@ eric-peladan의 답변은 아직까지는 작동하지 않았지만 꽤 가까웠습니다. 이전 버전의 Spring Boot에서 작동했을 수도 있습니다. 이제 이것이 어떻게 구성되어 대신 올바르다면 수정하십시오 :
@ eric-peladan의 답변은 아직까지는 작동하지 않았지만 꽤 가까웠습니다. 이전 버전의 Spring Boot에서 작동했을 수도 있습니다. 이제 이것이 어떻게 구성되어 대신 올바르다면 수정하십시오 :
import org.springframework.context.annotation.Configuration; import org.springframework.data.rest.core.config.RepositoryRestConfiguration; import org.springframework.data.rest.webmvc.config.RepositoryRestConfigurerAdapter; @Configuration public class RepositoryConfiguration extends RepositoryRestConfigurerAdapter { @Override public void configureRepositoryRestConfiguration(RepositoryRestConfiguration config) { config.exposeIdsFor(User.class); config.exposeIdsFor(Comment.class); } }
-
==============================
3.
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Configuration; import org.springframework.data.rest.core.config.RepositoryRestConfiguration; import org.springframework.data.rest.webmvc.config.RepositoryRestConfigurerAdapter; import javax.persistence.EntityManager; import javax.persistence.metamodel.Type; @Configuration public class RestConfiguration extends RepositoryRestConfigurerAdapter { @Autowired private EntityManager entityManager; @Override public void configureRepositoryRestConfiguration(RepositoryRestConfiguration config) { config.exposeIdsFor( entityManager.getMetamodel().getEntities().stream() .map(Type::getJavaType) .toArray(Class[]::new)); } }
... @Override public void configureRepositoryRestConfiguration(RepositoryRestConfiguration config) { config.exposeIdsFor( entityManager.getMetamodel().getEntities().stream() .map(Type::getJavaType) .filter(Identifiable.class::isAssignableFrom) .toArray(Class[]::new)); }
... @Override public void configureRepositoryRestConfiguration(RepositoryRestConfiguration config) { config.exposeIdsFor( entityManager.getMetamodel().getEntities().stream() .map(Type::getJavaType) .filter(c -> c.isAnnotationPresent(ExposeId.class)) .toArray(Class[]::new)); }
샘플 주석 :
import java.lang.annotation.*; @Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) public @interface ExposeId {}
-
==============================
4.SpringBoot를 사용하면 SpringBootRepositoryRestMvcConfiguration을 확장해야합니다. RepositoryRestMvcConfiguration을 사용하면 application.properties의 구성 정의가 작동하지 않을 수 있습니다.
SpringBoot를 사용하면 SpringBootRepositoryRestMvcConfiguration을 확장해야합니다. RepositoryRestMvcConfiguration을 사용하면 application.properties의 구성 정의가 작동하지 않을 수 있습니다.
@Configuration public class MyConfiguration extends SpringBootRepositoryRestMvcConfiguration { @Override protected void configureRepositoryRestConfiguration(RepositoryRestConfiguration config) { config.exposeIdsFor(Project.class); } }
그러나 일시적인 필요 투영을 사용하여 다음과 같은 직렬화에 ID를 포함 할 수 있습니다.
@Projection(name = "allparam", types = { Person.class }) public interface ProjectionPerson { Integer getIdPerson(); String getFirstName(); String getLastName();
}
-
==============================
5.
@Component public class EntityExposingIdConfiguration extends RepositoryRestConfigurerAdapter { @Override public void configureRepositoryRestConfiguration(RepositoryRestConfiguration config) { try { Field exposeIdsFor = RepositoryRestConfiguration.class.getDeclaredField("exposeIdsFor"); exposeIdsFor.setAccessible(true); ReflectionUtils.setField(exposeIdsFor, config, new ListAlwaysContains()); } catch (NoSuchFieldException e) { e.printStackTrace(); } } class ListAlwaysContains extends ArrayList { @Override public boolean contains(Object o) { return true; } } }
-
==============================
6.흠, 해결책을 찾은 것처럼 보입니다. pom 파일에서 spring-boot-startter-data-rest를 제거하고 phoneNumbers에 @JsonManagedReference를 추가하고 person에게 @JsonBackReference를 추가하여 원하는 출력을 제공합니다. 응답의 Json는 이제는 더 이상 인쇄되지 않습니다. 그러나 이제는 이드가 있습니다. 이 마법에 대한 후드에서 어떤 마법의 스프링 부트가 수행되는지 모르지만 나는 그것을 좋아하지 않는다.
흠, 해결책을 찾은 것처럼 보입니다. pom 파일에서 spring-boot-startter-data-rest를 제거하고 phoneNumbers에 @JsonManagedReference를 추가하고 person에게 @JsonBackReference를 추가하여 원하는 출력을 제공합니다. 응답의 Json는 이제는 더 이상 인쇄되지 않습니다. 그러나 이제는 이드가 있습니다. 이 마법에 대한 후드에서 어떤 마법의 스프링 부트가 수행되는지 모르지만 나는 그것을 좋아하지 않는다.
-
==============================
7.쉬운 방법 : 변수의 이름을 개인용 긴 ID로 변경하십시오. 사적인 롱 이드에게.
쉬운 방법 : 변수의 이름을 개인용 긴 ID로 변경하십시오. 사적인 롱 이드에게.
나를 위해 일합니다. 여기에 대한 자세한 내용은 여기를 참조하십시오.
from https://stackoverflow.com/questions/24839760/spring-boot-responsebody-doesnt-serialize-entity-id by cc-by-sa and MIT license
'SPRING' 카테고리의 다른 글
[SPRING] Spring Resttemplate 예외 처리 (0) | 2018.12.06 |
---|---|
[SPRING] Spring Boot - SessionFactory를위한 Hibernate 핸들 (0) | 2018.12.06 |
[SPRING] JPA 구성에서 기본 스키마 이름을 설정하는 방법은 무엇입니까? (0) | 2018.12.06 |
[SPRING] 봄 MVC를 사용하여 생성 된 PDF 반환 (0) | 2018.12.06 |
[SPRING] @RequestBody MultiValueMap에 대해 'application / x-www-form-urlencoded; charset = UTF-8'콘텐츠 유형이 지원되지 않습니다. (0) | 2018.12.06 |