inflearn logo
강의

강의

N
챌린지

챌린지

멘토링

멘토링

N
클립

클립

로드맵

로드맵

지식공유

[개정판 2023-11-27] Spring Boot 3.x 를 이용한 RESTful Web Services 개발

Level3 단계의 REST API 구현을 위한 HATEOAS 적용

HATEOAS질문드립니다

7230

작성자 없음

작성한 질문수 0

1

UserControll쪽에 최신으로 올려주신 

package com.example.restfulwebservice.user;

import org.springframework.data.crossstore.ChangeSetPersister;
import org.springframework.hateoas.CollectionModel;
import org.springframework.hateoas.EntityModel;
import org.springframework.hateoas.server.mvc.WebMvcLinkBuilder;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.support.ServletUriComponentsBuilder;

import javax.validation.Valid;
import java.net.URI;
import java.util.ArrayList;
import java.util.List;

import static org.springframework.hateoas.server.mvc.WebMvcLinkBuilder.linkTo;
import static org.springframework.hateoas.server.mvc.WebMvcLinkBuilder.methodOn;

@RestController
public class UserController {

private UserDaoService service;

//생성자를 통한 의존성 주입
public UserController(UserDaoService service) {
this.service = service;
}

@GetMapping("/users")
public List<User> retrieveAllUsers() {

return service.findAll();
}

// 전체 사용자 목록
@GetMapping("/users2")
public ResponseEntity<CollectionModel<EntityModel<User>>> retrieveUserList2() {
List<EntityModel<User>> result =
new ArrayList<>();
List<User> users = service.findAll();

for (User user : users) {
EntityModel entityModel = EntityModel.
of(user);
entityModel.add(linkTo(methodOn(this.getClass()).retrieveAllUsers()).withSelfRel());

result.add(entityModel);
}

return ResponseEntity.ok(CollectionModel.of(result, linkTo(methodOn(this.getClass()).retrieveAllUsers()).withSelfRel()));
}

//우리는 id를 숫자로 해도 서버측에 전달 될 경우에는 -> String으로 된다
//id로 하면 자동으로 원하는 int에 맞게 찾아준다
//HETAOS를 적용하면 개발자의 양은 많아지지만
//내가 개발한 것을 보는 사용자입장에서는 더 많은 정보를 알 수 있다
// 사용자 상세 정보
@GetMapping("/users/{id}")
public ResponseEntity<EntityModel<User>> retrieveUser(@PathVariable int id) {
User user =
service.findOne(id);

if (user == null) {
throw new UserNotFoundException("id-" + id);
}

EntityModel entityModel = EntityModel.
of(user);

WebMvcLinkBuilder linkTo = linkTo(methodOn(this.getClass()).retrieveAllUsers());
entityModel.add(linkTo.withRel("all-users"));
return ResponseEntity.ok(entityModel);

}

//post, put 처럼 데이터 맵핑 할려면 파라미터에 request body로 형식을 적어줘야한다
@PostMapping("/users")
public ResponseEntity<User> createUser(@Valid @RequestBody User user) {
User saveUser =
service.save(user);

URI localtion = ServletUriComponentsBuilder.fromCurrentRequest()
.path(
"/{id}")
.buildAndExpand(saveUser.getID())
.toUri()
;
return ResponseEntity.created(localtion).build();

}

@DeleteMapping("/users/{id}")
public void deleteUser(@PathVariable int id) {

User user =
service.deleteById( id);

if(user == null) {
throw new UserNotFoundException(String.format("ID[%s] not found ", id));
}
}
}
사용했는데 에러가 발생했습니다 ㅠㅠ
org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type 'org.springframework.plugin.core.PluginRegistry<org.springframework.hateoas.client.LinkDiscoverer, org.springframework.http.MediaType>' available: expected single matching bean but found 3: relProviderPluginRegistry,linkDiscovererRegistry,entityLinksPluginRegistry

rest-api spring-boot

답변 1

4

Dowon Lee

안녕하세요, 이도원입니다. 

Spring Boot, HATEOAS의 버전이 최신 버전으로 변경되면서 몇몇 라이브러리에서 충돌이 발생한 것 같습니다. 

아래와 같이 pom.xml을 변경해서 빌드해 보시기 바랍니다. 

        <parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.4.5</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
...
        <dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-hateoas</artifactId>
<!-- <version>2.1.8.RELEASE</version>-->
<version>2.4.3</version>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-rest-hal-browser</artifactId>
<version>3.3.6.RELEASE</version>
</dependency>

<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-boot-starter</artifactId>
<version>3.0.0</version>
</dependency>

<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>3.0.0</version>
</dependency>

pom.xml 파일의 변경으로 UserController.java의 Swagger 부분을 아래와 같이 변경하여 사용하시기 바랍니다.

//    @GetMapping("/users2")
// public Resources<Resource<User>> retrieveUserList() {
// List<Resource<User>> result = new ArrayList<>();
// List<User> users = service.findAll();
//
// for (User user : users) {
// Resource<User> resource = new Resource<>(user);
// ControllerLinkBuilder linkTo = linkTo(methodOn(this.getClass()).retrieveAllUsers());
// resource.add(linkTo.withRel("all-users"));
//
// result.add(resource);
// }
//
// return new Resources(result);
// }

// 전체 사용자 목록
@GetMapping("/users2")
public ResponseEntity<CollectionModel<EntityModel<User>>> retrieveUserList2() {
List<EntityModel<User>> result = new ArrayList<>();
List<User> users = service.findAll();

for (User user : users) {
EntityModel entityModel = EntityModel.of(user);
entityModel.add(linkTo(methodOn(this.getClass()).retrieveAllUsers()).withSelfRel());

result.add(entityModel);
}

return ResponseEntity.ok(CollectionModel.of(result, linkTo(methodOn(this.getClass()).retrieveAllUsers()).withSelfRel()));
}
수정해 보시고 문의사항 있으시면 다시 글 남겨주세요. 

감사합니다.

0

lon

해결했습니다 감사합니다.

JPA

0

61

1

jpa dependency를 추가하고 SecurityConfig클래스에서 오류가 납니다.

0

70

1

웹 브라우저 400 bad request

0

73

1

@Size는 되는데 @Past는 안 됩니다.

0

63

1

pdf 자료는 없나요?

0

75

2

locale 정보가 null 이면 무조건 messages_ko.properties이 호출 되는 문제

0

90

2

Swagger 강의, Unable to infer base url 이거 뜨시는 분들 도움되시라고

0

120

1

강의에서나온 화면 피피티

0

160

1

HelloWorldBean 관련 에러

0

188

2

Swagger API 3.x 오류..

0

222

1

java: variable message not initialized in the default constructor 에러는 어찌하면 좋을까요?

1

283

1

현재 GIT에 올리신 소스를 실행해봤습니다.

0

189

2

고양이 소리가 귀엽네요 !!

0

139

2

git에서 소스받고 실습중인데

0

119

1

post가 안되요

0

106

1

한국어 같은 경우 언어코드인 messages_ko.properties 로 생성하는게 더 좋지 않나요?

0

169

2

리턴타입으로서 EntityModel<User> 와 ResponseEntity질문

0

106

1

예외처리쪽 관련 질문있습니다.

0

160

2

엔티티가 바로 응답으로 나가도 되나요??

0

229

2

안녕하세여 Cannot invoke "co.kr.joneconsulting.resfulservice.repository.PostRepository.save(Object)" because "this.postRepository" is null

0

141

2

사용자 등록하고 나서 H2 에서 보면 신규 사용자의 password, ssn 이 null 로 되어 있습니다.

0

143

2

ApplictionContext 질문

0

195

2

롬북이 안먹히는것같아요

0

158

1

인텔리제이에서스프링부트 파일 실행하면

0

241

1