Compare commits
13 Commits
6d1c76cca6
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
020a211ac8 | ||
|
|
a2bf43d335 | ||
|
|
23042618f0 | ||
|
|
cfb900e4ed | ||
|
|
013152c248 | ||
|
|
e0fec299f9 | ||
|
|
7f6e2e6cd2 | ||
|
|
a166c7cafa | ||
|
|
12a66debc2 | ||
|
|
1034a5fa44 | ||
|
|
39fc4447a7 | ||
|
|
44fbabed19 | ||
|
|
9ea8160395 |
@@ -33,7 +33,7 @@ CREATE TABLE `click_stat` (
|
||||
`click_stat_id` BIGINT NOT NULL AUTO_INCREMENT,
|
||||
`url_map_id` BIGINT NOT NULL,
|
||||
`click_stat_clicked_at` DATETIME NOT NULL,
|
||||
`click_stat_user_agent` VARCHAR(20) NOT NULL,
|
||||
`click_stat_user_agent` VARCHAR(255) NOT NULL,
|
||||
`click_stat_ip_addr` VARCHAR(30) NOT NULL,
|
||||
PRIMARY KEY(click_stat_id),
|
||||
FOREIGN KEY(url_map_id) REFERENCES url_map(url_map_id)
|
||||
|
||||
@@ -54,12 +54,17 @@ public class MainController {
|
||||
/**
|
||||
* 단축 URL 조회 및 원본 URL로 Re-Direct 처리 메소드
|
||||
* @param shortUrl 단축 URL
|
||||
* @param request 사용자의 접속 정보
|
||||
* @param response Re-Direct 응답 처리를 위한 매개변수
|
||||
*/
|
||||
@GetMapping("/{shortUrl}")
|
||||
public void getShortUrl(@PathVariable(name="shortUrl") String shortUrl, HttpServletResponse response){
|
||||
public void getShortUrl(@PathVariable(name="shortUrl") String shortUrl, HttpServletRequest request, HttpServletResponse response){
|
||||
// 접속 정보들 추출
|
||||
String userAgent=request.getHeader("User-Agent");
|
||||
String userIpAddr=request.getRemoteAddr();
|
||||
|
||||
// 단축 URL을 통해, 원본 URL을 가져옴.
|
||||
String originalUrl=mainService.getOriginalUrl(shortUrl);
|
||||
String originalUrl=mainService.getOriginalUrl(shortUrl,userAgent,userIpAddr);
|
||||
// 가져온 원본 URL 값을 적잘한 URL이 될 수 있도록 Re-Direct하기 전에 URL-Encoding
|
||||
String encodeUrl=UriComponentsBuilder.fromUriString(originalUrl).build().encode().toUriString();
|
||||
// Re-Direct 상태 코드 설정
|
||||
|
||||
@@ -3,6 +3,8 @@ package be.gyu.urlShortener.entity;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
import jakarta.persistence.Entity;
|
||||
import jakarta.persistence.GeneratedValue;
|
||||
import jakarta.persistence.GenerationType;
|
||||
import jakarta.persistence.Id;
|
||||
import jakarta.persistence.JoinColumn;
|
||||
import jakarta.persistence.ManyToOne;
|
||||
@@ -18,6 +20,7 @@ import lombok.NoArgsConstructor;
|
||||
@AllArgsConstructor
|
||||
public class ClickStat {
|
||||
@Id
|
||||
@GeneratedValue(strategy=GenerationType.IDENTITY)
|
||||
private Long clickStatId;
|
||||
@ManyToOne
|
||||
@JoinColumn(name="url_map_id")
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
package be.gyu.urlShortener.repository;
|
||||
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
import be.gyu.urlShortener.entity.ClickStat;
|
||||
|
||||
@Repository
|
||||
public interface ClickStatRepository extends JpaRepository<ClickStat,Long>{
|
||||
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
package be.gyu.urlShortener.repository;
|
||||
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
|
||||
import be.gyu.urlShortener.entity.Users;
|
||||
|
||||
public interface UsersRepository extends JpaRepository<Users,Long>{
|
||||
|
||||
}
|
||||
@@ -3,14 +3,17 @@ package be.gyu.urlShortener.service;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import be.gyu.urlShortener.entity.ClickStat;
|
||||
import be.gyu.urlShortener.entity.UrlMap;
|
||||
import be.gyu.urlShortener.exception.ShortUrlNotFoundException;
|
||||
import be.gyu.urlShortener.exception.UrlValidationFailedException;
|
||||
import be.gyu.urlShortener.repository.ClickStatRepository;
|
||||
import be.gyu.urlShortener.repository.UrlMapRepository;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.regex.Pattern;
|
||||
import java.time.LocalDateTime;
|
||||
import java.security.MessageDigest;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
@@ -21,15 +24,19 @@ import io.seruco.encoding.base62.Base62;
|
||||
public class MainService {
|
||||
@Autowired
|
||||
private UrlMapRepository urlMapRepository;
|
||||
@Autowired
|
||||
private ClickStatRepository clickStatRepository;
|
||||
|
||||
// HTTP(S) URL 검증 패턴식
|
||||
private final String urlRegPattern="^((http|https):\\/\\/)?([a-z0-9-]{2,}\\.[a-z]{2,}|([0-9]{1,3}\\.){3}[0-9]{1,3})[\\w.\\/가-힣\\-\\ ?=&:%0-9A-Fa-f]*";
|
||||
private final Pattern urlPattern=Pattern.compile("^((http|https):\\/\\/)?([a-z0-9-]{2,}\\.[a-z]{2,}|([0-9]{1,3}\\.){3}[0-9]{1,3})[\\w.\\/가-힣\\-\\ ?=&:%0-9A-Fa-f]*");
|
||||
// URL 앞에 Protocol 존재 여부 확인 패턴식
|
||||
private final Pattern protocolPattern=Pattern.compile("^(http|https):\\/\\/");
|
||||
// Base62 Encoder Instance 생성 및 호출
|
||||
private Base62 base62=Base62.createInstance();
|
||||
|
||||
// HTTP(S) URL 검증 메소드
|
||||
public boolean validOriginalUrl(String url){
|
||||
return url.matches(urlRegPattern);
|
||||
return urlPattern.matcher(url).matches();
|
||||
}
|
||||
|
||||
// URL 단축 메소드
|
||||
@@ -89,14 +96,36 @@ public class MainService {
|
||||
}
|
||||
|
||||
// 단축 URL로 원본 URL 조회 및 반환 메소드
|
||||
public String getOriginalUrl(String shortUrl){
|
||||
public String getOriginalUrl(String shortUrl, String userAgent, String ipAddr){
|
||||
Optional<UrlMap> optional=urlMapRepository.findByUrlMapShort(shortUrl);
|
||||
|
||||
if(!optional.isPresent()){
|
||||
throw new ShortUrlNotFoundException();
|
||||
}
|
||||
|
||||
return optional.get().getUrlMapOriginal();
|
||||
// 접속 정보 저장을 위해서 새 엔티티 객체 생성
|
||||
ClickStat clickStat=ClickStat.builder()
|
||||
.clickStatClickedAt(LocalDateTime.now())
|
||||
.urlMap(optional.get())
|
||||
.clickStatUserAgent(userAgent)
|
||||
.clickStatIpAddr(ipAddr)
|
||||
.build();
|
||||
|
||||
// 접속한 클라이언트의 정보를 DB에 저장
|
||||
clickStatRepository.save(clickStat);
|
||||
String originalUrl=clickStat.getUrlMap().getUrlMapOriginal();
|
||||
|
||||
// 저장된 원본 URL에 Protocol이 있는지 확인
|
||||
// ㄴ 없으면, 원본 URL 값에 http 프로토콜을 추가
|
||||
if(!protocolPattern.matcher(originalUrl).find()){
|
||||
StringBuilder sb=new StringBuilder();
|
||||
sb.append("http://");
|
||||
sb.append(originalUrl);
|
||||
originalUrl=sb.toString();
|
||||
}
|
||||
|
||||
// 원본 URL을 반환
|
||||
return originalUrl;
|
||||
}
|
||||
|
||||
// 단축 URL 생성 메소드 (검증 및 생성)
|
||||
|
||||
Reference in New Issue
Block a user