Info |
---|
|
Image Added Code Block |
---|
language | xml |
---|
theme | Midnight |
---|
title | pom.xml |
---|
linenumbers | true |
---|
| <dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency> |
|
/home 에서 WebUI를 보여주도록 WebController를 추가합니다.
Code Block |
---|
language | java |
---|
theme | Midnight |
---|
title | src/main/java/com/example/demo/WebController.java |
---|
linenumbers | true |
---|
collapse | true |
---|
|
package com.example.demo;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
@Controller
@RequiredArgsConstructor
public class WebController {
@GetMapping("/home")
public String home(Model model) {
return "home";
}
} |
하드코딩된 BaseURL을 삭제 합니다.
- LinkController 와 LinkService를 같이 수정해야 합니다.
Info |
---|
icon | false |
---|
title | src/main/resources/application.properties |
---|
|
|
LinkController를 리펙토링 합니다.
Code Block |
---|
language | java |
---|
theme | Midnight |
---|
title | src/main/java/com/example/demo/LinkController.java |
---|
linenumbers | true |
---|
collapse | true |
---|
|
package com.example.demo;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import lombok.RequiredArgsConstructor;
import lombok.Value;
import reactor.core.publisher.Mono;
@RestController
@RequiredArgsConstructor
public class LinkController {
private final LinkService linkService;
@PostMapping("/link")
Mono<CreateLinkResponse> create(@RequestBody CreateLinkRequest requestLink) {
return linkService.shortenLink(requestLink.getLink())
.map(CreateLinkResponse::new);
}
@GetMapping("/link/{key}")
Mono<ResponseEntity<Object>> getLink(@PathVariable String key) {
return linkService.getOriginalLink(key)
.map(link -> ResponseEntity.status(HttpStatus.PERMANENT_REDIRECT)
.header("Location", link.getOriginalLink())
.build())
.defaultIfEmpty(ResponseEntity.notFound().build());
}
@Value
public static class CreateLinkRequest {
private String link;
}
@Value
public static class CreateLinkResponse {
private String shortenedLink;
}
} |
Code Block |
---|
language | java |
---|
theme | Midnight |
---|
title | src/main/java/com/example/demo/LinkService.java |
---|
linenumbers | true |
---|
collapse | true |
---|
|
package com.example.demo;
import org.apache.commons.lang3.RandomStringUtils;
import org.springframework.stereotype.Service;
import reactor.core.publisher.Mono;
@Service
public class LinkService {
private final LinkRepository linkRepository;
public LinkService(LinkRepository linkRepository) {
this.linkRepository = linkRepository;
}
Mono<String> shortenLink(String link) {
String randomKey = RandomStringUtils.randomAlphabetic(6);
return linkRepository.save(new Link(link, randomKey))
.map(result -> result.getKey());
}
Mono<Link> getOriginalLink(String key) {
return linkRepository.findByKey(key);
}
} |
Code Block |
---|
language | java |
theme |
---|
Midnight | title | src/main/java/com/example/demo/WebController.javaLinkControllerTest |
---|
linenumbers | true |
---|
collapse | true |
---|
|
package com.example.demo;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.reactive.WebFluxTest;
import lombok.RequiredArgsConstructororg.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.stereotypehttp.ControllerMediaType;
import org.springframework.test.context.uijunit4.ModelSpringRunner;
import org.springframework.test.web.bind.annotation.*;
@Controller
@RequiredArgsConstructor
public class WebController {
@GetMapping("/home")
public String home(Model model) {
.reactive.server.WebTestClient;
import reactor.core.publisher.Mono;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.when;
@RunWith(SpringRunner.class)
@WebFluxTest(controllers = LinkController.class)
public class LinkControllerTest {
@Autowired
private WebTestClient webTestClient;
@MockBean
private LinkService linkService;
@Test
public void shortensLink() {
when(linkService.shortenLink("https://spring.io")).thenReturn(Mono.just("aass2211"));
webTestClient.post()
.uri("/link")
.contentType(MediaType.APPLICATION_JSON)
.syncBody("{\"link\":\"https://spring.io\"}")
.exchange()
.expectStatus()
.is2xxSuccessful()
.expectBody()
.jsonPath("$.shortenedLink")
.value(val -> assertThat(val).isEqualTo("aass2211"));
}
@Test
public void redirectsToOriginalLink() {
when(linkService.getOriginalLink("aaa21123"))
.thenReturn(Mono.just(new Link("http://sprint.io", "aaa21123")));
webTestClient.get()
.uri("/link/aaa21123")
.exchange()
.expectStatus()
.isPermanentRedirect()
.expectHeader()
return "home" .value("Location", location -> assertThat(location).isEqualTo("http://sprint.io"));
}
}
|
Infocode |
---|
icon | false |
---|
title | pom.xmlLinkServiceTest |
---|
| Image Removedlinenumbers | true |
---|
collapse | true |
---|
|
package com.example.demo;
import org.junit.Before;
import org.junit.Test;
import org.mockito.stubbing.Answer;
import reactor.core.publisher.Mono;
import reactor.test.StepVerifier;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
public class LinkServiceTest {
private LinkRepository linkRepository = mock(LinkRepository.class);
private LinkService linkService = new LinkService(linkRepository);
@Before
public void setup() {
when(linkRepository.save(any()))
Code Block |
---|
|
language | xml |
---|
theme | Midnight |
---|
title | pom.xml |
---|
linenumbers | true |
---|
|
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId> .thenAnswer((Answer<Mono<Link>>) invocationOnMock -> Mono.just((Link) invocationOnMock.getArguments()[0]));
}
@Test
public void shortensLink() {
</dependency>StepVerifier.create(linkService.shortenLink("http://spring.io"))
<dependency>
<groupId>org.springframework.boot</groupId>.expectNextMatches(result -> result != null && result.length() > 0)
<artifactId>spring-boot-starter-thymeleaf</artifactId>
.expectComplete()
</dependency> .verify();
}
}