[SPRING] 커스텀 컨트롤러 메소드를위한 Spring Boot에서 HAL 직렬화 사용
SPRING커스텀 컨트롤러 메소드를위한 Spring Boot에서 HAL 직렬화 사용
spring-boot-startter-data-rest를 사용하여 Spring Boot로 RESTful API를 구현하려고한다. 계정, 거래, 카테고리 및 사용자 등 일부 항목이 있습니다. 일반적인 항목입니다.
기본적으로 생성 된 API를 통해 http : // localhost : 8080 / transactions에서 객체를 검색하면 모든 트랜잭션이 잘 진행됩니다. 모든 트랜잭션과 함께 JSON 객체로 목록을 가져옵니다.
{
"amount": -4.81,
"date": "2014-06-17T21:18:00.000+0000",
"description": "Pizza",
"_links": {
"self": {
"href": "http://localhost:8080/transactions/5"
},
"category": {
"href": "http://localhost:8080/transactions/5/category"
},
"account": {
"href": "http://localhost:8080/transactions/5/account"
}
}
}
그러나 이제 전체 데이터베이스 테이블을 직렬화하지 않으려 고하므로 그 URL의 최신 트랜잭션 만 검색하는 것이 목표입니다. 그래서 나는 컨트롤러를 썼다.
@Controller
public class TransactionController {
private final TransactionRepository transactionRepository;
@Autowired
public TransactionController(TransactionRepository transactionRepository) {
this.transactionRepository = transactionRepository;
}
// return the 5 latest transactions
@RequestMapping(value = "/transactions", method = RequestMethod.GET)
public @ResponseBody List<Transaction> getLastTransactions() {
return transactionRepository.findAll(new PageRequest(0, 5, new Sort(new Sort.Order(Sort.Direction.DESC, "date")))).getContent();
}
}
http : // localhost : 8080 / transactions에 액세스하려고하면
java.lang.IllegalStateException: Cannot call sendError() after the response has been committed
사용자와 계정 간의 순환 참조 때문입니다. User의 계정 목록에 @JsonBackReference 주석을 추가하여이 문제를 해결하면 트랜잭션 목록을 검색 할 수 있지만이 "클래식"형식 만 사용할 수 있습니다.
{
"id": 5,
"amount": -4.5,
"date": "2014-06-17T21:18:00.000+0000",
"description": "Pizza",
"account": {
"id": 2,
"name": "Account Tilman",
"owner": {
"id": 1,
"name": "Tilman"
},
"categories": [
{
"id": 1,
"name": "Groceries"
},
{
"id": 2,
"name": "Restaurant"
}
],
"users": [
{
"id": 1,
"name": "Tilman"
}
]
},
"category": {
"id": 2,
"name": "Restaurant"
}
}
더 이상 HAL 링크가 없으며 모든 것이 곧 잭슨에 의해 직렬화됩니다. 나는 추가를 시도했다.
@EnableHypermediaSupport(type = HypermediaType.HAL)
엔티티 클래스들에 전달했는데 그걸로 어디서나 나에게 다가 가지 않았다. 난 단지 내 컨트롤러가 생성 된 API와 동일한 객체를 반환하고, 모든 참조가 직렬화되는 대신 HAL _link를 사용하기를 원합니다. 이견있는 사람?
편집하다: 좋아, 두 번 생각한 후에 @EnableHypermediaSupport 주석을 구성에 추가해야한다는 것을 알았습니다. 이것은 순환 참조의 문제를 해결하고 사용자로부터 @JsonBackReference를 제거 할 수 있습니다. 그러나 객체 자체의 속성 만 직렬화되고 _links 섹션은 없습니다.
{
"amount": -4.81,
"date": "2014-06-17T21:18:00.000+0000",
"description": "Pizza"
}
나는 모든 엔티티에 대해 ResourceSupport를 확장하는 래퍼 클래스를 작성할 수 있다는 것을 알고 있지만 이것은 무의미한 것처럼 보입니다. Spring-hateoas는 자동으로 생성 된 REST 인터페이스의 _link 섹션을 사용하여 마술처럼 표현을 생성 할 수 있으므로 사용자 정의 컨트롤러에서 동일한 표현을 반환하는 방법이 있어야합니다. 맞습니까?
해결법
-
==============================
1.여기에 많은 측면이 있습니다.
여기에 많은 측면이 있습니다.
-
==============================
2.쿼리 결과를 제한하거나 결과를 정렬하기 위해 자체 컨트롤러를 만들 필요가 없습니다. 저장소에 쿼리 메소드를 작성하십시오.
쿼리 결과를 제한하거나 결과를 정렬하기 위해 자체 컨트롤러를 만들 필요가 없습니다. 저장소에 쿼리 메소드를 작성하십시오.
public interface TransactionRepository extends MongoRepository<Transaction, String> { List<Transaction> findFirst10ByOrderByDateDesc(); }
Spring Data REST는이를 자동으로 / transactions / search / findFirst10ByOrderByDateDesc의 메소드 자원으로 익스포트합니다.
-
==============================
3.컨트롤러에서 PersistentEntityResourceAssembler를 사용하려면 @RepositoryRestController로 표시해야합니다.
컨트롤러에서 PersistentEntityResourceAssembler를 사용하려면 @RepositoryRestController로 표시해야합니다.
@RestController @RequestMapping("/categories") @RepositoryRestController public class CategoryController implements ValidableController { // dependencies @RequestMapping(method = POST, consumes = MediaType.APPLICATION_JSON_VALUE) public ResponseEntity<PersistentEntityResource> create(@Valid @RequestBody CategoryForm category, BindingResult validation, PersistentEntityResourceAssembler resourceAssembler) { validate(validation); Category entity = categoryConverter.convert(category); entity = categoryService.save(entity); return ResponseEntity.ok(resourceAssembler.toFullResource(entity)); }
꽤 멋진 HAL 스타일의 응답을 만든다.
{ "createdTime": "2018-07-24T00:55:32.854", "updatedTime": "2018-07-24T00:55:32.855", "name": "cfvfcdfgdfdfdfs32", "options": [ "aaa", "bbb" ], "_links": { "self": { "href": "http://localhost:8080/shop/categories/34" }, "category": { "href": "http://localhost:8080/shop/categories/34{?projection}", "templated": true }, "products": { "href": "http://localhost:8080/shop/categories/34/products" }, "categories": { "href": "http://localhost:8080/shop/categories/34/categories{?projection}", "templated": true }, "parent": { "href": "http://localhost:8080/shop/categories/34/parent{?projection}", "templated": true } }
}
from https://stackoverflow.com/questions/31758862/enable-hal-serialization-in-spring-boot-for-custom-controller-method by cc-by-sa and MIT license
'SPRING' 카테고리의 다른 글
[SPRING] 봄과 최대 절전 모드 : 현재 스레드에 대한 세션이 없습니다. (0) | 2018.12.12 |
---|---|
[SPRING] JPA @Entity 내부의 빈 주입 (0) | 2018.12.12 |
[SPRING] 클라이언트가 보낸 요청은 구문 상 올바르지 않습니다.-Spring MVC + JDBC 템플릿 (0) | 2018.12.12 |
[SPRING] Spring DI - REST 서비스에서 Autowired 속성이 null입니다. (0) | 2018.12.12 |
[SPRING] RestTemplate은 스레드로부터 안전한가요? (0) | 2018.12.12 |