4주차/ 스프링부트로 구현하는 'URL' 단축 서비스'

전진수·2025년 4월 27일
post-thumbnail

7. 할 일 관리 서비스 시작, 할 일 추가

새로운 프로젝트

Todo.controller.java

package com.ll.demo02;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.ArrayList;
import java.util.List;

@RestController
@RequestMapping("/todos")

public class TodoController {

    private long todosLastId;
    private List<Todo> todos;

    public TodoController() {
        todos = new ArrayList<>();
    }

    @GetMapping("/add")
    public Todo add(String body) {
        Todo todo = Todo
                .builder()
                .id(++todosLastId)
                .body(body)
                .build();

        todos.add(todo);

        return todo;
    }
 }

Todo.java

package com.ll.demo02;

import lombok.Builder;
import lombok.Getter;
import lombok.Setter;

@Getter
@Setter
@Builder

public class Todo {
    private long id;
    private String body;
}

Getter, Setter, Builder, RequestMapping 사용이 안될시 build.gradle에 의존성을 추가해줘야함.

dependencies {
implementation 'org.projectlombok:lombok'
annotationProcessor 'org.projectlombok:lombok'
implementation 'org.springframework.boot:spring-boot-starter-web'
}

http://localhost:8090/todos/add 실행시

http://localhost:8090/todos/add?body=%EC%B6%95%EA%B5%AC 실행시

8. 할 일 조회

조회 코드

@GetMapping("")
public List<Todo> getTodos() {
    return todos;
}

http://localhost:8090/todos 실행시

id를 통한 조회 코드

@GetMapping("/detail")
public Todo getTodo(
        long id
) {
    return todos
            .stream()
            .filter(
                    todo -> todo.getId() == id
            )
            .findFirst()
            .orElse(null);
}

http://localhost:8090/todos/detail?id=3 실행시

http://localhost:8090/todos/detail?id=100 실행시

id를 통한 조회 코드2

@GetMapping("/{id}")
public Todo getTodo2(
        @PathVariable long id
) {
    return todos
            .stream()
            .filter(
                    todo -> todo.getId() == id
            )
            .findFirst()
            .orElse(null);
}

http://localhost:8090/todos/3 실행시

9. 할 일 삭제, 할 일 수정

삭제 코드

@GetMapping("/remove/{id}")
public boolean remove(@PathVariable long id) {
    boolean removed = todos.removeIf((todo -> todo.getId() == id));
    return removed;
}

http://localhost:8090/todos/remove/5 실행시

삭제 된 것을 확인할 수 있다.

수정 코드

@GetMapping("/modify/{id}")
public boolean modify(@PathVariable long id, String body) {
    Todo todo = todos
            .stream()
            .filter(
                    _todo -> _todo.getId() == id
            )
            .findFirst()
            .orElse(null);

    if( todo == null ) return false;

    todo.setBody(body);

    return true;
}

http://localhost:8090/todos/modify/3?body=야구 실행시

야구로 바뀐 것을 확인할 수 있다.

10. URL 단축 서비스 시작, URL 단축

새로운 프로젝트

Surl.java

package com.ll.demo03;

import lombok.Builder;
import lombok.Getter;
import lombok.Setter;

import java.time.LocalDateTime;

@Getter
@Setter
@Builder

public class Surl {

    private long id;
    @Builder.Default
    private LocalDateTime createDate = LocalDateTime.now();
    @Builder.Default
    private LocalDateTime modifyDate = LocalDateTime.now();
    private String body;
    private String url;
}

SurlController.java

package com.ll.demo03;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import java.util.ArrayList;
import java.util.List;

@Controller
public class SurlController {
    private List<Surl> surls = new ArrayList<Surl>();
    private long surlsLastId;

    @GetMapping("/add")
    @ResponseBody
    public Surl add(String body, String url) {
        Surl surl = Surl
                .builder()
                .id(++surlsLastId)
                .body(body)
                .url(url)
                .build();

        surls.add(surl);

        return surl;
    }
}

http://localhost:8090/add?body=네이버&url=https://naver.com 실행시

11. URL 단축방식 개선

http://localhost:8090/add?url=~~~~~
http://localhost:8090/s/~~~~~

URL 의 쿼리파라미터의 값은 URL 인코딩을 해야하는게 정석입니다.
HttpServletRequest는 보통 받은편지(요청)에 대한 자세한 정보를 얻어야 할 때 사용합니다.

URL 단축 코드

@GetMapping("/s/{body}/**")
@ResponseBody
public String add(@PathVariable String body, HttpServletRequest req) {
    String requestURI = req.getRequestURI();
    return requestURI;
}

http://localhost:8090/s/네이버/https://naver.com 실행시

URL 단축 코드2

@GetMapping("/s/{body}/**")
@ResponseBody
public Surl add(@PathVariable String body, HttpServletRequest req) {
    String url = req.getRequestURI();
    String[] urlBits = url.split("/", 4);
    url = urlBits[3];

    Surl surl = Surl
            .builder()
            .id(++surlsLastId)
            .body(body)
            .url(url)
            .build();

    surls.add(surl);

    return surl;
}

http://localhost:8090/s/네이버/https://naver.com 실행시

추가 코드

    if( req.getQueryString() != null ) {
        url = url + "?" + req.getQueryString();
    }
    

http://localhost:8090/s/네이버/https://search.naver.com/search.naver?where=nexearch&sm=top_hty&fbm=0&ie=utf8&query=%EB%84%A4%EC%9D%B4%EB%B2%84&ackey=wxf0qao9 실행시

System.out.println("Arrays.toString(urlBits) : " + Arrays.toString(urlBits));

을 통해 확인해보면

4 쿼리로 쪼개진 것을 확인할 수 있다.

12. 단축된 URL을 통해 원본 URL로 이동

전체 확인 코드

@GetMapping("/all")
@ResponseBody
public List<Surl> getAll() {
    return surls;
}

http://localhost:8090/all 실행시

id를 통해 URL 확인 코드

@GetMapping("/g/{id}")
@RespondBody
public String go(@PathVariable long id) {
    Surl surl =surls
            .stream()
            .filter(_surl -> _surl.getId() == id)
            .findFirst()
            .orElse(null);
    if (surl == null) throw new RuntimeException("%d번 URL을 찾을 수 없습니다.".formatted(id));

    return "redirect:" + surl.getUrl();
}

http://localhost:8090/g/1 실행시

http://localhost:8090/g/4 실행시

@RespondBody를 뺀 코드
-> redirect에 url을 추가할 시 그 url로 즉시 이동한다.

@GetMapping("/g/{id}")
public String go(@PathVariable long id) {
    Surl surl =surls
            .stream()
            .filter(_surl -> _surl.getId() == id)
            .findFirst()
            .orElse(null);
    if (surl == null) throw new RuntimeException("%d번 URL을 찾을 수 없습니다.".formatted(id));

    return "redirect:" + surl.getUrl();
}

http://localhost:8090/g/1 실행시

@Setter(AccessLevel.NONE)
private long count;

public void increaseCount() {
    count++;
}

surl.increaseCount();

두 코드를 각각 Surl.java와 SurlController.java에 추가하고 실행해보면 어떤 url이 쓰였는지 확인 할 수 있다. 아래 사진을 보면 count가 올라간 것 을 확인할 수 있다.

http://localhost:8090/all 실행시

0개의 댓글