[SPRING] 맞춤 컨트롤러가 Spring-Data-Rest / Spring-Hateoas 클래스의 형식을 미러링하도록 만들 수 있습니까?
SPRING맞춤 컨트롤러가 Spring-Data-Rest / Spring-Hateoas 클래스의 형식을 미러링하도록 만들 수 있습니까?
나는 정말로 간단해야한다고 생각하는 것을하려고 노력하고 있습니다. 나는 Question 객체를 가지고 있으며, Spring-Boot, Spring-Data-Rest, Spring-Hateo와 함께 설치한다. 모든 기본 작동합니다. 나는
여기 내 컨트롤러가 있습니다 :
@Controller
public class QuestionListController {
@Autowired private QuestionRepository questionRepository;
@Autowired private PagedResourcesAssembler<Question> pagedResourcesAssembler;
@Autowired private QuestionResourceAssembler questionResourceAssembler;
@RequestMapping(
value = "/api/questions/filter", method = RequestMethod.GET,
consumes = MediaType.APPLICATION_JSON_VALUE,
produces = MediaType.APPLICATION_JSON_VALUE)
public @ResponseBody PagedResources<QuestionResource> filter(
@RequestParam(value = "filter", required = false) String filter,
Pageable p) {
// Using queryDSL here to get a paged list of Questions
Page<Question> page =
questionRepository.findAll(
QuestionPredicate.findWithFilter(filter), p);
// Option 1 - default resource assembler
return pagedResourcesAssembler.toResource(page);
// Option 2 - custom resource assembler
return pagedResourcesAssembler.toResource(page, questionResourceAssembler);
}
}
옵션 1 : 제공된 SimplePagedResourceAssembler를 사용합니다.
이 옵션의 문제점은 필요한 _links가 렌더링되지 않습니다. 이것에 대한 해결책이 있다면 가장 쉬운 해결책이 될 것입니다.
옵션 2 : 오픈 리소스 어셈블러 구현
이 옵션의 문제점은 Spring-Hateoas 문서에 따라 QuestionResourceAssembler를 구현하면 QuestionResource가 Question의 거의 중복되는 경로로 이어지고 어셈블러가 두 객체간에 수동으로 데이터를 복사해야한다는 것입니다. 관련 _links를 모두 직접 작성하십시오. 이것은 많은 낭비 된 노력처럼 보입니다.
무엇을해야합니까?
Spring이 QuestionRepository를 내보낼 때 이미이 모든 작업을 수행하는 코드를 생성했다는 것을 알고 있습니다. 해당 코드를 탭하여 사용할 수있는 방법이 있습니까? 내 컨트롤러의 출력이 생성 된 응답과 원활하고 상호 교환 가능하도록하려면 어떻게해야합니까?
해결법
-
==============================
1.Spring Data Rest의 동작을 완전히 모방하는 방법을 찾았습니다. 속임수는 PagedResourcesAssembler와 인수가 삽입 된 PersistentEntityResourceAssembler 인스턴스를 조합하여 사용합니다. 다음과 같이 컨트롤러를 정의하십시오.
Spring Data Rest의 동작을 완전히 모방하는 방법을 찾았습니다. 속임수는 PagedResourcesAssembler와 인수가 삽입 된 PersistentEntityResourceAssembler 인스턴스를 조합하여 사용합니다. 다음과 같이 컨트롤러를 정의하십시오.
@RepositoryRestController @RequestMapping("...") public class ThingController { @Autowired private PagedResourcesAssembler pagedResourcesAssembler; @SuppressWarnings("unchecked") // optional - ignores warning on return statement below... @RequestMapping(value = "...", method = RequestMethod.GET) @ResponseBody public PagedResources<PersistentEntityResource> customMethod( ..., Pageable pageable, // this gets automatically injected by Spring... PersistentEntityResourceAssembler resourceAssembler) { Page<MyEntity> page = ...; ... return pagedResourcesAssembler.toResource(page, resourceAssembler); } }
이것은 Spring이 PersistentEntityResourceAssembler를 삽입하기 위해 사용하는 PersistentEntityResourceAssemblerArgumentResolver의 존재 덕분입니다. 결과는 저장소 쿼리 방법 중 하나에서 기대할 수있는 결과입니다.
-
==============================
2.이 오래된 질문에 대한 답변이 업데이트되었습니다. 이제 PersistentEntityResourceAssembler를 사용하여이 작업을 수행 할 수 있습니다.
이 오래된 질문에 대한 답변이 업데이트되었습니다. 이제 PersistentEntityResourceAssembler를 사용하여이 작업을 수행 할 수 있습니다.
@RepositoryRestController 내부 :
@RequestMapping(value = "somePath", method = POST) public @ResponseBody PersistentEntityResource postEntity(@RequestBody Resource<EntityModel> newEntityResource, PersistentEntityResourceAssembler resourceAssembler) { EntityModel newEntity = newEntityResource.getContent(); // ... do something additional with new Entity if you want here ... EntityModel savedEntity = entityRepo.save(newEntity); return resourceAssembler.toResource(savedEntity); // this will create the complete HATEOAS response }
-
==============================
3.나는이 문제를 비교적 직접적으로 해결했다고 믿는다.
나는이 문제를 비교적 직접적으로 해결했다고 믿는다.
SimplePagedResourceAssembler 구현을 읽은 후에 나는 하이브리드 솔루션이 작동 할 수 있음을 깨달았습니다. 제공된 Resource > 클래스는 엔티티를 올바르게 렌더링하지만 링크는 포함하지 않으므로 엔티티를 추가하면됩니다.
내 질문 ResourceAssembler 구현은 다음과 같습니다.
@Component public class QuestionResourceAssembler implements ResourceAssembler<Question, Resource<Question>> { @Autowired EntityLinks entityLinks; @Override public Resource<Question> toResource(Question question) { Resource<Question> resource = new Resource<Question>(question); final LinkBuilder lb = entityLinks.linkForSingleResource(Question.class, question.getId()); resource.add(lb.withSelfRel()); resource.add(lb.slash("answers").withRel("answers")); // other links return resource; } }
그게 끝나면 내 컨트롤러에서 위의 옵션 2를 사용했습니다.
return pagedResourcesAssembler.toResource(page, questionResourceAssembler);
이것은 잘 작동하며 너무 많은 코드가 아닙니다. 유일한 번거 로움은 필요한 각 참조에 대한 링크를 수동으로 추가해야한다는 것입니다.
from https://stackoverflow.com/questions/26538156/can-i-make-a-custom-controller-mirror-the-formatting-of-spring-data-rest-sprin by cc-by-sa and MIT license
'SPRING' 카테고리의 다른 글
[SPRING] MaxUploadSizeExceededException을 처리하는 방법 (0) | 2018.12.14 |
---|---|
[SPRING] 최대 절전 테이블 매핑 오류 (0) | 2018.12.14 |
[SPRING] 봄 보안 인증 예외에 대한 JSP로 사용자 정의 오류 메시지를 표시하는 방법 (0) | 2018.12.14 |
[SPRING] 스프링 부팅시 기본 URL을 설정하는 방법은 무엇입니까? (0) | 2018.12.14 |
[SPRING] RestTemplate을 사용할 때 어떻게 내부 잭슨 매퍼를 구성 할 수 있습니까? (0) | 2018.12.13 |