From 8a638f93a285ea57606ec288177428b0802a9735 Mon Sep 17 00:00:00 2001 From: ZZAMBAs Date: Tue, 12 Dec 2023 10:03:20 +0900 Subject: [PATCH 01/42] Initial commit --- build.gradle | 38 +++ gradle/wrapper/gradle-wrapper.jar | 0 gradle/wrapper/gradle-wrapper.properties | 7 + gradlew | 249 ++++++++++++++++++ gradlew.bat | 92 +++++++ .../SpringBootUrlShortenerApplication.java | 11 + src/main/resources/application.yml | 0 ...SpringBootUrlShortenerApplicationTest.java | 12 + 8 files changed, 409 insertions(+) create mode 100644 build.gradle create mode 100644 gradle/wrapper/gradle-wrapper.jar create mode 100644 gradle/wrapper/gradle-wrapper.properties create mode 100644 gradlew create mode 100644 gradlew.bat create mode 100644 src/main/java/org/prgms/springbooturlshortener/SpringBootUrlShortenerApplication.java create mode 100644 src/main/resources/application.yml create mode 100644 src/test/java/org/prgms/springbooturlshortener/SpringBootUrlShortenerApplicationTest.java diff --git a/build.gradle b/build.gradle new file mode 100644 index 00000000..f39369d1 --- /dev/null +++ b/build.gradle @@ -0,0 +1,38 @@ +plugins { + id 'java' + id 'org.springframework.boot' version '3.2.0' + id 'io.spring.dependency-management' version '1.1.3' +} + +group = 'org.prgms' +version = '0.0.1-SNAPSHOT' + +java { + sourceCompatibility = '17' +} + +configurations { + compileOnly { + extendsFrom annotationProcessor + } +} + +repositories { + mavenCentral() +} + +dependencies { + implementation 'org.springframework.boot:spring-boot-starter' + implementation 'org.springframework.boot:spring-boot-starter-web' + implementation 'org.springframework.boot:spring-boot-starter-data-jpa' + implementation 'org.springframework.boot:spring-boot-starter-thymeleaf' + compileOnly 'org.projectlombok:lombok' + annotationProcessor 'org.projectlombok:lombok' + testCompileOnly 'org.projectlombok:lombok' + testAnnotationProcessor 'org.projectlombok:lombok' + testImplementation 'org.springframework.boot:spring-boot-starter-test' +} + +tasks.named('test') { + useJUnitPlatform() +} diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 00000000..e69de29b diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 00000000..3fa8f862 --- /dev/null +++ b/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,7 @@ +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-8.4-bin.zip +networkTimeout=10000 +validateDistributionUrl=true +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists diff --git a/gradlew b/gradlew new file mode 100644 index 00000000..1aa94a42 --- /dev/null +++ b/gradlew @@ -0,0 +1,249 @@ +#!/bin/sh + +# +# Copyright © 2015-2021 the original authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +############################################################################## +# +# Gradle start up script for POSIX generated by Gradle. +# +# Important for running: +# +# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is +# noncompliant, but you have some other compliant shell such as ksh or +# bash, then to run this script, type that shell name before the whole +# command line, like: +# +# ksh Gradle +# +# Busybox and similar reduced shells will NOT work, because this script +# requires all of these POSIX shell features: +# * functions; +# * expansions «$var», «${var}», «${var:-default}», «${var+SET}», +# «${var#prefix}», «${var%suffix}», and «$( cmd )»; +# * compound commands having a testable exit status, especially «case»; +# * various built-in commands including «command», «set», and «ulimit». +# +# Important for patching: +# +# (2) This script targets any POSIX shell, so it avoids extensions provided +# by Bash, Ksh, etc; in particular arrays are avoided. +# +# The "traditional" practice of packing multiple parameters into a +# space-separated string is a well documented source of bugs and security +# problems, so this is (mostly) avoided, by progressively accumulating +# options in "$@", and eventually passing that to Java. +# +# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS, +# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly; +# see the in-line comments for details. +# +# There are tweaks for specific operating systems such as AIX, CygWin, +# Darwin, MinGW, and NonStop. +# +# (3) This script is generated from the Groovy template +# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# within the Gradle project. +# +# You can find Gradle at https://github.com/gradle/gradle/. +# +############################################################################## + +# Attempt to set APP_HOME + +# Resolve links: $0 may be a link +app_path=$0 + +# Need this for daisy-chained symlinks. +while + APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path + [ -h "$app_path" ] +do + ls=$( ls -ld "$app_path" ) + link=${ls#*' -> '} + case $link in #( + /*) app_path=$link ;; #( + *) app_path=$APP_HOME$link ;; + esac +done + +# This is normally unused +# shellcheck disable=SC2034 +APP_BASE_NAME=${0##*/} +# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) +APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD=maximum + +warn () { + echo "$*" +} >&2 + +die () { + echo + echo "$*" + echo + exit 1 +} >&2 + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +nonstop=false +case "$( uname )" in #( + CYGWIN* ) cygwin=true ;; #( + Darwin* ) darwin=true ;; #( + MSYS* | MINGW* ) msys=true ;; #( + NONSTOP* ) nonstop=true ;; +esac + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD=$JAVA_HOME/jre/sh/java + else + JAVACMD=$JAVA_HOME/bin/java + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD=java + if ! command -v java >/dev/null 2>&1 + then + die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +fi + +# Increase the maximum file descriptors if we can. +if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then + case $MAX_FD in #( + max*) + # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC2039,SC3045 + MAX_FD=$( ulimit -H -n ) || + warn "Could not query maximum file descriptor limit" + esac + case $MAX_FD in #( + '' | soft) :;; #( + *) + # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC2039,SC3045 + ulimit -n "$MAX_FD" || + warn "Could not set maximum file descriptor limit to $MAX_FD" + esac +fi + +# Collect all arguments for the java command, stacking in reverse order: +# * args from the command line +# * the main class name +# * -classpath +# * -D...appname settings +# * --module-path (only if needed) +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. + +# For Cygwin or MSYS, switch paths to Windows format before running java +if "$cygwin" || "$msys" ; then + APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) + CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) + + JAVACMD=$( cygpath --unix "$JAVACMD" ) + + # Now convert the arguments - kludge to limit ourselves to /bin/sh + for arg do + if + case $arg in #( + -*) false ;; # don't mess with options #( + /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath + [ -e "$t" ] ;; #( + *) false ;; + esac + then + arg=$( cygpath --path --ignore --mixed "$arg" ) + fi + # Roll the args list around exactly as many times as the number of + # args, so each arg winds up back in the position where it started, but + # possibly modified. + # + # NB: a `for` loop captures its iteration list before it begins, so + # changing the positional parameters here affects neither the number of + # iterations, nor the values presented in `arg`. + shift # remove old arg + set -- "$@" "$arg" # push replacement arg + done +fi + + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' + +# Collect all arguments for the java command: +# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# and any embedded shellness will be escaped. +# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be +# treated as '${Hostname}' itself on the command line. + +set -- \ + "-Dorg.gradle.appname=$APP_BASE_NAME" \ + -classpath "$CLASSPATH" \ + org.gradle.wrapper.GradleWrapperMain \ + "$@" + +# Stop when "xargs" is not available. +if ! command -v xargs >/dev/null 2>&1 +then + die "xargs is not available" +fi + +# Use "xargs" to parse quoted args. +# +# With -n1 it outputs one arg per line, with the quotes and backslashes removed. +# +# In Bash we could simply go: +# +# readarray ARGS < <( xargs -n1 <<<"$var" ) && +# set -- "${ARGS[@]}" "$@" +# +# but POSIX shell has neither arrays nor command substitution, so instead we +# post-process each arg (as a line of input to sed) to backslash-escape any +# character that might be a shell metacharacter, then use eval to reverse +# that process (while maintaining the separation between arguments), and wrap +# the whole thing up as a single "set" statement. +# +# This will of course break if any of these variables contains a newline or +# an unmatched quote. +# + +eval "set -- $( + printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | + xargs -n1 | + sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | + tr '\n' ' ' + )" '"$@"' + +exec "$JAVACMD" "$@" diff --git a/gradlew.bat b/gradlew.bat new file mode 100644 index 00000000..93e3f59f --- /dev/null +++ b/gradlew.bat @@ -0,0 +1,92 @@ +@rem +@rem Copyright 2015 the original author or authors. +@rem +@rem Licensed under the Apache License, Version 2.0 (the "License"); +@rem you may not use this file except in compliance with the License. +@rem You may obtain a copy of the License at +@rem +@rem https://www.apache.org/licenses/LICENSE-2.0 +@rem +@rem Unless required by applicable law or agreed to in writing, software +@rem distributed under the License is distributed on an "AS IS" BASIS, +@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@rem See the License for the specific language governing permissions and +@rem limitations under the License. +@rem + +@if "%DEBUG%"=="" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%"=="" set DIRNAME=. +@rem This is normally unused +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Resolve any "." and ".." in APP_HOME to make it shorter. +for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if %ERRORLEVEL% equ 0 goto execute + +echo. +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto execute + +echo. +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* + +:end +@rem End local scope for the variables with windows NT shell +if %ERRORLEVEL% equ 0 goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +set EXIT_CODE=%ERRORLEVEL% +if %EXIT_CODE% equ 0 set EXIT_CODE=1 +if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% +exit /b %EXIT_CODE% + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/src/main/java/org/prgms/springbooturlshortener/SpringBootUrlShortenerApplication.java b/src/main/java/org/prgms/springbooturlshortener/SpringBootUrlShortenerApplication.java new file mode 100644 index 00000000..2d3c3059 --- /dev/null +++ b/src/main/java/org/prgms/springbooturlshortener/SpringBootUrlShortenerApplication.java @@ -0,0 +1,11 @@ +package org.prgms.springbooturlshortener; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class SpringBootUrlShortenerApplication { + public static void main(String[] args) { + SpringApplication.run(SpringBootUrlShortenerApplication.class); + } +} diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml new file mode 100644 index 00000000..e69de29b diff --git a/src/test/java/org/prgms/springbooturlshortener/SpringBootUrlShortenerApplicationTest.java b/src/test/java/org/prgms/springbooturlshortener/SpringBootUrlShortenerApplicationTest.java new file mode 100644 index 00000000..4bf5d478 --- /dev/null +++ b/src/test/java/org/prgms/springbooturlshortener/SpringBootUrlShortenerApplicationTest.java @@ -0,0 +1,12 @@ +package org.prgms.springbooturlshortener; + +import org.junit.jupiter.api.Test; +import org.springframework.boot.test.context.SpringBootTest; + +@SpringBootTest +class SpringBootUrlShortenerApplicationTest { + @Test + void contextLoad() { + + } +} From 476b9308eec6a46cf6aa4d39da3a223562f713e7 Mon Sep 17 00:00:00 2001 From: ZZAMBAs Date: Wed, 13 Dec 2023 21:00:30 +0900 Subject: [PATCH 02/42] =?UTF-8?q?Feat:=20short=20url=EC=97=90=20=EB=8C=80?= =?UTF-8?q?=ED=95=9C=20=EB=8F=84=EB=A9=94=EC=9D=B8=20=ED=81=B4=EB=9E=98?= =?UTF-8?q?=EC=8A=A4=EC=99=80=20=EC=8A=A4=ED=82=A4=EB=A7=88=EB=A5=BC=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80=ED=95=9C=EB=8B=A4.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/shorturl/ShortUrl.java | 20 +++++++++++++++++++ src/main/resources/schema.sql | 6 ++++++ 2 files changed, 26 insertions(+) create mode 100644 src/main/java/org/prgms/springbooturlshortener/domain/shorturl/ShortUrl.java create mode 100644 src/main/resources/schema.sql diff --git a/src/main/java/org/prgms/springbooturlshortener/domain/shorturl/ShortUrl.java b/src/main/java/org/prgms/springbooturlshortener/domain/shorturl/ShortUrl.java new file mode 100644 index 00000000..edca93ad --- /dev/null +++ b/src/main/java/org/prgms/springbooturlshortener/domain/shorturl/ShortUrl.java @@ -0,0 +1,20 @@ +package org.prgms.springbooturlshortener.domain.shorturl; + +import jakarta.persistence.Entity; +import jakarta.persistence.Id; +import lombok.NoArgsConstructor; + +import java.time.LocalDateTime; + +@Entity +@NoArgsConstructor +public class ShortUrl { + @Id + private String transformedUrl; + + private String originalUrl; + + private Long visitCount; + + private LocalDateTime lastVisitTime; +} diff --git a/src/main/resources/schema.sql b/src/main/resources/schema.sql new file mode 100644 index 00000000..91f08e66 --- /dev/null +++ b/src/main/resources/schema.sql @@ -0,0 +1,6 @@ +CREATE TABLE IF NOT EXISTS short_url ( + transformed_url char(6) PRIMARY KEY, + original_url varchar(2047) not null, + visit_count bigint default 0 not null, + last_visit_time timestamp not null default current_timestamp(6) +); From 7ddf83fa49e3e30874f77fd010b1b4e8f198bea5 Mon Sep 17 00:00:00 2001 From: ZZAMBAs Date: Wed, 13 Dec 2023 21:33:44 +0900 Subject: [PATCH 03/42] =?UTF-8?q?Feat:=20ShortUrlRepository=EB=A5=BC=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80=ED=95=9C=EB=8B=A4.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/shorturl/repository/ShortUrlRepository.java | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 src/main/java/org/prgms/springbooturlshortener/domain/shorturl/repository/ShortUrlRepository.java diff --git a/src/main/java/org/prgms/springbooturlshortener/domain/shorturl/repository/ShortUrlRepository.java b/src/main/java/org/prgms/springbooturlshortener/domain/shorturl/repository/ShortUrlRepository.java new file mode 100644 index 00000000..1e34a45e --- /dev/null +++ b/src/main/java/org/prgms/springbooturlshortener/domain/shorturl/repository/ShortUrlRepository.java @@ -0,0 +1,7 @@ +package org.prgms.springbooturlshortener.domain.shorturl.repository; + +import org.prgms.springbooturlshortener.domain.shorturl.ShortUrl; +import org.springframework.data.jpa.repository.JpaRepository; + +public interface ShortUrlRepository extends JpaRepository { +} From f545f354635af7a311a696a5775a812637791673 Mon Sep 17 00:00:00 2001 From: ZZAMBAs Date: Wed, 13 Dec 2023 21:42:34 +0900 Subject: [PATCH 04/42] =?UTF-8?q?Feat:=20int=20=EA=B0=92=EC=9D=84=206?= =?UTF-8?q?=EC=9E=90=EB=A6=AC=20BASE62=20=EB=AC=B8=EC=9E=90=EC=97=B4?= =?UTF-8?q?=EB=A1=9C=20=EC=9D=B8=EC=BD=94=EB=94=A9=ED=95=98=EB=8A=94=20Url?= =?UTF-8?q?Transformer=EB=A5=BC=20=EC=B6=94=EA=B0=80=ED=95=9C=EB=8B=A4.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../shorturl/service/UrlTransformer.java | 22 +++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 src/main/java/org/prgms/springbooturlshortener/domain/shorturl/service/UrlTransformer.java diff --git a/src/main/java/org/prgms/springbooturlshortener/domain/shorturl/service/UrlTransformer.java b/src/main/java/org/prgms/springbooturlshortener/domain/shorturl/service/UrlTransformer.java new file mode 100644 index 00000000..3c8c956b --- /dev/null +++ b/src/main/java/org/prgms/springbooturlshortener/domain/shorturl/service/UrlTransformer.java @@ -0,0 +1,22 @@ +package org.prgms.springbooturlshortener.domain.shorturl.service; + +import org.springframework.stereotype.Component; + +@Component +public class UrlTransformer { + private static final String BASE62_TOKENS = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; + private static final short numOfUrl = 6; + + public String generateUrl(int number) { + StringBuilder sb = new StringBuilder(); + + for (short i = 0; i < numOfUrl; i++) { + char token = BASE62_TOKENS.charAt(number % 62); + + sb.append(token); + number /= 62; + } + + return sb.toString(); + } +} From 9e9b702831f1b21e13d8fe056703bb7aed43e7ad Mon Sep 17 00:00:00 2001 From: ZZAMBAs Date: Wed, 13 Dec 2023 23:33:42 +0900 Subject: [PATCH 05/42] =?UTF-8?q?Feat:=20ShortUrl=EC=97=90=20=EB=B9=8C?= =?UTF-8?q?=EB=8D=94=20=ED=8C=A8=ED=84=B4=EC=9D=84=20=EC=B6=94=EA=B0=80?= =?UTF-8?q?=ED=95=9C=EB=8B=A4.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/shorturl/ShortUrl.java | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/main/java/org/prgms/springbooturlshortener/domain/shorturl/ShortUrl.java b/src/main/java/org/prgms/springbooturlshortener/domain/shorturl/ShortUrl.java index edca93ad..708e49cf 100644 --- a/src/main/java/org/prgms/springbooturlshortener/domain/shorturl/ShortUrl.java +++ b/src/main/java/org/prgms/springbooturlshortener/domain/shorturl/ShortUrl.java @@ -2,6 +2,8 @@ import jakarta.persistence.Entity; import jakarta.persistence.Id; +import lombok.Builder; +import lombok.Getter; import lombok.NoArgsConstructor; import java.time.LocalDateTime; @@ -10,6 +12,7 @@ @NoArgsConstructor public class ShortUrl { @Id + @Getter private String transformedUrl; private String originalUrl; @@ -17,4 +20,11 @@ public class ShortUrl { private Long visitCount; private LocalDateTime lastVisitTime; + + @Builder + public ShortUrl(String transformedUrl, String originalUrl) { + this.transformedUrl = transformedUrl; + this.originalUrl = originalUrl; + this.visitCount = 0L; + } } From c9891ae3035625ab30cef92320dd8004fde6d4a6 Mon Sep 17 00:00:00 2001 From: ZZAMBAs Date: Wed, 13 Dec 2023 23:34:36 +0900 Subject: [PATCH 06/42] =?UTF-8?q?Feat:=20UrlTransformer=EB=A5=BC=20?= =?UTF-8?q?=EC=9D=B8=ED=84=B0=ED=8E=98=EC=9D=B4=EC=8A=A4=20=ED=98=95?= =?UTF-8?q?=EC=8B=9D=EC=9C=BC=EB=A1=9C=20=EB=B3=80=EA=B2=BD=ED=95=98?= =?UTF-8?q?=EA=B3=A0=20BASE62=20=EA=B8=B0=EB=B0=98=20=EA=B5=AC=ED=98=84?= =?UTF-8?q?=EC=B2=B4=EB=A5=BC=20=EC=B6=94=EA=B0=80=ED=95=9C=EB=8B=A4.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../service/Base62UrlTransformer.java | 24 +++++++++++++++++++ .../shorturl/service/UrlTransformer.java | 21 ++-------------- 2 files changed, 26 insertions(+), 19 deletions(-) create mode 100644 src/main/java/org/prgms/springbooturlshortener/domain/shorturl/service/Base62UrlTransformer.java diff --git a/src/main/java/org/prgms/springbooturlshortener/domain/shorturl/service/Base62UrlTransformer.java b/src/main/java/org/prgms/springbooturlshortener/domain/shorturl/service/Base62UrlTransformer.java new file mode 100644 index 00000000..45502b00 --- /dev/null +++ b/src/main/java/org/prgms/springbooturlshortener/domain/shorturl/service/Base62UrlTransformer.java @@ -0,0 +1,24 @@ +package org.prgms.springbooturlshortener.domain.shorturl.service; + +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.stereotype.Component; + +@Component +@Qualifier("BASE62") +public class Base62UrlTransformer implements UrlTransformer{ + private static final String BASE62_TOKENS = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; + private static final short numOfUrl = 6; + + public String generateUrl(int number) { + StringBuilder sb = new StringBuilder(); + + for (short i = 0; i < numOfUrl; i++) { + char token = BASE62_TOKENS.charAt(number % 62); + + sb.append(token); + number /= 62; + } + + return sb.toString(); + } +} diff --git a/src/main/java/org/prgms/springbooturlshortener/domain/shorturl/service/UrlTransformer.java b/src/main/java/org/prgms/springbooturlshortener/domain/shorturl/service/UrlTransformer.java index 3c8c956b..06c8cd7c 100644 --- a/src/main/java/org/prgms/springbooturlshortener/domain/shorturl/service/UrlTransformer.java +++ b/src/main/java/org/prgms/springbooturlshortener/domain/shorturl/service/UrlTransformer.java @@ -1,22 +1,5 @@ package org.prgms.springbooturlshortener.domain.shorturl.service; -import org.springframework.stereotype.Component; - -@Component -public class UrlTransformer { - private static final String BASE62_TOKENS = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; - private static final short numOfUrl = 6; - - public String generateUrl(int number) { - StringBuilder sb = new StringBuilder(); - - for (short i = 0; i < numOfUrl; i++) { - char token = BASE62_TOKENS.charAt(number % 62); - - sb.append(token); - number /= 62; - } - - return sb.toString(); - } +public interface UrlTransformer { + String generateUrl(int number); } From ee7e7819339a64fc2da9076f79936dee6e628214 Mon Sep 17 00:00:00 2001 From: ZZAMBAs Date: Fri, 15 Dec 2023 00:04:50 +0900 Subject: [PATCH 07/42] =?UTF-8?q?Feat:=20Url=20=EC=B2=98=EB=A6=AC=20?= =?UTF-8?q?=EA=B4=80=EB=A0=A8=20=EC=98=88=EC=99=B8,=20=EC=97=90=EB=9F=AC?= =?UTF-8?q?=EC=BD=94=EB=93=9C=20=ED=81=B4=EB=9E=98=EC=8A=A4=EB=A5=BC=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80=ED=95=9C=EB=8B=A4.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/shorturl/exception/UrlErrorCode.java | 11 +++++++++++ .../domain/shorturl/exception/UrlException.java | 9 +++++++++ 2 files changed, 20 insertions(+) create mode 100644 src/main/java/org/prgms/springbooturlshortener/domain/shorturl/exception/UrlErrorCode.java create mode 100644 src/main/java/org/prgms/springbooturlshortener/domain/shorturl/exception/UrlException.java diff --git a/src/main/java/org/prgms/springbooturlshortener/domain/shorturl/exception/UrlErrorCode.java b/src/main/java/org/prgms/springbooturlshortener/domain/shorturl/exception/UrlErrorCode.java new file mode 100644 index 00000000..96721f44 --- /dev/null +++ b/src/main/java/org/prgms/springbooturlshortener/domain/shorturl/exception/UrlErrorCode.java @@ -0,0 +1,11 @@ +package org.prgms.springbooturlshortener.domain.shorturl.exception; + +public enum UrlErrorCode { + ORIGINAL_URL_NOT_FOUND(400); + + private final int errorCode; + + UrlErrorCode(int errorCode) { + this.errorCode = errorCode; + } +} diff --git a/src/main/java/org/prgms/springbooturlshortener/domain/shorturl/exception/UrlException.java b/src/main/java/org/prgms/springbooturlshortener/domain/shorturl/exception/UrlException.java new file mode 100644 index 00000000..5feece9c --- /dev/null +++ b/src/main/java/org/prgms/springbooturlshortener/domain/shorturl/exception/UrlException.java @@ -0,0 +1,9 @@ +package org.prgms.springbooturlshortener.domain.shorturl.exception; + +public class UrlException extends RuntimeException { + private UrlErrorCode urlErrorCode; + + public UrlException(UrlErrorCode urlErrorCode) { + this.urlErrorCode = urlErrorCode; + } +} From 77d1b9e63a27ef32049fa1b5e1c597476eb9f254 Mon Sep 17 00:00:00 2001 From: ZZAMBAs Date: Fri, 15 Dec 2023 00:28:43 +0900 Subject: [PATCH 08/42] =?UTF-8?q?Chore:=20MySQL=EC=9D=84=20=EC=82=AC?= =?UTF-8?q?=EC=9A=A9=ED=95=98=EB=8F=84=EB=A1=9D=20=EB=B9=8C=EB=93=9C=20?= =?UTF-8?q?=ED=8C=8C=EC=9D=BC=EA=B3=BC=20yml=20=ED=8C=8C=EC=9D=BC=EC=9D=98?= =?UTF-8?q?=20=EB=82=B4=EC=9A=A9=EC=9D=84=20=EC=88=98=EC=A0=95=ED=95=9C?= =?UTF-8?q?=EB=8B=A4.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- build.gradle | 1 + src/main/resources/application.yml | 11 +++++++++++ 2 files changed, 12 insertions(+) diff --git a/build.gradle b/build.gradle index f39369d1..789343b0 100644 --- a/build.gradle +++ b/build.gradle @@ -25,6 +25,7 @@ dependencies { implementation 'org.springframework.boot:spring-boot-starter' implementation 'org.springframework.boot:spring-boot-starter-web' implementation 'org.springframework.boot:spring-boot-starter-data-jpa' + implementation 'com.mysql:mysql-connector-j:8.2.0' implementation 'org.springframework.boot:spring-boot-starter-thymeleaf' compileOnly 'org.projectlombok:lombok' annotationProcessor 'org.projectlombok:lombok' diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index e69de29b..fe123acc 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -0,0 +1,11 @@ +spring: + datasource: + driver-class-name: com.mysql.cj.jdbc.Driver + username: root + password: 1234 + url: jdbc:mysql://localhost:8080/test + jpa: + properties: + hibernate: + show_sql: true + format_sql: true From 960b602313681dd9c07bee42f116be290092bd7c Mon Sep 17 00:00:00 2001 From: ZZAMBAs Date: Fri, 15 Dec 2023 00:39:34 +0900 Subject: [PATCH 09/42] =?UTF-8?q?Fix:=20=EC=9D=BC=EB=B6=80=20=EC=9E=98?= =?UTF-8?q?=EB=AA=BB=EB=90=9C=20=ED=99=98=EA=B2=BD=20=EC=84=A4=EC=A0=95,?= =?UTF-8?q?=20visitCount=EB=A5=BC=20=EB=8D=94=ED=95=98=EB=8A=94=20?= =?UTF-8?q?=EC=BF=BC=EB=A6=AC=EB=A5=BC=20=EC=A0=9C=EB=8C=80=EB=A1=9C=20?= =?UTF-8?q?=EC=88=98=EC=A0=95=ED=95=9C=EB=8B=A4.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/shorturl/repository/ShortUrlRepository.java | 3 +++ src/main/resources/application.yml | 2 +- src/main/resources/schema.sql | 2 +- 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/prgms/springbooturlshortener/domain/shorturl/repository/ShortUrlRepository.java b/src/main/java/org/prgms/springbooturlshortener/domain/shorturl/repository/ShortUrlRepository.java index 1e34a45e..2a28cd6e 100644 --- a/src/main/java/org/prgms/springbooturlshortener/domain/shorturl/repository/ShortUrlRepository.java +++ b/src/main/java/org/prgms/springbooturlshortener/domain/shorturl/repository/ShortUrlRepository.java @@ -2,6 +2,9 @@ import org.prgms.springbooturlshortener.domain.shorturl.ShortUrl; import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; public interface ShortUrlRepository extends JpaRepository { + @Query(value = "UPDATE ShortUrl s SET s.visitCount = s.visitCount + 1 WHERE s.transformedUrl = :transformedUrl") + void updateVisitCount(String transformedUrl); } diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index fe123acc..8dbfcc1b 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -3,7 +3,7 @@ spring: driver-class-name: com.mysql.cj.jdbc.Driver username: root password: 1234 - url: jdbc:mysql://localhost:8080/test + url: jdbc:mysql://localhost:3306/test jpa: properties: hibernate: diff --git a/src/main/resources/schema.sql b/src/main/resources/schema.sql index 91f08e66..e99d22a3 100644 --- a/src/main/resources/schema.sql +++ b/src/main/resources/schema.sql @@ -2,5 +2,5 @@ CREATE TABLE IF NOT EXISTS short_url ( transformed_url char(6) PRIMARY KEY, original_url varchar(2047) not null, visit_count bigint default 0 not null, - last_visit_time timestamp not null default current_timestamp(6) + last_visit_time timestamp(6) not null default current_timestamp(6) ); From 6b261f98d4d602ace083e5f28aa1659729bc38b3 Mon Sep 17 00:00:00 2001 From: ZZAMBAs Date: Fri, 15 Dec 2023 22:18:05 +0900 Subject: [PATCH 10/42] =?UTF-8?q?Feat:=20=EC=BD=94=EB=93=9C=EB=A5=BC=20?= =?UTF-8?q?=EA=B0=80=EB=8F=85=EC=84=B1=20=EC=A2=8B=EA=B2=8C=20=EC=88=98?= =?UTF-8?q?=EC=A0=95=ED=95=98=EA=B3=A0=20ShortUrl=EC=97=90=EC=84=9C=20?= =?UTF-8?q?=EB=B0=A9=EB=AC=B8=20=EC=B9=B4=EC=9A=B4=ED=8A=B8=EB=A5=BC=20?= =?UTF-8?q?=EC=98=AC=EB=A6=AC=EB=8A=94=20=EB=A9=94=EC=84=9C=EB=93=9C?= =?UTF-8?q?=EB=A5=BC=20=EC=B6=94=EA=B0=80=ED=95=9C=EB=8B=A4.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../springbooturlshortener/domain/shorturl/ShortUrl.java | 9 +++++++++ .../domain/shorturl/exception/UrlException.java | 2 +- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/src/main/java/org/prgms/springbooturlshortener/domain/shorturl/ShortUrl.java b/src/main/java/org/prgms/springbooturlshortener/domain/shorturl/ShortUrl.java index 708e49cf..e012eede 100644 --- a/src/main/java/org/prgms/springbooturlshortener/domain/shorturl/ShortUrl.java +++ b/src/main/java/org/prgms/springbooturlshortener/domain/shorturl/ShortUrl.java @@ -1,5 +1,6 @@ package org.prgms.springbooturlshortener.domain.shorturl; +import jakarta.persistence.Column; import jakarta.persistence.Entity; import jakarta.persistence.Id; import lombok.Builder; @@ -13,12 +14,16 @@ public class ShortUrl { @Id @Getter + @Column(name = "transformed_url") private String transformedUrl; + @Column(name = "original_url") private String originalUrl; + @Column(name = "visit_count") private Long visitCount; + @Column(name = "last_visit_time") private LocalDateTime lastVisitTime; @Builder @@ -27,4 +32,8 @@ public ShortUrl(String transformedUrl, String originalUrl) { this.originalUrl = originalUrl; this.visitCount = 0L; } + + public void increaseVisit() { + this.visitCount++; + } } diff --git a/src/main/java/org/prgms/springbooturlshortener/domain/shorturl/exception/UrlException.java b/src/main/java/org/prgms/springbooturlshortener/domain/shorturl/exception/UrlException.java index 5feece9c..f02436f1 100644 --- a/src/main/java/org/prgms/springbooturlshortener/domain/shorturl/exception/UrlException.java +++ b/src/main/java/org/prgms/springbooturlshortener/domain/shorturl/exception/UrlException.java @@ -1,7 +1,7 @@ package org.prgms.springbooturlshortener.domain.shorturl.exception; public class UrlException extends RuntimeException { - private UrlErrorCode urlErrorCode; + private final UrlErrorCode urlErrorCode; public UrlException(UrlErrorCode urlErrorCode) { this.urlErrorCode = urlErrorCode; From 7643d3cda77536e78dd9b22f5657b93c11376150 Mon Sep 17 00:00:00 2001 From: ZZAMBAs Date: Fri, 15 Dec 2023 22:18:52 +0900 Subject: [PATCH 11/42] =?UTF-8?q?Feat:=20URL=20=EC=A0=80=EC=9E=A5,=20?= =?UTF-8?q?=EA=B0=80=EC=A0=B8=EC=98=A4=EA=B8=B0=EB=A5=BC=20=EA=B5=AC?= =?UTF-8?q?=ED=98=84=ED=95=9C=20=EC=84=9C=EB=B9=84=EC=8A=A4=EB=A5=BC=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80=ED=95=9C=EB=8B=A4.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../shorturl/service/ShortUrlService.java | 54 +++++++++++++++++++ 1 file changed, 54 insertions(+) create mode 100644 src/main/java/org/prgms/springbooturlshortener/domain/shorturl/service/ShortUrlService.java diff --git a/src/main/java/org/prgms/springbooturlshortener/domain/shorturl/service/ShortUrlService.java b/src/main/java/org/prgms/springbooturlshortener/domain/shorturl/service/ShortUrlService.java new file mode 100644 index 00000000..367f2645 --- /dev/null +++ b/src/main/java/org/prgms/springbooturlshortener/domain/shorturl/service/ShortUrlService.java @@ -0,0 +1,54 @@ +package org.prgms.springbooturlshortener.domain.shorturl.service; + +import org.prgms.springbooturlshortener.domain.shorturl.ShortUrl; +import org.prgms.springbooturlshortener.domain.shorturl.exception.UrlErrorCode; +import org.prgms.springbooturlshortener.domain.shorturl.exception.UrlException; +import org.prgms.springbooturlshortener.domain.shorturl.repository.ShortUrlRepository; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.stereotype.Service; + +import java.util.Random; + +@Service +public class ShortUrlService { + private final UrlTransformer urlTransformer; + private final ShortUrlRepository urlRepository; + + public ShortUrlService(@Qualifier("BASE62") UrlTransformer urlTransformer, ShortUrlRepository urlRepository) { + this.urlTransformer = urlTransformer; + this.urlRepository = urlRepository; + } + + public String saveOriginalUrl(String originalUrl) { + Random random = new Random(); + int randomInt = random.nextInt(); + String generatedUrl = urlTransformer.generateUrl(randomInt); + + while (urlRepository.findById(generatedUrl).isPresent()) { + randomInt = random.nextInt(); + generatedUrl = urlTransformer.generateUrl(randomInt); + } + + ShortUrl shortUrl = ShortUrl.builder() + .transformedUrl(generatedUrl) + .originalUrl(originalUrl) + .build(); + ShortUrl savedShortUrl = urlRepository.save(shortUrl); + + return savedShortUrl.getTransformedUrl(); + } + + public String getOriginalUrl(String encodedUrl) { + ShortUrl shortUrl = urlRepository.findById(encodedUrl) + .orElseThrow(() -> new UrlException(UrlErrorCode.ORIGINAL_URL_NOT_FOUND)); + + increaseVisit(shortUrl); + + return shortUrl.getTransformedUrl(); + } + + private void increaseVisit(ShortUrl shortUrl) { + shortUrl.increaseVisit(); + urlRepository.updateVisitCount(shortUrl.getTransformedUrl()); + } +} From 41e87046f5edebc5f0072d6d12925ced1cf72876 Mon Sep 17 00:00:00 2001 From: ZZAMBAs Date: Fri, 15 Dec 2023 23:02:07 +0900 Subject: [PATCH 12/42] =?UTF-8?q?Test:=20=ED=85=8C=EC=8A=A4=ED=8A=B8?= =?UTF-8?q?=EC=9A=A9=20yml=20=ED=8C=8C=EC=9D=BC=EC=9D=84=20=EC=83=9D?= =?UTF-8?q?=EC=84=B1=ED=95=9C=EB=8B=A4.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/resources/application.yml | 2 +- src/test/resources/application.yml | 11 +++++++++++ 2 files changed, 12 insertions(+), 1 deletion(-) create mode 100644 src/test/resources/application.yml diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index 8dbfcc1b..3f682214 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -3,7 +3,7 @@ spring: driver-class-name: com.mysql.cj.jdbc.Driver username: root password: 1234 - url: jdbc:mysql://localhost:3306/test + url: jdbc:mysql://localhost:3306/prod jpa: properties: hibernate: diff --git a/src/test/resources/application.yml b/src/test/resources/application.yml new file mode 100644 index 00000000..8dbfcc1b --- /dev/null +++ b/src/test/resources/application.yml @@ -0,0 +1,11 @@ +spring: + datasource: + driver-class-name: com.mysql.cj.jdbc.Driver + username: root + password: 1234 + url: jdbc:mysql://localhost:3306/test + jpa: + properties: + hibernate: + show_sql: true + format_sql: true From c26e7e5ab192d3ada5024643e4269ccad1abd17a Mon Sep 17 00:00:00 2001 From: ZZAMBAs Date: Fri, 15 Dec 2023 23:02:31 +0900 Subject: [PATCH 13/42] =?UTF-8?q?Fix:=20=EB=9E=9C=EB=8D=A4=20=EC=A0=95?= =?UTF-8?q?=EC=88=98=EA=B0=80=20=EC=9D=8C=EC=88=98=EA=B0=80=20=EB=90=98?= =?UTF-8?q?=EC=A7=80=20=EC=95=8A=EB=8F=84=EB=A1=9D=20=EC=88=98=EC=A0=95?= =?UTF-8?q?=ED=95=9C=EB=8B=A4.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/shorturl/service/ShortUrlService.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main/java/org/prgms/springbooturlshortener/domain/shorturl/service/ShortUrlService.java b/src/main/java/org/prgms/springbooturlshortener/domain/shorturl/service/ShortUrlService.java index 367f2645..d6883b5d 100644 --- a/src/main/java/org/prgms/springbooturlshortener/domain/shorturl/service/ShortUrlService.java +++ b/src/main/java/org/prgms/springbooturlshortener/domain/shorturl/service/ShortUrlService.java @@ -21,11 +21,11 @@ public ShortUrlService(@Qualifier("BASE62") UrlTransformer urlTransformer, Short public String saveOriginalUrl(String originalUrl) { Random random = new Random(); - int randomInt = random.nextInt(); + int randomInt = random.nextInt(0, Integer.MAX_VALUE); String generatedUrl = urlTransformer.generateUrl(randomInt); while (urlRepository.findById(generatedUrl).isPresent()) { - randomInt = random.nextInt(); + randomInt = random.nextInt(0, Integer.MAX_VALUE); generatedUrl = urlTransformer.generateUrl(randomInt); } @@ -44,11 +44,11 @@ public String getOriginalUrl(String encodedUrl) { increaseVisit(shortUrl); - return shortUrl.getTransformedUrl(); + return shortUrl.getOriginalUrl(); } private void increaseVisit(ShortUrl shortUrl) { shortUrl.increaseVisit(); - urlRepository.updateVisitCount(shortUrl.getTransformedUrl()); + urlRepository.save(shortUrl); } } From 7d638e72f4de906f864b0fa743b3de21bc43aaff Mon Sep 17 00:00:00 2001 From: ZZAMBAs Date: Fri, 15 Dec 2023 23:03:24 +0900 Subject: [PATCH 14/42] =?UTF-8?q?Feat:=20null=EC=9D=80=20=EC=BF=BC?= =?UTF-8?q?=EB=A6=AC=EC=97=90=20=ED=8F=AC=ED=95=A8=EC=8B=9C=ED=82=A4?= =?UTF-8?q?=EC=A7=80=20=EC=95=8A=EB=8F=84=EB=A1=9D=20=ED=95=98=EA=B3=A0=20?= =?UTF-8?q?originalUrl=EC=97=90=20getter=EB=A5=BC=20=EC=B6=94=EA=B0=80?= =?UTF-8?q?=ED=95=9C=EB=8B=A4.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../springbooturlshortener/domain/shorturl/ShortUrl.java | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/prgms/springbooturlshortener/domain/shorturl/ShortUrl.java b/src/main/java/org/prgms/springbooturlshortener/domain/shorturl/ShortUrl.java index e012eede..ac05728c 100644 --- a/src/main/java/org/prgms/springbooturlshortener/domain/shorturl/ShortUrl.java +++ b/src/main/java/org/prgms/springbooturlshortener/domain/shorturl/ShortUrl.java @@ -6,21 +6,26 @@ import lombok.Builder; import lombok.Getter; import lombok.NoArgsConstructor; +import org.hibernate.annotations.DynamicInsert; +import org.hibernate.annotations.DynamicUpdate; import java.time.LocalDateTime; @Entity @NoArgsConstructor +@DynamicInsert +@DynamicUpdate public class ShortUrl { @Id @Getter @Column(name = "transformed_url") private String transformedUrl; - @Column(name = "original_url") + @Getter + @Column(name = "original_url", nullable = false) private String originalUrl; - @Column(name = "visit_count") + @Column(name = "visit_count", nullable = false) private Long visitCount; @Column(name = "last_visit_time") From 9172394bbb1d760a810708accf3b1b49b11d569e Mon Sep 17 00:00:00 2001 From: ZZAMBAs Date: Fri, 15 Dec 2023 23:04:09 +0900 Subject: [PATCH 15/42] =?UTF-8?q?Test:=20shortUrlService=EC=9D=98=20?= =?UTF-8?q?=EA=B8=B0=EB=8A=A5=EC=9D=84=20=ED=85=8C=EC=8A=A4=ED=8A=B8?= =?UTF-8?q?=ED=95=98=EB=8A=94=20=EC=BD=94=EB=93=9C=EB=A5=BC=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80=ED=95=9C=EB=8B=A4.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../repository/ShortUrlRepository.java | 3 -- .../shorturl/service/ShortUrlServiceTest.java | 52 +++++++++++++++++++ 2 files changed, 52 insertions(+), 3 deletions(-) create mode 100644 src/test/java/org/prgms/springbooturlshortener/domain/shorturl/service/ShortUrlServiceTest.java diff --git a/src/main/java/org/prgms/springbooturlshortener/domain/shorturl/repository/ShortUrlRepository.java b/src/main/java/org/prgms/springbooturlshortener/domain/shorturl/repository/ShortUrlRepository.java index 2a28cd6e..1e34a45e 100644 --- a/src/main/java/org/prgms/springbooturlshortener/domain/shorturl/repository/ShortUrlRepository.java +++ b/src/main/java/org/prgms/springbooturlshortener/domain/shorturl/repository/ShortUrlRepository.java @@ -2,9 +2,6 @@ import org.prgms.springbooturlshortener.domain.shorturl.ShortUrl; import org.springframework.data.jpa.repository.JpaRepository; -import org.springframework.data.jpa.repository.Query; public interface ShortUrlRepository extends JpaRepository { - @Query(value = "UPDATE ShortUrl s SET s.visitCount = s.visitCount + 1 WHERE s.transformedUrl = :transformedUrl") - void updateVisitCount(String transformedUrl); } diff --git a/src/test/java/org/prgms/springbooturlshortener/domain/shorturl/service/ShortUrlServiceTest.java b/src/test/java/org/prgms/springbooturlshortener/domain/shorturl/service/ShortUrlServiceTest.java new file mode 100644 index 00000000..4eae5e7c --- /dev/null +++ b/src/test/java/org/prgms/springbooturlshortener/domain/shorturl/service/ShortUrlServiceTest.java @@ -0,0 +1,52 @@ +package org.prgms.springbooturlshortener.domain.shorturl.service; + +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.prgms.springbooturlshortener.domain.shorturl.ShortUrl; +import org.prgms.springbooturlshortener.domain.shorturl.exception.UrlErrorCode; +import org.prgms.springbooturlshortener.domain.shorturl.exception.UrlException; +import org.prgms.springbooturlshortener.domain.shorturl.repository.ShortUrlRepository; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; + +import static org.assertj.core.api.Assertions.assertThat; + +@SpringBootTest +class ShortUrlServiceTest { + @Autowired + private ShortUrlService shortUrlService; + @Autowired + private ShortUrlRepository shortUrlRepository; + + private String preSavedOriginalUrl = "youtube.com"; + private String preSavedTransformedUrl; + + @BeforeEach + void setUp() { + preSavedTransformedUrl = shortUrlService.saveOriginalUrl(preSavedOriginalUrl); + } + + @AfterEach + void tearDown() { + shortUrlRepository.deleteAll(); + } + + @Test + void saveOriginalUrl() { + String originalUrl = "https://naver.com"; + String transformedUrl = shortUrlService.saveOriginalUrl(originalUrl); + + ShortUrl savedShortUrl = shortUrlRepository.findById(transformedUrl) + .orElseThrow(() -> new UrlException(UrlErrorCode.ORIGINAL_URL_NOT_FOUND)); + + assertThat(savedShortUrl.getTransformedUrl()).isEqualTo(transformedUrl); + } + + @Test + void getOriginalUrl() { + String originalUrl = shortUrlService.getOriginalUrl(preSavedTransformedUrl); + + assertThat(originalUrl).isEqualTo(preSavedOriginalUrl); + } +} From 2b834650c5132fd9f3723594b0720f5eff7a0bc5 Mon Sep 17 00:00:00 2001 From: ZZAMBAs Date: Fri, 15 Dec 2023 23:36:56 +0900 Subject: [PATCH 16/42] =?UTF-8?q?Feat:=20saveOriginalUrl()=EC=97=90?= =?UTF-8?q?=EC=84=9C=20=EC=9D=B4=EB=AF=B8=20=EC=A0=80=EC=9E=A5=EB=90=9C=20?= =?UTF-8?q?original=20Url=EC=9D=80=20=EB=B0=94=EB=A1=9C=20=EB=B0=98?= =?UTF-8?q?=ED=99=98=ED=95=98=EB=8F=84=EB=A1=9D=20=ED=95=9C=EB=8B=A4.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../repository/ShortUrlRepository.java | 3 ++ .../shorturl/service/ShortUrlService.java | 41 ++++++++++++++----- 2 files changed, 33 insertions(+), 11 deletions(-) diff --git a/src/main/java/org/prgms/springbooturlshortener/domain/shorturl/repository/ShortUrlRepository.java b/src/main/java/org/prgms/springbooturlshortener/domain/shorturl/repository/ShortUrlRepository.java index 1e34a45e..79a9f7e7 100644 --- a/src/main/java/org/prgms/springbooturlshortener/domain/shorturl/repository/ShortUrlRepository.java +++ b/src/main/java/org/prgms/springbooturlshortener/domain/shorturl/repository/ShortUrlRepository.java @@ -3,5 +3,8 @@ import org.prgms.springbooturlshortener.domain.shorturl.ShortUrl; import org.springframework.data.jpa.repository.JpaRepository; +import java.util.Optional; + public interface ShortUrlRepository extends JpaRepository { + Optional findByOriginalUrl(String originalUrl); } diff --git a/src/main/java/org/prgms/springbooturlshortener/domain/shorturl/service/ShortUrlService.java b/src/main/java/org/prgms/springbooturlshortener/domain/shorturl/service/ShortUrlService.java index d6883b5d..e996b6ed 100644 --- a/src/main/java/org/prgms/springbooturlshortener/domain/shorturl/service/ShortUrlService.java +++ b/src/main/java/org/prgms/springbooturlshortener/domain/shorturl/service/ShortUrlService.java @@ -7,6 +7,7 @@ import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.stereotype.Service; +import java.util.Optional; import java.util.Random; @Service @@ -20,20 +21,17 @@ public ShortUrlService(@Qualifier("BASE62") UrlTransformer urlTransformer, Short } public String saveOriginalUrl(String originalUrl) { - Random random = new Random(); - int randomInt = random.nextInt(0, Integer.MAX_VALUE); - String generatedUrl = urlTransformer.generateUrl(randomInt); + Optional foundShortUrl = urlRepository.findByOriginalUrl(originalUrl); - while (urlRepository.findById(generatedUrl).isPresent()) { - randomInt = random.nextInt(0, Integer.MAX_VALUE); - generatedUrl = urlTransformer.generateUrl(randomInt); + if (foundShortUrl.isPresent()) { + return foundShortUrl.get().getTransformedUrl(); } - ShortUrl shortUrl = ShortUrl.builder() - .transformedUrl(generatedUrl) - .originalUrl(originalUrl) - .build(); - ShortUrl savedShortUrl = urlRepository.save(shortUrl); + String generatedUrl; + + generatedUrl = getRandomUrl(); + + ShortUrl savedShortUrl = getSavedShortUrl(originalUrl, generatedUrl); return savedShortUrl.getTransformedUrl(); } @@ -47,6 +45,27 @@ public String getOriginalUrl(String encodedUrl) { return shortUrl.getOriginalUrl(); } + private ShortUrl getSavedShortUrl(String originalUrl, String generatedUrl) { + ShortUrl shortUrl = ShortUrl.builder() + .transformedUrl(generatedUrl) + .originalUrl(originalUrl) + .build(); + return urlRepository.save(shortUrl); + } + + private String getRandomUrl() { + Random random = new Random(); + String generatedUrl; + int randomInt; + + do { + randomInt = random.nextInt(0, Integer.MAX_VALUE); + generatedUrl = urlTransformer.generateUrl(randomInt); + } while (urlRepository.findById(generatedUrl).isPresent()); + + return generatedUrl; + } + private void increaseVisit(ShortUrl shortUrl) { shortUrl.increaseVisit(); urlRepository.save(shortUrl); From 4f9300bd823912a689472050c68114e08691f306 Mon Sep 17 00:00:00 2001 From: ZZAMBAs Date: Fri, 15 Dec 2023 23:37:25 +0900 Subject: [PATCH 17/42] =?UTF-8?q?Test:=20=EC=9D=B4=EB=AF=B8=20=EC=A0=80?= =?UTF-8?q?=EC=9E=A5=EB=90=9C=20url=EC=97=90=20=EB=8C=80=ED=95=B4=20?= =?UTF-8?q?=EA=B0=99=EC=9D=80=20url=EC=9D=84=20=EB=B0=98=ED=99=98=ED=95=98?= =?UTF-8?q?=EB=8A=94=20=ED=85=8C=EC=8A=A4=ED=8A=B8=EB=A5=BC=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80=ED=95=9C=EB=8B=A4.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/shorturl/service/ShortUrlServiceTest.java | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/test/java/org/prgms/springbooturlshortener/domain/shorturl/service/ShortUrlServiceTest.java b/src/test/java/org/prgms/springbooturlshortener/domain/shorturl/service/ShortUrlServiceTest.java index 4eae5e7c..1d223fa9 100644 --- a/src/test/java/org/prgms/springbooturlshortener/domain/shorturl/service/ShortUrlServiceTest.java +++ b/src/test/java/org/prgms/springbooturlshortener/domain/shorturl/service/ShortUrlServiceTest.java @@ -33,7 +33,7 @@ void tearDown() { } @Test - void saveOriginalUrl() { + void saveNewOriginalUrl() { String originalUrl = "https://naver.com"; String transformedUrl = shortUrlService.saveOriginalUrl(originalUrl); @@ -43,6 +43,13 @@ void saveOriginalUrl() { assertThat(savedShortUrl.getTransformedUrl()).isEqualTo(transformedUrl); } + @Test + void getAlreadyExistingOriginalUrl() { + String transformedUrl = shortUrlService.saveOriginalUrl(preSavedOriginalUrl); + + assertThat(transformedUrl).isEqualTo(preSavedTransformedUrl); + } + @Test void getOriginalUrl() { String originalUrl = shortUrlService.getOriginalUrl(preSavedTransformedUrl); From 2853a6d25fd84b6738323c153e5ce81bf994bcf7 Mon Sep 17 00:00:00 2001 From: ZZAMBAs Date: Fri, 15 Dec 2023 23:57:11 +0900 Subject: [PATCH 18/42] =?UTF-8?q?Rename:=20=ED=8C=A8=ED=82=A4=EC=A7=80?= =?UTF-8?q?=EB=A5=BC=20=EC=84=B8=EB=B6=84=ED=99=94=ED=95=9C=EB=8B=A4.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/shorturl/service/ShortUrlService.java | 1 + .../service/{ => transformer}/Base62UrlTransformer.java | 2 +- .../shorturl/service/{ => transformer}/UrlTransformer.java | 2 +- 3 files changed, 3 insertions(+), 2 deletions(-) rename src/main/java/org/prgms/springbooturlshortener/domain/shorturl/service/{ => transformer}/Base62UrlTransformer.java (98%) rename src/main/java/org/prgms/springbooturlshortener/domain/shorturl/service/{ => transformer}/UrlTransformer.java (90%) diff --git a/src/main/java/org/prgms/springbooturlshortener/domain/shorturl/service/ShortUrlService.java b/src/main/java/org/prgms/springbooturlshortener/domain/shorturl/service/ShortUrlService.java index e996b6ed..19605265 100644 --- a/src/main/java/org/prgms/springbooturlshortener/domain/shorturl/service/ShortUrlService.java +++ b/src/main/java/org/prgms/springbooturlshortener/domain/shorturl/service/ShortUrlService.java @@ -4,6 +4,7 @@ import org.prgms.springbooturlshortener.domain.shorturl.exception.UrlErrorCode; import org.prgms.springbooturlshortener.domain.shorturl.exception.UrlException; import org.prgms.springbooturlshortener.domain.shorturl.repository.ShortUrlRepository; +import org.prgms.springbooturlshortener.domain.shorturl.service.transformer.UrlTransformer; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.stereotype.Service; diff --git a/src/main/java/org/prgms/springbooturlshortener/domain/shorturl/service/Base62UrlTransformer.java b/src/main/java/org/prgms/springbooturlshortener/domain/shorturl/service/transformer/Base62UrlTransformer.java similarity index 98% rename from src/main/java/org/prgms/springbooturlshortener/domain/shorturl/service/Base62UrlTransformer.java rename to src/main/java/org/prgms/springbooturlshortener/domain/shorturl/service/transformer/Base62UrlTransformer.java index 45502b00..27b00e8e 100644 --- a/src/main/java/org/prgms/springbooturlshortener/domain/shorturl/service/Base62UrlTransformer.java +++ b/src/main/java/org/prgms/springbooturlshortener/domain/shorturl/service/transformer/Base62UrlTransformer.java @@ -1,4 +1,4 @@ -package org.prgms.springbooturlshortener.domain.shorturl.service; +package org.prgms.springbooturlshortener.domain.shorturl.service.transformer; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.stereotype.Component; diff --git a/src/main/java/org/prgms/springbooturlshortener/domain/shorturl/service/UrlTransformer.java b/src/main/java/org/prgms/springbooturlshortener/domain/shorturl/service/transformer/UrlTransformer.java similarity index 90% rename from src/main/java/org/prgms/springbooturlshortener/domain/shorturl/service/UrlTransformer.java rename to src/main/java/org/prgms/springbooturlshortener/domain/shorturl/service/transformer/UrlTransformer.java index 06c8cd7c..e308add1 100644 --- a/src/main/java/org/prgms/springbooturlshortener/domain/shorturl/service/UrlTransformer.java +++ b/src/main/java/org/prgms/springbooturlshortener/domain/shorturl/service/transformer/UrlTransformer.java @@ -1,4 +1,4 @@ -package org.prgms.springbooturlshortener.domain.shorturl.service; +package org.prgms.springbooturlshortener.domain.shorturl.service.transformer; public interface UrlTransformer { String generateUrl(int number); From 027c9094975fde6be32897034e9d98a783e8abe6 Mon Sep 17 00:00:00 2001 From: ZZAMBAs Date: Sat, 16 Dec 2023 16:28:16 +0900 Subject: [PATCH 19/42] =?UTF-8?q?Feat:=20=EC=B5=9C=EC=B4=88=20=ED=8E=98?= =?UTF-8?q?=EC=9D=B4=EC=A7=80=EB=A5=BC=20=EC=83=9D=EC=84=B1=ED=95=9C?= =?UTF-8?q?=EB=8B=A4.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/resources/templates/index.html | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 src/main/resources/templates/index.html diff --git a/src/main/resources/templates/index.html b/src/main/resources/templates/index.html new file mode 100644 index 00000000..a1aff832 --- /dev/null +++ b/src/main/resources/templates/index.html @@ -0,0 +1,19 @@ + + + + + URL Shortener + +
+ +
+ +

아래에 변환할 URL을 붙여 넣으세요!

+
+ + +
+ + From b41f1de76a092ba1fcfdbe4ef3127910f5ec93dc Mon Sep 17 00:00:00 2001 From: ZZAMBAs Date: Sun, 17 Dec 2023 11:59:36 +0900 Subject: [PATCH 20/42] =?UTF-8?q?Feat:=20=EB=B9=A0=EB=A5=B8=20=ED=83=90?= =?UTF-8?q?=EC=83=89=EC=9D=84=20=EC=9C=84=ED=95=B4=20=EC=9D=B8=EB=8D=B1?= =?UTF-8?q?=EC=8B=B1=EC=9D=84=20=EC=B6=94=EA=B0=80=ED=95=9C=EB=8B=A4.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/resources/schema.sql | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/main/resources/schema.sql b/src/main/resources/schema.sql index e99d22a3..94fa0bb2 100644 --- a/src/main/resources/schema.sql +++ b/src/main/resources/schema.sql @@ -1,6 +1,7 @@ CREATE TABLE IF NOT EXISTS short_url ( - transformed_url char(6) PRIMARY KEY, - original_url varchar(2047) not null, - visit_count bigint default 0 not null, - last_visit_time timestamp(6) not null default current_timestamp(6) + transformed_url CHAR(6) PRIMARY KEY, + original_url VARCHAR(2047) NOT NULL, + visit_count BIGINT DEFAULT 0 NOT NULL, + last_visit_time TIMESTAMP(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6), + INDEX idx_original_url (original_url(255)) ); From 9970d68373df56183aa7d3ca36cd147da509d8d6 Mon Sep 17 00:00:00 2001 From: ZZAMBAs Date: Sun, 17 Dec 2023 12:00:31 +0900 Subject: [PATCH 21/42] =?UTF-8?q?Feat:=20DTO=EB=A5=BC=20=EC=B6=94=EA=B0=80?= =?UTF-8?q?=ED=95=98=EA=B3=A0=20=EC=A0=81=EC=9A=A9=ED=95=9C=EB=8B=A4.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/shorturl/ShortUrl.java | 6 ++++++ .../shorturl/service/ShortUrlService.java | 12 ++++++----- .../service/dto/TransformRequestUrlDto.java | 4 ++++ .../service/dto/TransformedShortUrlDto.java | 21 +++++++++++++++++++ 4 files changed, 38 insertions(+), 5 deletions(-) create mode 100644 src/main/java/org/prgms/springbooturlshortener/domain/shorturl/service/dto/TransformRequestUrlDto.java create mode 100644 src/main/java/org/prgms/springbooturlshortener/domain/shorturl/service/dto/TransformedShortUrlDto.java diff --git a/src/main/java/org/prgms/springbooturlshortener/domain/shorturl/ShortUrl.java b/src/main/java/org/prgms/springbooturlshortener/domain/shorturl/ShortUrl.java index ac05728c..91e48d9b 100644 --- a/src/main/java/org/prgms/springbooturlshortener/domain/shorturl/ShortUrl.java +++ b/src/main/java/org/prgms/springbooturlshortener/domain/shorturl/ShortUrl.java @@ -8,6 +8,7 @@ import lombok.NoArgsConstructor; import org.hibernate.annotations.DynamicInsert; import org.hibernate.annotations.DynamicUpdate; +import org.prgms.springbooturlshortener.domain.shorturl.service.dto.TransformedShortUrlDto; import java.time.LocalDateTime; @@ -36,9 +37,14 @@ public ShortUrl(String transformedUrl, String originalUrl) { this.transformedUrl = transformedUrl; this.originalUrl = originalUrl; this.visitCount = 0L; + this.lastVisitTime = null; } public void increaseVisit() { this.visitCount++; } + + public TransformedShortUrlDto toTransformedShortUrlDto() { + return new TransformedShortUrlDto(this.transformedUrl, this.visitCount, this.lastVisitTime); + } } diff --git a/src/main/java/org/prgms/springbooturlshortener/domain/shorturl/service/ShortUrlService.java b/src/main/java/org/prgms/springbooturlshortener/domain/shorturl/service/ShortUrlService.java index 19605265..3531f2e1 100644 --- a/src/main/java/org/prgms/springbooturlshortener/domain/shorturl/service/ShortUrlService.java +++ b/src/main/java/org/prgms/springbooturlshortener/domain/shorturl/service/ShortUrlService.java @@ -4,6 +4,7 @@ import org.prgms.springbooturlshortener.domain.shorturl.exception.UrlErrorCode; import org.prgms.springbooturlshortener.domain.shorturl.exception.UrlException; import org.prgms.springbooturlshortener.domain.shorturl.repository.ShortUrlRepository; +import org.prgms.springbooturlshortener.domain.shorturl.service.dto.TransformedShortUrlDto; import org.prgms.springbooturlshortener.domain.shorturl.service.transformer.UrlTransformer; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.stereotype.Service; @@ -21,11 +22,12 @@ public ShortUrlService(@Qualifier("BASE62") UrlTransformer urlTransformer, Short this.urlRepository = urlRepository; } - public String saveOriginalUrl(String originalUrl) { + public TransformedShortUrlDto saveOriginalUrl(String originalUrl) { Optional foundShortUrl = urlRepository.findByOriginalUrl(originalUrl); if (foundShortUrl.isPresent()) { - return foundShortUrl.get().getTransformedUrl(); + ShortUrl shortUrl = foundShortUrl.get(); + return shortUrl.toTransformedShortUrlDto(); } String generatedUrl; @@ -34,11 +36,11 @@ public String saveOriginalUrl(String originalUrl) { ShortUrl savedShortUrl = getSavedShortUrl(originalUrl, generatedUrl); - return savedShortUrl.getTransformedUrl(); + return savedShortUrl.toTransformedShortUrlDto(); } - public String getOriginalUrl(String encodedUrl) { - ShortUrl shortUrl = urlRepository.findById(encodedUrl) + public String getOriginalUrl(String transformedUrl) { + ShortUrl shortUrl = urlRepository.findById(transformedUrl) .orElseThrow(() -> new UrlException(UrlErrorCode.ORIGINAL_URL_NOT_FOUND)); increaseVisit(shortUrl); diff --git a/src/main/java/org/prgms/springbooturlshortener/domain/shorturl/service/dto/TransformRequestUrlDto.java b/src/main/java/org/prgms/springbooturlshortener/domain/shorturl/service/dto/TransformRequestUrlDto.java new file mode 100644 index 00000000..4e9ee36b --- /dev/null +++ b/src/main/java/org/prgms/springbooturlshortener/domain/shorturl/service/dto/TransformRequestUrlDto.java @@ -0,0 +1,4 @@ +package org.prgms.springbooturlshortener.domain.shorturl.service.dto; + +public record TransformRequestUrlDto (String originalUrl) { +} diff --git a/src/main/java/org/prgms/springbooturlshortener/domain/shorturl/service/dto/TransformedShortUrlDto.java b/src/main/java/org/prgms/springbooturlshortener/domain/shorturl/service/dto/TransformedShortUrlDto.java new file mode 100644 index 00000000..0e28d180 --- /dev/null +++ b/src/main/java/org/prgms/springbooturlshortener/domain/shorturl/service/dto/TransformedShortUrlDto.java @@ -0,0 +1,21 @@ +package org.prgms.springbooturlshortener.domain.shorturl.service.dto; + +import java.time.LocalDateTime; +import java.util.Objects; + +public record TransformedShortUrlDto (String shortUrl, + Long visitCount, + LocalDateTime lastVisitTime) { + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + TransformedShortUrlDto that = (TransformedShortUrlDto) o; + return Objects.equals(shortUrl, that.shortUrl) && Objects.equals(visitCount, that.visitCount) && Objects.equals(lastVisitTime, that.lastVisitTime); + } + + @Override + public int hashCode() { + return Objects.hash(shortUrl, visitCount, lastVisitTime); + } +} From d0692539d3f825adbaa838b663f44c7556040440 Mon Sep 17 00:00:00 2001 From: ZZAMBAs Date: Sun, 17 Dec 2023 12:05:47 +0900 Subject: [PATCH 22/42] =?UTF-8?q?Test:=20DTO=EC=97=90=20=EB=A7=9E=EA=B2=8C?= =?UTF-8?q?=20=ED=85=8C=EC=8A=A4=ED=8A=B8=20=EC=BD=94=EB=93=9C=EB=A5=BC=20?= =?UTF-8?q?=EC=88=98=EC=A0=95=ED=95=98=EA=B3=A0,=20short=20url=20=EB=B0=A9?= =?UTF-8?q?=EB=AC=B8=20=EC=8B=9C=20=EC=97=85=EB=8D=B0=EC=9D=B4=ED=8A=B8=20?= =?UTF-8?q?=EB=90=98=EB=8A=94=EC=A7=80=20=ED=99=95=EC=9D=B8=ED=95=98?= =?UTF-8?q?=EB=8A=94=20=ED=85=8C=EC=8A=A4=ED=8A=B8=EB=A5=BC=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80=ED=95=9C=EB=8B=A4.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../shorturl/service/ShortUrlServiceTest.java | 44 +++++++++++++++---- 1 file changed, 35 insertions(+), 9 deletions(-) diff --git a/src/test/java/org/prgms/springbooturlshortener/domain/shorturl/service/ShortUrlServiceTest.java b/src/test/java/org/prgms/springbooturlshortener/domain/shorturl/service/ShortUrlServiceTest.java index 1d223fa9..bfe95cf0 100644 --- a/src/test/java/org/prgms/springbooturlshortener/domain/shorturl/service/ShortUrlServiceTest.java +++ b/src/test/java/org/prgms/springbooturlshortener/domain/shorturl/service/ShortUrlServiceTest.java @@ -1,30 +1,36 @@ package org.prgms.springbooturlshortener.domain.shorturl.service; +import lombok.extern.slf4j.Slf4j; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import org.prgms.springbooturlshortener.domain.shorturl.ShortUrl; import org.prgms.springbooturlshortener.domain.shorturl.exception.UrlErrorCode; import org.prgms.springbooturlshortener.domain.shorturl.exception.UrlException; import org.prgms.springbooturlshortener.domain.shorturl.repository.ShortUrlRepository; +import org.prgms.springbooturlshortener.domain.shorturl.service.dto.TransformedShortUrlDto; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; +import java.util.Optional; + import static org.assertj.core.api.Assertions.assertThat; @SpringBootTest +@Slf4j class ShortUrlServiceTest { @Autowired private ShortUrlService shortUrlService; @Autowired private ShortUrlRepository shortUrlRepository; - private String preSavedOriginalUrl = "youtube.com"; - private String preSavedTransformedUrl; + private final String preSavedOriginalUrl = "youtube.com"; + private TransformedShortUrlDto preSavedTransformedShortUrlDto; @BeforeEach void setUp() { - preSavedTransformedUrl = shortUrlService.saveOriginalUrl(preSavedOriginalUrl); + preSavedTransformedShortUrlDto = shortUrlService.saveOriginalUrl(preSavedOriginalUrl); } @AfterEach @@ -33,27 +39,47 @@ void tearDown() { } @Test + @DisplayName("새로운 URL을 짧은 URL로 변환할 수 있다.") void saveNewOriginalUrl() { String originalUrl = "https://naver.com"; - String transformedUrl = shortUrlService.saveOriginalUrl(originalUrl); + TransformedShortUrlDto transformedUrl = shortUrlService.saveOriginalUrl(originalUrl); - ShortUrl savedShortUrl = shortUrlRepository.findById(transformedUrl) + ShortUrl savedShortUrl = shortUrlRepository.findById(transformedUrl.shortUrl()) .orElseThrow(() -> new UrlException(UrlErrorCode.ORIGINAL_URL_NOT_FOUND)); - assertThat(savedShortUrl.getTransformedUrl()).isEqualTo(transformedUrl); + assertThat(savedShortUrl.getTransformedUrl()).isEqualTo(transformedUrl.shortUrl()); } @Test + @DisplayName("이미 존재하는 URL이면 짧은 URL을 생성 없이 즉시 반환한다.") void getAlreadyExistingOriginalUrl() { - String transformedUrl = shortUrlService.saveOriginalUrl(preSavedOriginalUrl); + TransformedShortUrlDto transformedShortUrlDto = shortUrlService.saveOriginalUrl(preSavedOriginalUrl); - assertThat(transformedUrl).isEqualTo(preSavedTransformedUrl); + assertThat(transformedShortUrlDto.shortUrl()).isEqualTo(preSavedTransformedShortUrlDto.shortUrl()); } @Test + @DisplayName("기존 URL을 가져올 수 있다.") void getOriginalUrl() { - String originalUrl = shortUrlService.getOriginalUrl(preSavedTransformedUrl); + String originalUrl = shortUrlService.getOriginalUrl(preSavedTransformedShortUrlDto.shortUrl()); assertThat(originalUrl).isEqualTo(preSavedOriginalUrl); } + + @Test + @DisplayName("짧은 URL을 이용해 기존 URL을 가져온다면 방문 횟수와 마지막 방문 일시가 수정되어야 한다.") + void updateLastVisitTimeAndVisitCountWhenFindUrl() { + shortUrlService.getOriginalUrl(preSavedTransformedShortUrlDto.shortUrl()); + + Optional shortUrl = shortUrlRepository.findById(preSavedTransformedShortUrlDto.shortUrl()); + + assertThat(shortUrl.isPresent()).isTrue(); + + TransformedShortUrlDto urlInfoAfterVisit = shortUrl.get().toTransformedShortUrlDto(); + + assertThat(urlInfoAfterVisit.lastVisitTime()).isNotEqualTo(preSavedTransformedShortUrlDto.lastVisitTime()); + assertThat(urlInfoAfterVisit.visitCount()).isEqualTo(preSavedTransformedShortUrlDto.visitCount() + 1); + + log.info("before lastVisitTime:{}, after lastVisitTime:{}", preSavedTransformedShortUrlDto.lastVisitTime(), urlInfoAfterVisit.lastVisitTime()); + } } From c0c134cc5659db03f51cdcf5e7b56800e02a32fe Mon Sep 17 00:00:00 2001 From: ZZAMBAs Date: Sun, 17 Dec 2023 19:04:02 +0900 Subject: [PATCH 23/42] =?UTF-8?q?Feat:=20=EB=B3=80=ED=99=98=20URL=EC=9D=84?= =?UTF-8?q?=20=EB=B3=B4=EC=97=AC=EC=A3=BC=EB=8A=94=20=ED=8E=98=EC=9D=B4?= =?UTF-8?q?=EC=A7=80=EB=A5=BC=20=EC=B6=94=EA=B0=80=ED=95=9C=EB=8B=A4.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/resources/templates/index.html | 2 +- .../resources/templates/short-url-info.html | 18 ++++++++++++++++++ 2 files changed, 19 insertions(+), 1 deletion(-) create mode 100644 src/main/resources/templates/short-url-info.html diff --git a/src/main/resources/templates/index.html b/src/main/resources/templates/index.html index a1aff832..d509083c 100644 --- a/src/main/resources/templates/index.html +++ b/src/main/resources/templates/index.html @@ -1,5 +1,5 @@ - + URL Shortener diff --git a/src/main/resources/templates/short-url-info.html b/src/main/resources/templates/short-url-info.html new file mode 100644 index 00000000..ad046dde --- /dev/null +++ b/src/main/resources/templates/short-url-info.html @@ -0,0 +1,18 @@ + + + + + url info + + +

변환된 URL 정보

+
+

+

+

+
+ + + + + From df622150633dad556fcbe0cbc7137cd9180985bf Mon Sep 17 00:00:00 2001 From: ZZAMBAs Date: Sun, 17 Dec 2023 19:05:02 +0900 Subject: [PATCH 24/42] =?UTF-8?q?Feat:=20ShortUrl=20=EA=B4=80=EB=A0=A8=20?= =?UTF-8?q?=EA=B3=B5=ED=86=B5=20=EC=83=81=EC=88=98=EB=A5=BC=20=EA=B4=80?= =?UTF-8?q?=EB=A6=AC=ED=95=98=EB=8A=94=20=ED=81=B4=EB=9E=98=EC=8A=A4?= =?UTF-8?q?=EB=A5=BC=20=EC=B6=94=EA=B0=80=ED=95=9C=EB=8B=A4.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/shorturl/common/ShortUrlConstant.java | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 src/main/java/org/prgms/springbooturlshortener/domain/shorturl/common/ShortUrlConstant.java diff --git a/src/main/java/org/prgms/springbooturlshortener/domain/shorturl/common/ShortUrlConstant.java b/src/main/java/org/prgms/springbooturlshortener/domain/shorturl/common/ShortUrlConstant.java new file mode 100644 index 00000000..016a73e2 --- /dev/null +++ b/src/main/java/org/prgms/springbooturlshortener/domain/shorturl/common/ShortUrlConstant.java @@ -0,0 +1,5 @@ +package org.prgms.springbooturlshortener.domain.shorturl.common; + +public class ShortUrlConstant { + public static final String[] PROTOCOLS = {"http://", "https://"}; +} From 9dc80e23f6e425b7e2bd22de4ac70ebcbba6dd42 Mon Sep 17 00:00:00 2001 From: ZZAMBAs Date: Sun, 17 Dec 2023 19:05:25 +0900 Subject: [PATCH 25/42] =?UTF-8?q?Feat:=20ShortUrl=20=EA=B4=80=EB=A0=A8=20?= =?UTF-8?q?=EA=B3=B5=ED=86=B5=20=EB=A9=94=EC=84=9C=EB=93=9C=EB=A5=BC=20?= =?UTF-8?q?=EA=B4=80=EB=A6=AC=ED=95=98=EB=8A=94=20=ED=81=B4=EB=9E=98?= =?UTF-8?q?=EC=8A=A4=EB=A5=BC=20=EC=B6=94=EA=B0=80=ED=95=9C=EB=8B=A4.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/shorturl/common/ShortUrlUtil.java | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 src/main/java/org/prgms/springbooturlshortener/domain/shorturl/common/ShortUrlUtil.java diff --git a/src/main/java/org/prgms/springbooturlshortener/domain/shorturl/common/ShortUrlUtil.java b/src/main/java/org/prgms/springbooturlshortener/domain/shorturl/common/ShortUrlUtil.java new file mode 100644 index 00000000..5541a673 --- /dev/null +++ b/src/main/java/org/prgms/springbooturlshortener/domain/shorturl/common/ShortUrlUtil.java @@ -0,0 +1,13 @@ +package org.prgms.springbooturlshortener.domain.shorturl.common; + +public class ShortUrlUtil { + public static String deleteProtocol(String originalUrl) { + for (String protocol: ShortUrlConstant.PROTOCOLS) { + if (originalUrl.startsWith(protocol)) { + originalUrl = originalUrl.replace(protocol, ""); + } + } + + return originalUrl; + } +} From da170d3ec869d01ca442cd92bfe7e2aede873147 Mon Sep 17 00:00:00 2001 From: ZZAMBAs Date: Sun, 17 Dec 2023 19:06:38 +0900 Subject: [PATCH 26/42] =?UTF-8?q?Feat:=20HTTP=20=ED=94=84=EB=A1=9C?= =?UTF-8?q?=ED=86=A0=EC=BD=9C=EC=9D=84=20=EC=A0=9C=EA=B1=B0=ED=95=98?= =?UTF-8?q?=EC=97=AC=20DB=20=EC=A0=80=EC=9E=A5=20=EA=B3=B5=EA=B0=84?= =?UTF-8?q?=EC=9D=84=20=EC=A0=88=EC=95=BD=ED=95=9C=EB=8B=A4.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/shorturl/ShortUrl.java | 3 ++- .../service/dto/TransformRequestUrlDto.java | 5 +++++ .../service/dto/TransformedShortUrlDto.java | 13 ------------- 3 files changed, 7 insertions(+), 14 deletions(-) diff --git a/src/main/java/org/prgms/springbooturlshortener/domain/shorturl/ShortUrl.java b/src/main/java/org/prgms/springbooturlshortener/domain/shorturl/ShortUrl.java index 91e48d9b..b00fbadc 100644 --- a/src/main/java/org/prgms/springbooturlshortener/domain/shorturl/ShortUrl.java +++ b/src/main/java/org/prgms/springbooturlshortener/domain/shorturl/ShortUrl.java @@ -8,6 +8,7 @@ import lombok.NoArgsConstructor; import org.hibernate.annotations.DynamicInsert; import org.hibernate.annotations.DynamicUpdate; +import org.prgms.springbooturlshortener.domain.shorturl.common.ShortUrlUtil; import org.prgms.springbooturlshortener.domain.shorturl.service.dto.TransformedShortUrlDto; import java.time.LocalDateTime; @@ -35,7 +36,7 @@ public class ShortUrl { @Builder public ShortUrl(String transformedUrl, String originalUrl) { this.transformedUrl = transformedUrl; - this.originalUrl = originalUrl; + this.originalUrl = ShortUrlUtil.deleteProtocol(originalUrl); this.visitCount = 0L; this.lastVisitTime = null; } diff --git a/src/main/java/org/prgms/springbooturlshortener/domain/shorturl/service/dto/TransformRequestUrlDto.java b/src/main/java/org/prgms/springbooturlshortener/domain/shorturl/service/dto/TransformRequestUrlDto.java index 4e9ee36b..288db780 100644 --- a/src/main/java/org/prgms/springbooturlshortener/domain/shorturl/service/dto/TransformRequestUrlDto.java +++ b/src/main/java/org/prgms/springbooturlshortener/domain/shorturl/service/dto/TransformRequestUrlDto.java @@ -1,4 +1,9 @@ package org.prgms.springbooturlshortener.domain.shorturl.service.dto; +import org.prgms.springbooturlshortener.domain.shorturl.common.ShortUrlUtil; + public record TransformRequestUrlDto (String originalUrl) { + public TransformRequestUrlDto(String originalUrl) { + this.originalUrl = ShortUrlUtil.deleteProtocol(originalUrl); + } } diff --git a/src/main/java/org/prgms/springbooturlshortener/domain/shorturl/service/dto/TransformedShortUrlDto.java b/src/main/java/org/prgms/springbooturlshortener/domain/shorturl/service/dto/TransformedShortUrlDto.java index 0e28d180..34ef3c99 100644 --- a/src/main/java/org/prgms/springbooturlshortener/domain/shorturl/service/dto/TransformedShortUrlDto.java +++ b/src/main/java/org/prgms/springbooturlshortener/domain/shorturl/service/dto/TransformedShortUrlDto.java @@ -1,21 +1,8 @@ package org.prgms.springbooturlshortener.domain.shorturl.service.dto; import java.time.LocalDateTime; -import java.util.Objects; public record TransformedShortUrlDto (String shortUrl, Long visitCount, LocalDateTime lastVisitTime) { - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - TransformedShortUrlDto that = (TransformedShortUrlDto) o; - return Objects.equals(shortUrl, that.shortUrl) && Objects.equals(visitCount, that.visitCount) && Objects.equals(lastVisitTime, that.lastVisitTime); - } - - @Override - public int hashCode() { - return Objects.hash(shortUrl, visitCount, lastVisitTime); - } } From 1093c0cf18d999b87ea8a19fb82357f71e2ab004 Mon Sep 17 00:00:00 2001 From: ZZAMBAs Date: Sun, 17 Dec 2023 19:07:00 +0900 Subject: [PATCH 27/42] =?UTF-8?q?Feat:=20favicon.ico=EB=A5=BC=20=EB=B6=88?= =?UTF-8?q?=EB=9F=AC=EC=98=A4=EC=A7=80=20=EC=95=8A=EB=8F=84=EB=A1=9D=20?= =?UTF-8?q?=ED=95=98=EB=8A=94=20MVC=20=EC=84=A4=EC=A0=95=EC=9D=84=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80=ED=95=9C=EB=8B=A4.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../springbooturlshortener/config/WebMvcConfig.java | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 src/main/java/org/prgms/springbooturlshortener/config/WebMvcConfig.java diff --git a/src/main/java/org/prgms/springbooturlshortener/config/WebMvcConfig.java b/src/main/java/org/prgms/springbooturlshortener/config/WebMvcConfig.java new file mode 100644 index 00000000..949ce8f4 --- /dev/null +++ b/src/main/java/org/prgms/springbooturlshortener/config/WebMvcConfig.java @@ -0,0 +1,13 @@ +package org.prgms.springbooturlshortener.config; + +import org.springframework.context.annotation.Configuration; +import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; + +@Configuration +public class WebMvcConfig implements WebMvcConfigurer { + @Override + public void addResourceHandlers(ResourceHandlerRegistry registry) { + registry.addResourceHandler("favicon.ico").resourceChain(false); + } +} From e51224f34cea68bc876c7ced611d44c00511fd51 Mon Sep 17 00:00:00 2001 From: ZZAMBAs Date: Sun, 17 Dec 2023 19:07:18 +0900 Subject: [PATCH 28/42] =?UTF-8?q?Feat:=20ShortUrl=20=EC=B2=98=EB=A6=AC=20?= =?UTF-8?q?=EC=BB=A8=ED=8A=B8=EB=A1=A4=EB=9F=AC=EB=A5=BC=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80=ED=95=9C=EB=8B=A4.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/ShortUrlController.java | 56 +++++++++++++++++++ 1 file changed, 56 insertions(+) create mode 100644 src/main/java/org/prgms/springbooturlshortener/domain/shorturl/controller/ShortUrlController.java diff --git a/src/main/java/org/prgms/springbooturlshortener/domain/shorturl/controller/ShortUrlController.java b/src/main/java/org/prgms/springbooturlshortener/domain/shorturl/controller/ShortUrlController.java new file mode 100644 index 00000000..92e6fa60 --- /dev/null +++ b/src/main/java/org/prgms/springbooturlshortener/domain/shorturl/controller/ShortUrlController.java @@ -0,0 +1,56 @@ +package org.prgms.springbooturlshortener.domain.shorturl.controller; + +import jakarta.servlet.http.HttpServletRequest; +import lombok.extern.slf4j.Slf4j; +import org.prgms.springbooturlshortener.domain.shorturl.service.ShortUrlService; +import org.prgms.springbooturlshortener.domain.shorturl.service.dto.TransformRequestUrlDto; +import org.prgms.springbooturlshortener.domain.shorturl.service.dto.TransformedShortUrlDto; +import org.springframework.stereotype.Controller; +import org.springframework.ui.Model; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.servlet.mvc.support.RedirectAttributes; + +@Controller +@Slf4j +public class ShortUrlController { + private final ShortUrlService shortUrlService; + + public ShortUrlController(ShortUrlService shortUrlService) { + this.shortUrlService = shortUrlService; + } + + @GetMapping("/") + public String showMain() { + return "index"; + } + + @GetMapping("/{transformedUrl}") + public String redirectToOriginalUrl(@PathVariable String transformedUrl) { + String originalUrl = shortUrlService.getOriginalUrl(transformedUrl); + + return "redirect:https://" + originalUrl; + } + + @PostMapping("/shorten") + public String transformOriginalUrl(TransformRequestUrlDto transformRequestUrlDto, RedirectAttributes redirectAttributes) { + log.info(transformRequestUrlDto.originalUrl()); + + TransformedShortUrlDto transformedShortUrlDto = shortUrlService.saveOriginalUrl(transformRequestUrlDto.originalUrl()); + + redirectAttributes.addFlashAttribute("transformedShortUrlDto", transformedShortUrlDto); + + return "redirect:/shorten"; + } + + @GetMapping("/shorten") + public String showTransformedUrl(TransformedShortUrlDto transformedShortUrlDto, Model model, HttpServletRequest request) { + log.info(transformedShortUrlDto.toString()); + + model.addAttribute("transformedShortUrlDto", transformedShortUrlDto); + model.addAttribute("domain", request.getServerName() + ":" + request.getServerPort()); + + return "short-url-info"; + } +} From 7077d588a64d609ea723591c451916088bed00fe Mon Sep 17 00:00:00 2001 From: ZZAMBAs Date: Sun, 17 Dec 2023 19:28:38 +0900 Subject: [PATCH 29/42] =?UTF-8?q?Feat:=20ShortUrl=20=EB=B3=B5=EC=82=AC=20?= =?UTF-8?q?=EA=B8=B0=EB=8A=A5=EC=9D=84=20=EC=B6=94=EA=B0=80=ED=95=9C?= =?UTF-8?q?=EB=8B=A4.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../resources/templates/short-url-info.html | 20 ++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/src/main/resources/templates/short-url-info.html b/src/main/resources/templates/short-url-info.html index ad046dde..a72255c6 100644 --- a/src/main/resources/templates/short-url-info.html +++ b/src/main/resources/templates/short-url-info.html @@ -7,7 +7,9 @@

변환된 URL 정보

-

+
+ 변환된 URL:

+

@@ -15,4 +17,20 @@

{ + const copyButton = document.querySelector("[name='copyButton']"); + copyButton.innerText = "복사됨!"; + alert('URL 복사됨!'); + }) + .catch(err => { + console.error('복사 중 에러가 발생', err); + }); + + } + From 38537962e588abac44a6e553794ad8ca1bcbdfdb Mon Sep 17 00:00:00 2001 From: ZZAMBAs Date: Sun, 17 Dec 2023 20:44:20 +0900 Subject: [PATCH 30/42] =?UTF-8?q?Feat:=20=EC=9E=98=EB=AA=BB=EB=90=9C=20?= =?UTF-8?q?=EC=9A=94=EC=B2=AD=20=ED=98=B9=EC=9D=80=20=EC=84=9C=EB=B2=84=20?= =?UTF-8?q?=EC=98=88=EC=99=B8=EC=97=90=20=EB=8C=80=ED=95=9C=20=EC=BB=A8?= =?UTF-8?q?=ED=8A=B8=EB=A1=A4=EB=9F=AC=20=EC=B2=98=EB=A6=AC=EB=A5=BC=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80=ED=95=9C=EB=8B=A4.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/ShortUrlController.java | 31 +++++++++++++++++-- .../shorturl/exception/UrlErrorCode.java | 5 ++- .../shorturl/exception/UrlException.java | 4 +++ src/main/resources/templates/error/400.html | 11 +++++++ src/main/resources/templates/error/500.html | 11 +++++++ .../resources/templates/short-url-info.html | 3 ++ 6 files changed, 61 insertions(+), 4 deletions(-) create mode 100644 src/main/resources/templates/error/400.html create mode 100644 src/main/resources/templates/error/500.html diff --git a/src/main/java/org/prgms/springbooturlshortener/domain/shorturl/controller/ShortUrlController.java b/src/main/java/org/prgms/springbooturlshortener/domain/shorturl/controller/ShortUrlController.java index 92e6fa60..0262505e 100644 --- a/src/main/java/org/prgms/springbooturlshortener/domain/shorturl/controller/ShortUrlController.java +++ b/src/main/java/org/prgms/springbooturlshortener/domain/shorturl/controller/ShortUrlController.java @@ -2,11 +2,14 @@ import jakarta.servlet.http.HttpServletRequest; import lombok.extern.slf4j.Slf4j; +import org.prgms.springbooturlshortener.domain.shorturl.exception.UrlErrorCode; +import org.prgms.springbooturlshortener.domain.shorturl.exception.UrlException; import org.prgms.springbooturlshortener.domain.shorturl.service.ShortUrlService; import org.prgms.springbooturlshortener.domain.shorturl.service.dto.TransformRequestUrlDto; import org.prgms.springbooturlshortener.domain.shorturl.service.dto.TransformedShortUrlDto; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; +import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PostMapping; @@ -15,6 +18,8 @@ @Controller @Slf4j public class ShortUrlController { + private static final int HTTP_500_ERROR_BOUND = 400; + private final ShortUrlService shortUrlService; public ShortUrlController(ShortUrlService shortUrlService) { @@ -35,8 +40,6 @@ public String redirectToOriginalUrl(@PathVariable String transformedUrl) { @PostMapping("/shorten") public String transformOriginalUrl(TransformRequestUrlDto transformRequestUrlDto, RedirectAttributes redirectAttributes) { - log.info(transformRequestUrlDto.originalUrl()); - TransformedShortUrlDto transformedShortUrlDto = shortUrlService.saveOriginalUrl(transformRequestUrlDto.originalUrl()); redirectAttributes.addFlashAttribute("transformedShortUrlDto", transformedShortUrlDto); @@ -46,11 +49,33 @@ public String transformOriginalUrl(TransformRequestUrlDto transformRequestUrlDto @GetMapping("/shorten") public String showTransformedUrl(TransformedShortUrlDto transformedShortUrlDto, Model model, HttpServletRequest request) { - log.info(transformedShortUrlDto.toString()); + if (transformedShortUrlDto.shortUrl() == null) { + throw new UrlException(UrlErrorCode.ORIGINAL_URL_NOT_FOUND); + } model.addAttribute("transformedShortUrlDto", transformedShortUrlDto); model.addAttribute("domain", request.getServerName() + ":" + request.getServerPort()); return "short-url-info"; } + + @ExceptionHandler(UrlException.class) + public String showUrlErrorPage(UrlException ex) { + if (ex.getUrlErrorCode() > HTTP_500_ERROR_BOUND) { + log.warn("서버에서의 에러: {}", ex.getMessage()); + + return "error/500"; + } + + log.info("클라이언트에서 잘못된 입력. {}", ex.getMessage()); + + return "error/400"; + } + + @ExceptionHandler(Exception.class) + public String showDefaultError(Exception ex) { + log.error("예상하지 못한 에러 발생: {}", ex.getMessage()); + + return "error/400"; + } } diff --git a/src/main/java/org/prgms/springbooturlshortener/domain/shorturl/exception/UrlErrorCode.java b/src/main/java/org/prgms/springbooturlshortener/domain/shorturl/exception/UrlErrorCode.java index 96721f44..a9f61df7 100644 --- a/src/main/java/org/prgms/springbooturlshortener/domain/shorturl/exception/UrlErrorCode.java +++ b/src/main/java/org/prgms/springbooturlshortener/domain/shorturl/exception/UrlErrorCode.java @@ -1,7 +1,10 @@ package org.prgms.springbooturlshortener.domain.shorturl.exception; +import lombok.Getter; + +@Getter public enum UrlErrorCode { - ORIGINAL_URL_NOT_FOUND(400); + ORIGINAL_URL_NOT_FOUND(404); private final int errorCode; diff --git a/src/main/java/org/prgms/springbooturlshortener/domain/shorturl/exception/UrlException.java b/src/main/java/org/prgms/springbooturlshortener/domain/shorturl/exception/UrlException.java index f02436f1..1efbb38b 100644 --- a/src/main/java/org/prgms/springbooturlshortener/domain/shorturl/exception/UrlException.java +++ b/src/main/java/org/prgms/springbooturlshortener/domain/shorturl/exception/UrlException.java @@ -6,4 +6,8 @@ public class UrlException extends RuntimeException { public UrlException(UrlErrorCode urlErrorCode) { this.urlErrorCode = urlErrorCode; } + + public int getUrlErrorCode() { + return urlErrorCode.getErrorCode(); + } } diff --git a/src/main/resources/templates/error/400.html b/src/main/resources/templates/error/400.html new file mode 100644 index 00000000..18c655f2 --- /dev/null +++ b/src/main/resources/templates/error/400.html @@ -0,0 +1,11 @@ + + + + + Error Page 400 + + +클라 에러입니당. +홈으로 가기 + + diff --git a/src/main/resources/templates/error/500.html b/src/main/resources/templates/error/500.html new file mode 100644 index 00000000..9473bbce --- /dev/null +++ b/src/main/resources/templates/error/500.html @@ -0,0 +1,11 @@ + + + + + Error Page 500 + + +서버 에러입니당~ +홈으로 가기 + + diff --git a/src/main/resources/templates/short-url-info.html b/src/main/resources/templates/short-url-info.html index a72255c6..709679ec 100644 --- a/src/main/resources/templates/short-url-info.html +++ b/src/main/resources/templates/short-url-info.html @@ -4,6 +4,9 @@ url info +
+ +

변환된 URL 정보

From 237dc396761747d50d5098a3a918250d0b22406f Mon Sep 17 00:00:00 2001 From: ZZAMBAs Date: Sun, 17 Dec 2023 21:14:22 +0900 Subject: [PATCH 31/42] =?UTF-8?q?Feat:=20=EB=B3=80=ED=99=98=20URL=20?= =?UTF-8?q?=EC=A0=95=EB=B3=B4=EC=97=90=20=EC=9B=90=EB=B3=B8=20URL=EB=8F=84?= =?UTF-8?q?=20=EB=82=98=ED=83=80=EB=82=98=EB=8F=84=EB=A1=9D=20=ED=95=9C?= =?UTF-8?q?=EB=8B=A4.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../springbooturlshortener/domain/shorturl/ShortUrl.java | 2 +- .../domain/shorturl/service/dto/TransformedShortUrlDto.java | 1 + src/main/resources/templates/short-url-info.html | 5 +++++ 3 files changed, 7 insertions(+), 1 deletion(-) diff --git a/src/main/java/org/prgms/springbooturlshortener/domain/shorturl/ShortUrl.java b/src/main/java/org/prgms/springbooturlshortener/domain/shorturl/ShortUrl.java index b00fbadc..4ce0d579 100644 --- a/src/main/java/org/prgms/springbooturlshortener/domain/shorturl/ShortUrl.java +++ b/src/main/java/org/prgms/springbooturlshortener/domain/shorturl/ShortUrl.java @@ -46,6 +46,6 @@ public void increaseVisit() { } public TransformedShortUrlDto toTransformedShortUrlDto() { - return new TransformedShortUrlDto(this.transformedUrl, this.visitCount, this.lastVisitTime); + return new TransformedShortUrlDto(this.transformedUrl, this.originalUrl, this.visitCount, this.lastVisitTime); } } diff --git a/src/main/java/org/prgms/springbooturlshortener/domain/shorturl/service/dto/TransformedShortUrlDto.java b/src/main/java/org/prgms/springbooturlshortener/domain/shorturl/service/dto/TransformedShortUrlDto.java index 34ef3c99..9a28018b 100644 --- a/src/main/java/org/prgms/springbooturlshortener/domain/shorturl/service/dto/TransformedShortUrlDto.java +++ b/src/main/java/org/prgms/springbooturlshortener/domain/shorturl/service/dto/TransformedShortUrlDto.java @@ -3,6 +3,7 @@ import java.time.LocalDateTime; public record TransformedShortUrlDto (String shortUrl, + String originalUrl, Long visitCount, LocalDateTime lastVisitTime) { } diff --git a/src/main/resources/templates/short-url-info.html b/src/main/resources/templates/short-url-info.html index 709679ec..7dde72fb 100644 --- a/src/main/resources/templates/short-url-info.html +++ b/src/main/resources/templates/short-url-info.html @@ -12,7 +12,12 @@

변환된 URL 정보

변환된 URL:

+
+
+ 원본 URL:

+
+

From 2f4e65b38f6f104646078022e9450a72e835d0b1 Mon Sep 17 00:00:00 2001 From: ZZAMBAs Date: Tue, 26 Dec 2023 13:45:30 +0900 Subject: [PATCH 32/42] =?UTF-8?q?Feat:=20originalUrl=EC=9D=84=20=EA=B3=A0?= =?UTF-8?q?=EC=9C=A0=ED=95=98=EB=8F=84=EB=A1=9D=20=EC=BB=AC=EB=9F=BC=20?= =?UTF-8?q?=EC=86=8D=EC=84=B1=EC=9D=84=20=EC=B6=94=EA=B0=80=ED=95=9C?= =?UTF-8?q?=EB=8B=A4.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../prgms/springbooturlshortener/domain/shorturl/ShortUrl.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/prgms/springbooturlshortener/domain/shorturl/ShortUrl.java b/src/main/java/org/prgms/springbooturlshortener/domain/shorturl/ShortUrl.java index 4ce0d579..f4475cd0 100644 --- a/src/main/java/org/prgms/springbooturlshortener/domain/shorturl/ShortUrl.java +++ b/src/main/java/org/prgms/springbooturlshortener/domain/shorturl/ShortUrl.java @@ -24,7 +24,7 @@ public class ShortUrl { private String transformedUrl; @Getter - @Column(name = "original_url", nullable = false) + @Column(name = "original_url", unique = true, nullable = false) private String originalUrl; @Column(name = "visit_count", nullable = false) From db1d23278f6f4b178ac31569c174ff0dbd690410 Mon Sep 17 00:00:00 2001 From: ZZAMBAs Date: Tue, 2 Jan 2024 00:32:46 +0900 Subject: [PATCH 33/42] =?UTF-8?q?Refactor:=20stream=EC=9D=84=20=EC=9D=B4?= =?UTF-8?q?=EC=9A=A9=ED=95=98=EC=97=AC=20=EA=B0=84=EB=9E=B5=ED=99=94?= =?UTF-8?q?=ED=95=9C=EB=8B=A4.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/shorturl/common/ShortUrlUtil.java | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/src/main/java/org/prgms/springbooturlshortener/domain/shorturl/common/ShortUrlUtil.java b/src/main/java/org/prgms/springbooturlshortener/domain/shorturl/common/ShortUrlUtil.java index 5541a673..fe21b6c7 100644 --- a/src/main/java/org/prgms/springbooturlshortener/domain/shorturl/common/ShortUrlUtil.java +++ b/src/main/java/org/prgms/springbooturlshortener/domain/shorturl/common/ShortUrlUtil.java @@ -1,13 +1,9 @@ package org.prgms.springbooturlshortener.domain.shorturl.common; +import java.util.Arrays; + public class ShortUrlUtil { public static String deleteProtocol(String originalUrl) { - for (String protocol: ShortUrlConstant.PROTOCOLS) { - if (originalUrl.startsWith(protocol)) { - originalUrl = originalUrl.replace(protocol, ""); - } - } - - return originalUrl; + return Arrays.stream(ShortUrlConstant.PROTOCOLS).reduce(originalUrl, (url, protocol) -> url.replace(protocol, "")); } } From d30ee0ba6cdbeb50c38916c4c2e4aa8b7719fd4f Mon Sep 17 00:00:00 2001 From: ZZAMBAs Date: Tue, 2 Jan 2024 00:33:10 +0900 Subject: [PATCH 34/42] =?UTF-8?q?feat:=20=EC=98=88=EC=99=B8=20=EC=B2=98?= =?UTF-8?q?=EB=A6=AC=EB=A5=BC=20=EC=9C=84=ED=95=9C=20Controller=EB=A5=BC?= =?UTF-8?q?=20=EB=94=B0=EB=A1=9C=20=EC=83=9D=EC=84=B1=ED=95=9C=EB=8B=A4.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/ExceptionController.java | 31 +++++++++++++++++++ .../controller/ShortUrlController.java | 22 ------------- 2 files changed, 31 insertions(+), 22 deletions(-) create mode 100644 src/main/java/org/prgms/springbooturlshortener/domain/shorturl/controller/ExceptionController.java diff --git a/src/main/java/org/prgms/springbooturlshortener/domain/shorturl/controller/ExceptionController.java b/src/main/java/org/prgms/springbooturlshortener/domain/shorturl/controller/ExceptionController.java new file mode 100644 index 00000000..b8db1af0 --- /dev/null +++ b/src/main/java/org/prgms/springbooturlshortener/domain/shorturl/controller/ExceptionController.java @@ -0,0 +1,31 @@ +package org.prgms.springbooturlshortener.domain.shorturl.controller; + +import lombok.extern.slf4j.Slf4j; +import org.prgms.springbooturlshortener.domain.shorturl.exception.UrlException; +import org.springframework.web.bind.annotation.ControllerAdvice; +import org.springframework.web.bind.annotation.ExceptionHandler; + +@ControllerAdvice +@Slf4j +public class ExceptionController { + private static final int HTTP_500_ERROR_BOUND = 400; + @ExceptionHandler(UrlException.class) + public String showUrlErrorPage(UrlException ex) { + if (ex.getUrlErrorCode() > HTTP_500_ERROR_BOUND) { + log.warn("서버에서의 에러: {}", ex.getMessage()); + + return "error/500"; + } + + log.info("클라이언트에서 잘못된 입력. {}", ex.getMessage()); + + return "error/400"; + } + + @ExceptionHandler(Exception.class) + public String showDefaultError(Exception ex) { + log.error("예상하지 못한 에러 발생: {}", ex.getMessage()); + + return "error/500"; + } +} diff --git a/src/main/java/org/prgms/springbooturlshortener/domain/shorturl/controller/ShortUrlController.java b/src/main/java/org/prgms/springbooturlshortener/domain/shorturl/controller/ShortUrlController.java index 0262505e..b36be01c 100644 --- a/src/main/java/org/prgms/springbooturlshortener/domain/shorturl/controller/ShortUrlController.java +++ b/src/main/java/org/prgms/springbooturlshortener/domain/shorturl/controller/ShortUrlController.java @@ -9,7 +9,6 @@ import org.prgms.springbooturlshortener.domain.shorturl.service.dto.TransformedShortUrlDto; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; -import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PostMapping; @@ -18,7 +17,6 @@ @Controller @Slf4j public class ShortUrlController { - private static final int HTTP_500_ERROR_BOUND = 400; private final ShortUrlService shortUrlService; @@ -58,24 +56,4 @@ public String showTransformedUrl(TransformedShortUrlDto transformedShortUrlDto, return "short-url-info"; } - - @ExceptionHandler(UrlException.class) - public String showUrlErrorPage(UrlException ex) { - if (ex.getUrlErrorCode() > HTTP_500_ERROR_BOUND) { - log.warn("서버에서의 에러: {}", ex.getMessage()); - - return "error/500"; - } - - log.info("클라이언트에서 잘못된 입력. {}", ex.getMessage()); - - return "error/400"; - } - - @ExceptionHandler(Exception.class) - public String showDefaultError(Exception ex) { - log.error("예상하지 못한 에러 발생: {}", ex.getMessage()); - - return "error/400"; - } } From ff371c71b7a4f2e553942f13277ea38b79b9d84f Mon Sep 17 00:00:00 2001 From: ZZAMBAs Date: Tue, 2 Jan 2024 00:38:12 +0900 Subject: [PATCH 35/42] =?UTF-8?q?Refactor:=20=EC=97=90=EB=9F=AC=20?= =?UTF-8?q?=EC=BD=94=EB=93=9C=EB=A5=BC=20HTTP=EC=99=80=20=EA=B0=95?= =?UTF-8?q?=EA=B2=B0=ED=95=A9=EB=90=98=EC=A7=80=20=EC=95=8A=EB=8F=84?= =?UTF-8?q?=EB=A1=9D=20=EC=9E=90=EC=B2=B4=20=EC=BD=94=EB=93=9C=EB=A1=9C=20?= =?UTF-8?q?=EC=88=98=EC=A0=95=ED=95=9C=EB=8B=A4.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/shorturl/exception/UrlErrorCode.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/prgms/springbooturlshortener/domain/shorturl/exception/UrlErrorCode.java b/src/main/java/org/prgms/springbooturlshortener/domain/shorturl/exception/UrlErrorCode.java index a9f61df7..b55ae01e 100644 --- a/src/main/java/org/prgms/springbooturlshortener/domain/shorturl/exception/UrlErrorCode.java +++ b/src/main/java/org/prgms/springbooturlshortener/domain/shorturl/exception/UrlErrorCode.java @@ -4,7 +4,7 @@ @Getter public enum UrlErrorCode { - ORIGINAL_URL_NOT_FOUND(404); + ORIGINAL_URL_NOT_FOUND(1100); private final int errorCode; From 9ea0a29d255172454bc008224eac3b3f3c56bf75 Mon Sep 17 00:00:00 2001 From: ZZAMBAs Date: Tue, 2 Jan 2024 00:52:14 +0900 Subject: [PATCH 36/42] =?UTF-8?q?Refactor:=20BASE62=EC=9D=98=2062=EB=A5=BC?= =?UTF-8?q?=20=EC=83=81=EC=88=98=EB=A1=9C=20=EA=B4=80=EB=A6=AC=ED=95=9C?= =?UTF-8?q?=EB=8B=A4.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../shorturl/service/transformer/Base62UrlTransformer.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/prgms/springbooturlshortener/domain/shorturl/service/transformer/Base62UrlTransformer.java b/src/main/java/org/prgms/springbooturlshortener/domain/shorturl/service/transformer/Base62UrlTransformer.java index 27b00e8e..835889fa 100644 --- a/src/main/java/org/prgms/springbooturlshortener/domain/shorturl/service/transformer/Base62UrlTransformer.java +++ b/src/main/java/org/prgms/springbooturlshortener/domain/shorturl/service/transformer/Base62UrlTransformer.java @@ -8,15 +8,16 @@ public class Base62UrlTransformer implements UrlTransformer{ private static final String BASE62_TOKENS = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; private static final short numOfUrl = 6; + private static final int DIVIDE_NUM = 62; public String generateUrl(int number) { StringBuilder sb = new StringBuilder(); for (short i = 0; i < numOfUrl; i++) { - char token = BASE62_TOKENS.charAt(number % 62); + char token = BASE62_TOKENS.charAt(number % DIVIDE_NUM); sb.append(token); - number /= 62; + number /= DIVIDE_NUM; } return sb.toString(); From 3a248f5800bd05fba2347f18768e3e874d216dcd Mon Sep 17 00:00:00 2001 From: ZZAMBAs Date: Tue, 2 Jan 2024 00:53:11 +0900 Subject: [PATCH 37/42] =?UTF-8?q?Chore:=20=EC=83=81=EC=88=98=20=EB=84=A4?= =?UTF-8?q?=EC=9D=B4=EB=B0=8D=EC=9D=84=20=ED=86=B5=EC=9D=BC=ED=95=9C?= =?UTF-8?q?=EB=8B=A4.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../shorturl/service/transformer/Base62UrlTransformer.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/prgms/springbooturlshortener/domain/shorturl/service/transformer/Base62UrlTransformer.java b/src/main/java/org/prgms/springbooturlshortener/domain/shorturl/service/transformer/Base62UrlTransformer.java index 835889fa..417f44bb 100644 --- a/src/main/java/org/prgms/springbooturlshortener/domain/shorturl/service/transformer/Base62UrlTransformer.java +++ b/src/main/java/org/prgms/springbooturlshortener/domain/shorturl/service/transformer/Base62UrlTransformer.java @@ -7,13 +7,13 @@ @Qualifier("BASE62") public class Base62UrlTransformer implements UrlTransformer{ private static final String BASE62_TOKENS = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; - private static final short numOfUrl = 6; + private static final short NUM_OF_URL = 6; private static final int DIVIDE_NUM = 62; public String generateUrl(int number) { StringBuilder sb = new StringBuilder(); - for (short i = 0; i < numOfUrl; i++) { + for (short i = 0; i < NUM_OF_URL; i++) { char token = BASE62_TOKENS.charAt(number % DIVIDE_NUM); sb.append(token); From 507ebbabb805f47717be292d60b7a7a01523ee78 Mon Sep 17 00:00:00 2001 From: ZZAMBAs Date: Tue, 2 Jan 2024 01:11:02 +0900 Subject: [PATCH 38/42] =?UTF-8?q?Rename:=20=EC=9D=B4=EB=AF=B8=20=ED=81=B4?= =?UTF-8?q?=EB=9E=98=EC=8A=A4=20=EB=AA=85=EC=97=90=20URL=EC=9E=84=EC=9D=B4?= =?UTF-8?q?=20=EB=AA=85=EC=8B=9C=EB=90=98=EC=96=B4=20=EC=9E=88=EA=B8=B0?= =?UTF-8?q?=EC=97=90=20=EB=8D=94=20=EC=A7=81=EA=B4=80=EC=A0=81=EC=9D=B8=20?= =?UTF-8?q?=EB=A9=94=EC=84=9C=EB=93=9C=20=EB=AA=85=EC=9C=BC=EB=A1=9C=20?= =?UTF-8?q?=EB=B3=80=EA=B2=BD=ED=95=9C=EB=8B=A4.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../shorturl/service/transformer/Base62UrlTransformer.java | 2 +- .../domain/shorturl/service/transformer/UrlTransformer.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/prgms/springbooturlshortener/domain/shorturl/service/transformer/Base62UrlTransformer.java b/src/main/java/org/prgms/springbooturlshortener/domain/shorturl/service/transformer/Base62UrlTransformer.java index 417f44bb..2a049984 100644 --- a/src/main/java/org/prgms/springbooturlshortener/domain/shorturl/service/transformer/Base62UrlTransformer.java +++ b/src/main/java/org/prgms/springbooturlshortener/domain/shorturl/service/transformer/Base62UrlTransformer.java @@ -10,7 +10,7 @@ public class Base62UrlTransformer implements UrlTransformer{ private static final short NUM_OF_URL = 6; private static final int DIVIDE_NUM = 62; - public String generateUrl(int number) { + public String transform(int number) { StringBuilder sb = new StringBuilder(); for (short i = 0; i < NUM_OF_URL; i++) { diff --git a/src/main/java/org/prgms/springbooturlshortener/domain/shorturl/service/transformer/UrlTransformer.java b/src/main/java/org/prgms/springbooturlshortener/domain/shorturl/service/transformer/UrlTransformer.java index e308add1..3abfe007 100644 --- a/src/main/java/org/prgms/springbooturlshortener/domain/shorturl/service/transformer/UrlTransformer.java +++ b/src/main/java/org/prgms/springbooturlshortener/domain/shorturl/service/transformer/UrlTransformer.java @@ -1,5 +1,5 @@ package org.prgms.springbooturlshortener.domain.shorturl.service.transformer; public interface UrlTransformer { - String generateUrl(int number); + String transform(); } From 8081b488a3dc33080cd93d6e19dada4b9552bdec Mon Sep 17 00:00:00 2001 From: ZZAMBAs Date: Tue, 2 Jan 2024 01:21:09 +0900 Subject: [PATCH 39/42] =?UTF-8?q?Chore:=20=EC=9D=BC=EB=B6=80=20=EC=BD=94?= =?UTF-8?q?=EB=93=9C=EB=A5=BC=20=EB=8B=A4=EB=93=AC=EB=8A=94=EB=8B=A4.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/shorturl/service/ShortUrlService.java | 9 ++------- .../SpringBootUrlShortenerApplicationTest.java | 1 - 2 files changed, 2 insertions(+), 8 deletions(-) diff --git a/src/main/java/org/prgms/springbooturlshortener/domain/shorturl/service/ShortUrlService.java b/src/main/java/org/prgms/springbooturlshortener/domain/shorturl/service/ShortUrlService.java index 3531f2e1..47d05491 100644 --- a/src/main/java/org/prgms/springbooturlshortener/domain/shorturl/service/ShortUrlService.java +++ b/src/main/java/org/prgms/springbooturlshortener/domain/shorturl/service/ShortUrlService.java @@ -30,9 +30,7 @@ public TransformedShortUrlDto saveOriginalUrl(String originalUrl) { return shortUrl.toTransformedShortUrlDto(); } - String generatedUrl; - - generatedUrl = getRandomUrl(); + String generatedUrl = getRandomUrl(); ShortUrl savedShortUrl = getSavedShortUrl(originalUrl, generatedUrl); @@ -57,13 +55,10 @@ private ShortUrl getSavedShortUrl(String originalUrl, String generatedUrl) { } private String getRandomUrl() { - Random random = new Random(); String generatedUrl; - int randomInt; do { - randomInt = random.nextInt(0, Integer.MAX_VALUE); - generatedUrl = urlTransformer.generateUrl(randomInt); + generatedUrl = urlTransformer.transform(); } while (urlRepository.findById(generatedUrl).isPresent()); return generatedUrl; diff --git a/src/test/java/org/prgms/springbooturlshortener/SpringBootUrlShortenerApplicationTest.java b/src/test/java/org/prgms/springbooturlshortener/SpringBootUrlShortenerApplicationTest.java index 4bf5d478..e37a0d7e 100644 --- a/src/test/java/org/prgms/springbooturlshortener/SpringBootUrlShortenerApplicationTest.java +++ b/src/test/java/org/prgms/springbooturlshortener/SpringBootUrlShortenerApplicationTest.java @@ -7,6 +7,5 @@ class SpringBootUrlShortenerApplicationTest { @Test void contextLoad() { - } } From 817e9eb09a1767c52fb41d155d591ab5b3fc053c Mon Sep 17 00:00:00 2001 From: ZZAMBAs Date: Tue, 2 Jan 2024 01:21:47 +0900 Subject: [PATCH 40/42] =?UTF-8?q?Refactor:=20=EB=A9=94=EC=84=9C=EB=93=9C?= =?UTF-8?q?=20=EB=82=B4=EB=B6=80=EB=A1=9C=20=EB=9E=9C=EB=8D=A4=20=EC=A0=95?= =?UTF-8?q?=EC=88=98=20=EB=A7=8C=EB=93=9C=EB=8A=94=20=EB=A1=9C=EC=A7=81?= =?UTF-8?q?=EC=9D=84=20=ED=8F=AC=ED=95=A8=EC=8B=9C=ED=82=A8=EB=8B=A4.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../shorturl/service/transformer/Base62UrlTransformer.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/main/java/org/prgms/springbooturlshortener/domain/shorturl/service/transformer/Base62UrlTransformer.java b/src/main/java/org/prgms/springbooturlshortener/domain/shorturl/service/transformer/Base62UrlTransformer.java index 2a049984..d8f614fa 100644 --- a/src/main/java/org/prgms/springbooturlshortener/domain/shorturl/service/transformer/Base62UrlTransformer.java +++ b/src/main/java/org/prgms/springbooturlshortener/domain/shorturl/service/transformer/Base62UrlTransformer.java @@ -1,5 +1,6 @@ package org.prgms.springbooturlshortener.domain.shorturl.service.transformer; +import java.util.Random; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.stereotype.Component; @@ -10,7 +11,10 @@ public class Base62UrlTransformer implements UrlTransformer{ private static final short NUM_OF_URL = 6; private static final int DIVIDE_NUM = 62; - public String transform(int number) { + public String transform() { + Random random = new Random(); + int number = random.nextInt(0, Integer.MAX_VALUE); + StringBuilder sb = new StringBuilder(); for (short i = 0; i < NUM_OF_URL; i++) { From bc3dbb591eb8b64404a3701526c38093bdb9c19a Mon Sep 17 00:00:00 2001 From: ZZAMBAs Date: Tue, 2 Jan 2024 01:22:14 +0900 Subject: [PATCH 41/42] =?UTF-8?q?Refactor:=20=EB=A6=AC=EB=8B=A4=EC=9D=B4?= =?UTF-8?q?=EB=A0=89=ED=8A=B8=20=EC=84=9C=EB=B2=84=EA=B0=80=20=EB=B3=80?= =?UTF-8?q?=EA=B2=BD=EB=90=A0=20=EA=B2=83=EC=9D=84=20=EC=83=9D=EA=B0=81?= =?UTF-8?q?=ED=95=B4=20=EC=83=81=EC=88=98=ED=99=94=ED=95=9C=EB=8B=A4.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/shorturl/controller/ShortUrlController.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/prgms/springbooturlshortener/domain/shorturl/controller/ShortUrlController.java b/src/main/java/org/prgms/springbooturlshortener/domain/shorturl/controller/ShortUrlController.java index b36be01c..6fd74b52 100644 --- a/src/main/java/org/prgms/springbooturlshortener/domain/shorturl/controller/ShortUrlController.java +++ b/src/main/java/org/prgms/springbooturlshortener/domain/shorturl/controller/ShortUrlController.java @@ -18,6 +18,7 @@ @Slf4j public class ShortUrlController { + private final String REDIRECT_URL = "localhost:8080"; private final ShortUrlService shortUrlService; public ShortUrlController(ShortUrlService shortUrlService) { @@ -46,13 +47,13 @@ public String transformOriginalUrl(TransformRequestUrlDto transformRequestUrlDto } @GetMapping("/shorten") - public String showTransformedUrl(TransformedShortUrlDto transformedShortUrlDto, Model model, HttpServletRequest request) { + public String showTransformedUrl(TransformedShortUrlDto transformedShortUrlDto, Model model) { if (transformedShortUrlDto.shortUrl() == null) { throw new UrlException(UrlErrorCode.ORIGINAL_URL_NOT_FOUND); } model.addAttribute("transformedShortUrlDto", transformedShortUrlDto); - model.addAttribute("domain", request.getServerName() + ":" + request.getServerPort()); + model.addAttribute("domain", REDIRECT_URL); return "short-url-info"; } From 0a15a04724552102e4609c8ffaec03969d2c313c Mon Sep 17 00:00:00 2001 From: ZZAMBAs Date: Tue, 2 Jan 2024 01:23:29 +0900 Subject: [PATCH 42/42] =?UTF-8?q?Chore:=20=EC=82=AC=EC=9A=A9=ED=95=98?= =?UTF-8?q?=EC=A7=80=20=EC=95=8A=EB=8A=94=20import=20=EB=AC=B8=EC=9D=84=20?= =?UTF-8?q?=EC=A0=95=EB=A6=AC=ED=95=9C=EB=8B=A4.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/shorturl/service/ShortUrlService.java | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/main/java/org/prgms/springbooturlshortener/domain/shorturl/service/ShortUrlService.java b/src/main/java/org/prgms/springbooturlshortener/domain/shorturl/service/ShortUrlService.java index 47d05491..e75da32f 100644 --- a/src/main/java/org/prgms/springbooturlshortener/domain/shorturl/service/ShortUrlService.java +++ b/src/main/java/org/prgms/springbooturlshortener/domain/shorturl/service/ShortUrlService.java @@ -1,5 +1,6 @@ package org.prgms.springbooturlshortener.domain.shorturl.service; +import java.util.Optional; import org.prgms.springbooturlshortener.domain.shorturl.ShortUrl; import org.prgms.springbooturlshortener.domain.shorturl.exception.UrlErrorCode; import org.prgms.springbooturlshortener.domain.shorturl.exception.UrlException; @@ -9,9 +10,6 @@ import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.stereotype.Service; -import java.util.Optional; -import java.util.Random; - @Service public class ShortUrlService { private final UrlTransformer urlTransformer;