简体   繁体   中英

How can I change an algorithm returning a String type to return a List type in Spring?

The job of this snippet is: When I give a long unique url in the form of List, it converts it to a short url.

@Slf4j
@Service
public class ShortUrlService {
        private static final String SERVICE_URL = "http://mysite.co/example-api.php";
        private static final String SIGNATURE = "45abc12345";
        private static final String ACTION = "shorturl";
        private static final String FORMAT = "simple";
        private static final String SERVICE_CALL_FAIL = "SERVICE_CALL_FAIL";
        
        private Random random = new Random();
        
        @Autowired
        private HttpClient httpClient;
    
        public String shortenUrl(String url, String pCache) {
            String shortUrl = null;
            String longUrl = url;
            
            if (!StringUtils.isEmpty(pCache)) {
                longUrl = addCacheParameter(url, pCache);
            }
            
            longUrl = longUrl.replace("&", "%26");
            
            try {
                shortUrl = httpClient.getRequest(buildServiceUrl(longUrl));
            } catch (IOException e) {
                log.error("Service call failed: " + e.getMessage());
                shortUrl = SERVICE_CALL_FAIL;
            }
            
            log.info("Short URL: " + shortUrl);
            
            if (shortUrl.contains("-")) {
                int rand = random.nextInt(999999);
                return shortenUrl(url, String.valueOf(rand));
            }
            
            return shortUrl;
        }
        
        private String addCacheParameter(String url, String pCache) {
            if (url.contains("?")) {
                return url + "&pCache=" + pCache;
            } else {
                return url + "?pCache=" + pCache;
            }
        }
    
        private String buildServiceUrl(String url) {
            StringBuilder sb = new StringBuilder();
    
            sb.append(SERVICE_URL);
            sb.append("?signature=");
            sb.append(SIGNATURE);
            sb.append("&action=");
            sb.append(ACTION);
            sb.append("&url=");
            sb.append(url);
            sb.append("&format=");
            sb.append(FORMAT);
            
            log.info("Built URL: " + sb.toString());
            
            return sb.toString();
        }
        
}

I have a service like below. The return value of this service is List I want to change to. I'm having problems in several places here can you help me fix the code?

@Slf4j
@Service
public class ShortUrlService {
      private static final String SERVICE_URL = "http://mysite.co/example-api.php";
      private static final String SIGNATURE = "45abc12345";
      private static final String ACTION = "shorturl";
      private static final String FORMAT = "simple";
      private static final String SERVICE_CALL_FAIL = "SERVICE_CALL_FAIL";
                
      private Random random = new Random();
            
      @Override
      public List<String> shortenUrl(List<String> url, String pCache) {
          List<String> shortUrl = null;
          List<String> longUrl = url;
    
          if (!StringUtils.isEmpty(pCache)) {
              longUrl = Collections.singletonList(addCacheParameter(url, pCache));
          }
    
          **longUrl = longUrl.replace("&", "%26");**
    
    
          RestTemplate restTemplate = new RestTemplate();
    
            try {
                **shortUrl = restTemplate.getForObject(buildServiceUrl(longUrl),List.class);**
            } catch (Exception e) {
                log.error("Service call failed: " + e.getMessage());
                 **shortUrl =  SERVICE_CALL_FAIL;**
            }
    
            log.info("Short URL: " + shortUrl);
    
            if (shortUrl.contains("-")) {
                int rand = random.nextInt(999999);
                return shortenUrl(url, String.valueOf(rand));
            }
    
            return shortUrl;
        }
    
        private String addCacheParameter(List<String> url, String pCache) {
            if (url.contains("?")) {
                return url + "&pCache=" + pCache;
            } else {
                return url + "?pCache=" + pCache;
            }
        }
    
        private String buildServiceUrl(List<String> url) {
            StringBuilder sb = new StringBuilder();
    
            sb.append(SERVICE_URL);
            sb.append("?signature=");
            sb.append(SIGNATURE);
            sb.append("&action=");
            sb.append(ACTION);
            sb.append("&url=");
            sb.append(url);
            sb.append("&format=");
            sb.append(FORMAT);
    
            log.info("Built URL: " + sb.toString());
    
            return sb.toString();
        }
                
}

Here httpClient.getRequest throws an error as it remains an old technology. I wanted to use RestTemplate instead. But did I use it right? And how can i write replace method as replaceAll?

Use a for loop, shorten each URL in the List , and add them to another List to return.

List<String> shortUrls = new ArrayList<>(urls.size());
if (!StringUtils.isEmpty(pCache)) {
  longUrl = Collections.singletonList(addCacheParameter(url, pCache));
}
RestTemplate restTemplate = new RestTemplate();
for (String url: urls) {
    String longUrl = url.replace("&", "%26");
    String shortUrl = null;
    try {
        shortUrl = restTemplate.getForObject(buildServiceUrl(longUrl),List.class);
    } catch (Exception e) {
        log.error("Service call failed: " + e.getMessage());
         shortUrl = SERVICE_CALL_FAIL;
    }
    log.info("Short URL: " + shortUrl);
    if (shortUrl.contains("-")) {
        int rand = random.nextInt(999999);
        shortUrl = shortenUrl(url, String.valueOf(rand));
    }
    shortUrls.add(shortUrl);
}
return shortUrls;
@Slf4j
@Service
public class ShortUrlService {
      private static final String SERVICE_URL = "http://mysite.co/example-api.php";
      private static final String SIGNATURE = "45abc12345";
      private static final String ACTION = "shorturl";
      private static final String FORMAT = "simple";
      private static final String SERVICE_CALL_FAIL = "SERVICE_CALL_FAIL";
                
      private Random random = new Random();
            
      @Override
      public List<String> shortenUrl(List<String> urls, String pCache, List<String> shortUrls, List<String> longUrls) {
          
          for(String url:urls){            
          if (!StringUtils.isEmpty(pCache)) {
              longUrl = Collections.singletonList(addCacheParameter(url, pCache));
              longUrl = longUrl.replace("&", "%26");
              longUrls.add(longUrl);
          }
          RestTemplate restTemplate = new RestTemplate();    
            try {
                **shortUrl = restTemplate.getForObject(buildServiceUrl(longUrl));**
            } catch (Exception e) {
                log.error("Service call failed: " + e.getMessage());
                 **shortUrl =  SERVICE_CALL_FAIL;**
            }
    
            log.info("Short URL: " + shortUrl);
    
            if (shortUrl.contains("-")) {
                int rand = random.nextInt(999999);
                return shortenUrl(url, String.valueOf(rand));
            }
            shortUrls.add(shortUrl);
            
           }
            return shortUrls;
        }
    
        private String addCacheParameter(String url, String pCache) {
            if (url.contains("?")) {
                return url + "&pCache=" + pCache;
            } else {
                return url + "?pCache=" + pCache;
            }
        }
    
         private String buildServiceUrl(String url) {
            StringBuilder sb = new StringBuilder();
    
            sb.append(SERVICE_URL);
            sb.append("?signature=");
            sb.append(SIGNATURE);
            sb.append("&action=");
            sb.append(ACTION);
            sb.append("&url=");
            sb.append(url);
            sb.append("&format=");
            sb.append(FORMAT);
            
            log.info("Built URL: " + sb.toString());
            
            return sb.toString();
        }
                
}

Try this.Modified some part.

In procedural languages, if you have something that applies to one thing and you need to support multiple things, the solution is 99% of the time a loop.

If you already have a method which handles the one thing, you can create an overload and delegate the actual work to this one method. This will work, but might not always the most efficient solution (think N+1 select problem for example). Some things are better done once before the loop instead of every time the loop's body is executed.

For your problem, easiest is to provide an overload (or a similarly named method). If you don't want the single-arg method to be callable any longer, you can mark it private.

The list-enabled method instantiates the new list to return, calls the original method and adds its result to the list. The list is ultimately returned:

    public List<String> shortenUrls(final List<String> urls, final String pCache) {
        final List<String> shortUrls = new ArrayList<>();
        for (final String url : urls) {
            shortUrls.add(shortenUrl(url, pCache));
        }
        return shortUrls;
    }

    public String shortenUrl(String url, String pCache) {
        // nothing to change in this method, except maybe make it `private`
        String shortUrl = null;
        String longUrl = url;
        
        if (!StringUtils.isEmpty(pCache)) {
            longUrl = addCacheParameter(url, pCache);
        }
        
        longUrl = longUrl.replace("&", "%26");
        
        try {
            shortUrl = httpClient.getRequest(buildServiceUrl(longUrl));
        } catch (IOException e) {
            log.error("Service call failed: " + e.getMessage());
            shortUrl = SERVICE_CALL_FAIL;
        }
        
        log.info("Short URL: " + shortUrl);
        
        if (shortUrl.contains("-")) {
            int rand = random.nextInt(999999);
            return shortenUrl(url, String.valueOf(rand));
        }
        
        return shortUrl;
    }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM