그래서 짧고 보기 쉽게 Url을 인코딩 해보자. 방법은 세 가지가 있고, 지금은 Base62를 사용한다.
DB의 pk정보를 사용하여 url 생성 : 데이터가 많아지면 이것도 길어질 수 있다
Base64(64진수) 사용 : +, /, = 등 특수문자는 URL 예약어이기 때문에 Url을 인코딩하는데에는 부적절한 방법이다. 대신 Url-safe한 방법으로 인코딩 할 수 있는데,
+
는 - (하이픈)
으로 대체되고, /
는 _ (언더스코어)
로 대체된다.
패딩 문자인 =
는 URL-safe Base64에서는 제거되거나 무시된다.
Base62(62진수) 사용
// https://github.com/seruco/base62
implementation 'io.seruco.encoding:base62:0.1.3'
Base62 base62 = Base62.createInstance();
- 인코딩
final byte[] encoded = base62.encode("Hello World".getBytes());
new String(encoded); // is "73XpUgyMwkGr29M"
- 디코딩
final byte[] decoded = base62.decode("73XpUgyMwkGr29M".getBytes());
new String(decoded); // is "Hello World"
public class Base62Service {
private static final Base62 base62Instance = Base62.createInstance();
public String encodeDirectionId(Long directionId){
return new String(base62Instance.encode(String.valueOf(directionId).getBytes()));
}
public Long decodeDirectionId(String encodedDirectionId){
String directionId = new String(base62Instance.decode(encodedDirectionId.getBytes()));
return Long.valueOf(directionId);
}
}
private PharmacyInfoDto convertToPharmacyInfo(Direction direction) {
return PharmacyInfoDto.builder()
.pharmacyAddress(direction.getTargetAddress())
.pharmacyName(direction.getTargetPharmacyName())
.directionUrl(baseUrl + base62Service.encodeDirectionId(direction.getId())) // shorten url
.roadViewUrl(ROAD_VIEW_BASE_URL + direction.getTargetLatitude() + "," + direction.getTargetLongitude())
.distance(String.format("%.2f km", direction.getDistance())) // 소수점 2번째 자리까지
.build();
}
public String findDirectionUrlById(String encodeId){
Long directionId = base62Service.decodeDirectionId(encodeId);
Direction direction = directionRepository.findById(directionId).orElseThrow(EntityNotFoundException::new);
String params = String.join(",", direction.getTargetPharmacyName(), String.valueOf(direction.getTargetLatitude()),
String.valueOf(direction.getTargetLongitude()));
//Uri를 동적으로 생성해주는 클래스, .toUriString()는 한글을 UTF-8로 자동으로 인코딩 해준다.
String directionUrl = UriComponentsBuilder.fromHttpUrl(DIRECTION_VIEW_BASE_URL + params).toUriString();
return directionUrl;
}
public class DirectionController {
private final DirectionService directionService;
@GetMapping("/dir/{encodedId}")
public String searchDirection(@PathVariable String encodedId){
String directionUrl = directionService.findDirectionUrlById(encodedId);
// 사용자가 입력한 주소를 기준으로 추천된 약국을 DB에서 가져오고 길안내 url 생성
log.info("direction url : {}", directionUrl);
return "redirect:" + directionUrl;
}
}