[SPRING] Spring 데이터 REST : 컨트롤러에서 리파지토리 메서드 재정의
SPRINGSpring 데이터 REST : 컨트롤러에서 리파지토리 메서드 재정의
나는 Spring에서 런타임에 구현을 생성하는 다음 REST 저장소를 가지고있다.
@RepositoryRestResource
public interface FooRepository extends CrudRepository<Foo, Long> {
}
즉, save (), find (), exists () 및 REST를 통해 사용 가능하고 노출 된 다른 메소드를 갖게됩니다.
이제, 나는이 방법들 중 하나를 오버라이드하고 싶다. 예 : save (). 이를 위해 다음과 같이 해당 메서드를 노출하는 컨트롤러를 만듭니다.
@RepositoryRestController
@RequestMapping("/foo")
public class FooController {
@Autowired
FooService fooService;
@RequestMapping(value = "/{fooId}", method = RequestMethod.PUT)
public void updateFoo(@PathVariable Long fooId) {
fooService.updateProperly(fooId);
}
}
문제 : 이 컨트롤러를 활성화하면 Spring에 의해 구현 된 다른 모든 메소드가 더 이상 노출되지 않습니다. 예를 들어, 더 이상 / foo / 1에 GET 요청을 할 수 없습니다.
의문: 다른 자동 생성 된 Spring 메서드를 유지하면서 REST 메서드를 재정의하는 방법이 있습니까?
추가 정보 :
그래서 그것은 상자에서 작동해야하지만 불행히도하지 않는 것 같습니다.
해결법
-
==============================
1.설명서의 예제를주의 깊게 살펴보십시오. 클래스 수준의 요청 매핑을 명시 적으로 금지하지 않지만 메서드 수준의 요청 매핑을 사용합니다. 이것이 바람직한 행동인지 버그인지 확실하지 않지만, 여기에 언급 된 것처럼 이것이 이것이 작동하도록 만드는 유일한 방법이라는 것을 알고있는 한.
설명서의 예제를주의 깊게 살펴보십시오. 클래스 수준의 요청 매핑을 명시 적으로 금지하지 않지만 메서드 수준의 요청 매핑을 사용합니다. 이것이 바람직한 행동인지 버그인지 확실하지 않지만, 여기에 언급 된 것처럼 이것이 이것이 작동하도록 만드는 유일한 방법이라는 것을 알고있는 한.
컨트롤러를 다음과 같이 변경하십시오.
@RepositoryRestController public class FooController { @Autowired FooService fooService; @RequestMapping(value = "/foo/{fooId}", method = RequestMethod.PUT) public void updateFoo(@PathVariable Long fooId) { fooService.updateProperly(fooId); } // edited after Sergey's comment @RequestMapping(value = "/foo/{fooId}", method = RequestMethod.PUT) public RequestEntity<Void> updateFoo(@PathVariable Long fooId) { fooService.updateProperly(fooId); return ResponseEntity.ok().build(); // simplest use of a ResponseEntity } }
-
==============================
2.Account 엔티티가 있다고 가정 해 보겠습니다.
Account 엔티티가 있다고 가정 해 보겠습니다.
@Entity public class Account implements Identifiable<Integer>, Serializable { private static final long serialVersionUID = -3187480027431265380L; @Id private Integer id; private String name; public Account(Integer id, String name) { this.id = id; this.name = name; } public void setId(Integer id) { this.id = id; } @Override public Integer getId() { return id; } public String getName() { return name; } public void setName(String name) { this.name = name; } }
/ accounts에 CRUD 엔드 포인트를 표시하는 AccountRepository를 사용하는 경우 :
@RepositoryRestResource(collectionResourceRel = "accounts", path = "accounts") public interface AccountRepository extends CrudRepository<Account, Integer> { }
AccountRepository : 기본 GET 끝점 양식을 재정의하는 AccountController.
@RepositoryRestController public class AccountController { private PagedResourcesAssembler<Account> pagedAssembler; @Autowired public AccountController(PagedResourcesAssembler<Account> pagedAssembler) { this.pagedAssembler = pagedAssembler; } private Page<Account> getAccounts(Pageable pageRequest){ int totalAccounts= 50; List<Account> accountList = IntStream.rangeClosed(1, totalAccounts) .boxed() .map( value -> new Account(value, value.toString())) .skip(pageRequest.getOffset()) .limit(pageRequest.getPageSize()) .collect(Collectors.toList()); return new PageImpl(accountList, pageRequest, totalAccounts); } @RequestMapping(method= RequestMethod.GET, path="/accounts", produces = "application/hal+json") public ResponseEntity<Page<Account>> getAccountsHal(Pageable pageRequest, PersistentEntityResourceAssembler assembler){ return new ResponseEntity(pagedAssembler.toResource(getAccounts(pageRequest), (ResourceAssembler) assembler), HttpStatus.OK); }
? GET / accounts? size = 5 & page = 0을 호출하면 mock 구현을 사용하는 다음과 같은 결과가 출력됩니다.
{ "_embedded": { "accounts": [ { "name": "1", "_links": { "self": { "href": "http://localhost:8080/accounts/1" }, "account": { "href": "http://localhost:8080/accounts/1" } } }, { "name": "2", "_links": { "self": { "href": "http://localhost:8080/accounts/2" }, "account": { "href": "http://localhost:8080/accounts/2" } } }, { "name": "3", "_links": { "self": { "href": "http://localhost:8080/accounts/3" }, "account": { "href": "http://localhost:8080/accounts/3" } } }, { "name": "4", "_links": { "self": { "href": "http://localhost:8080/accounts/4" }, "account": { "href": "http://localhost:8080/accounts/4" } } }, { "name": "5", "_links": { "self": { "href": "http://localhost:8080/accounts/5" }, "account": { "href": "http://localhost:8080/accounts/5" } } } ] }, "_links": { "first": { "href": "http://localhost:8080/accounts?page=0&size=5" }, "self": { "href": "http://localhost:8080/accounts?page=0&size=5" }, "next": { "href": "http://localhost:8080/accounts?page=1&size=5" }, "last": { "href": "http://localhost:8080/accounts?page=9&size=5" } }, "page": { "size": 5, "totalElements": 50, "totalPages": 10, "number": 0 } }
완벽을 기하기 위해 POM을 다음 상위 항목과 종속 항목으로 구성 할 수 있습니다.
<parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.5.2.RELEASE</version> </parent> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.data</groupId> <artifactId>spring-data-rest-webmvc</artifactId> <version>2.6.1.RELEASE</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency> <dependency> <groupId>com.h2database</groupId> <artifactId>h2</artifactId> </dependency> </dependencies>
-
==============================
3.Java 8을 사용하는 경우에는 깔끔한 해결책을 발견했습니다. 인터페이스에서 기본 메소드 만 사용하십시오.
Java 8을 사용하는 경우에는 깔끔한 해결책을 발견했습니다. 인터페이스에서 기본 메소드 만 사용하십시오.
@RepositoryRestResource public interface FooRepository extends CrudRepository<Foo, Long> { default <S extends T> S save(S var1) { //do some work here } }
-
==============================
4.내가 찾은 업데이트 만 내 목숨을 구했어. 이 대답에서 @ mathias-dpunkt에 의해 훌륭하게 말한 것처럼 https://stackoverflow.com/a/34518166/2836627
내가 찾은 업데이트 만 내 목숨을 구했어. 이 대답에서 @ mathias-dpunkt에 의해 훌륭하게 말한 것처럼 https://stackoverflow.com/a/34518166/2836627
따라서 기본 경로가 "/ api"이고 @RepositoryRestController를 사용하는 경우
@RequestMapping에서 "/ api"를 생략해야합니다.
from https://stackoverflow.com/questions/36773171/spring-data-rest-override-repository-method-on-the-controller by cc-by-sa and MIT license
'SPRING' 카테고리의 다른 글
[SPRING] Java 및 Spring 3.0을 사용하여 JMS 항목 (대기열 아님)에서 동시에 여러 메시지를 처리 할 수 있습니까? (0) | 2019.01.04 |
---|---|
[SPRING] 적절한 mvc : Spring의 인터셉터 설정 (0) | 2019.01.04 |
[SPRING] URL 매핑 문제 - Spring 웹 MVC (0) | 2019.01.04 |
[SPRING] 스프링 데이터 - null 값을 가진 경우 매개 변수를 무시합니다. (0) | 2019.01.04 |
[SPRING] 스프링 스케줄링 작업 - 한 번만 실행 (0) | 2019.01.03 |