我需要将长URL转换为其中包含8个字符的短URL作为缩短URL,我将Spring Boot与Java结合使用,问题是每当我尝试缩短相同URL时得到相同的缩短URL,但我不希望为相同的链接生成相同的链接
@RequestMapping(value="/shorturl", method=RequestMethod.POST, consumes={"application/json"})
public ResponseEntity<?> shortenUrl(HttpServletRequest request,
@ApiParam(value="Body Parameters") @RequestBody @Validated ShortenRequest shortenRequest,
BindingResult bindingResult) throws Exception {
URLDto urlDto=new URLDto();
try {
LOGGER.info("Received url to shorten: " + shortenRequest.getUrl());
if (bindingResult.hasErrors()) {
throw new InvalidRequestException("Invalid Request", bindingResult);
}
String longUrl=shortenRequest.getUrl();
if (URLValidator.INSTANCE.validateURL(longUrl)) {
String shortenedUrl=urlConverterService.shortenURL(shortenRequest.getUrl());
if (shortenedUrl.equalsIgnoreCase("") || shortenedUrl == null || shortenedUrl.isEmpty()) {
urlDto.setUrl("No Records Found");
return convertToResponse(urlDto, HttpStatus.NOT_FOUND);
} else {
shortenedUrl=URLValidator.DOMAIN + "/" + shortenedUrl;
urlDto.setUrl(shortenedUrl);
LOGGER.info("Shortened url to: " + shortenedUrl);
return convertToResponse(urlDto, HttpStatus.OK);
}
}
} catch (Exception e) {
throw new CustomException(e.getMessage());
}
return convertToResponse(HttpStatus.OK);
}
上面的代码是我的控制器方法
public String shortenURL(String longUrl) {
urlDetail=new URLDetail();
String shortenedURL="";
try {
LOGGER.info("Shortening {}", longUrl);
shortenedURL=urlShortener.shortenURL(longUrl);
if (shortenedURL !=null){
URLDetail isExistingURL=urlRepository.findByshortenURL(shortenedURL);
if (isExistingURL == null || isExistingURL.equals("") || isExistingURL.equals(null)) {
LOGGER.info("The Unique ID, which is generated is " + shortenedURL);
urlDetail.setNoOfHits(0);
urlDetail.setShortenURL(shortenedURL);
urlDetail.setOriginalURL(longUrl);
LOGGER.info("Going to Save the URL Details to DB");
urlRepository.save(urlDetail);
LOGGER.info("URL Details has been Saved , Returning the shorten URL " + shortenedURL);
}
else{
LOGGER.info("Going to call shortenURL() in order to Shorten the URL (Recursive Call)");
shortenURL(longUrl);
}
} else {
LOGGER.info("Going to call shortenURL() in order to Shorten the URL (Recursive Call)");
shortenURL(longUrl);
}
return shortenedURL;
} catch (Exception e) {
LOGGER.info("Some issue while shortening the URL, Shorten URL{} " + e.getMessage());
LOGGER.error("Some Issue while Shortening the URL, Shorten URL{} " + e.getMessage());
}
return shortenedURL;
}
上面的代码是我的服务类方法,最后我的实际转换器类看起来像下面的代码
@EnableAutoConfiguration
@Service
public class URLShortener {
// In order to store the generated key
private HashMap<String, String> keyMap;
private HashMap<String, String> valueMap;
//THis attribute is used to map to our custom server url
private String domain;
private char myChars[];
// Random Object used to generate random integers
private Random myRandom;
private int keyLength;
URLShortener() {
keyMap = new HashMap<>();
valueMap = new HashMap<>();
myRandom = new Random();
keyLength = 8;
myChars = new char[62];
for (int i = 0; i < 62; i++) {
int j = 0;
if (i < 10) {
j = i + 48;
} else if (i > 9 && i <= 35) {
j = i + 55;
} else {
j = i + 61;
}
myChars[i] = (char) j;
}
domain = "https://abc.in";
}
// Constructor to define tiny URL key length and base URL
URLShortener(int length, String newDomain) {
this();
this.keyLength = length;
if (!newDomain.isEmpty()) {
newDomain = sanitizeURL(newDomain);
domain = newDomain;
}
}
// Shorten URL For the Public which can be called to shorten a given URL
public String shortenURL(String longURL) {
String shortURL = "";
if (URLValidator.INSTANCE.validateURL(longURL)) {
longURL = sanitizeURL(longURL);
if (valueMap.containsKey(longURL)) {
shortURL = valueMap.get(longURL);
} else {
shortURL = getKey(longURL);
}
}
return shortURL;
}
//Expand URL public method by which returns back the original URL given the shorten URL
public String expandURL(String shortURL) {
String longURL = "";
// String key = shorURL.substring(domain.length() + 1);
longURL = keyMap.get(shortURL);
return longURL;
}
// In order to Validate the URL Which whether given URL is valid or not, not implemented as of now, returning true as of now
private boolean validateURL(String url) {
return true;
}
//Sanitize URL takes care of several Issues with a valid URL
private String sanitizeURL(String url) {
if (url.substring(0, 7).equals("http://"))
url = url.substring(7);
if (url.substring(0, 8).equals("https://"))
url = url.substring(8);
if (url.charAt(url.length() - 1) == '/')
url = url.substring(0, url.length() - 1);
return url;
}
private String getKey(String longURL) {
String key;
key = generateKey();
keyMap.put(key, longURL);
valueMap.put(longURL, key);
return key;
}
private String generateKey() {
String key = "";
boolean flag = true;
if (flag) {
key = "";
for (int i = 0; i <= keyLength; i++) {
key += myChars[myRandom.nextInt(62)];
}
if (!keyMap.containsKey(key)) {
flag = false;
}
}
return key;
}
}
我的模型类看起来像这样
公共类ShortenRequest {
private String url;
@JsonCreator
public ShortenRequest() {
}
@JsonCreator
public ShortenRequest(@JsonProperty("url") String url) {
this.url = url;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
}
我不明白为什么会为同一链接一遍又一遍地生成相同的链接,对此将提供任何帮助。