簡體   English   中英

Spring中返回String類型的算法怎么改成返回List類型?

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

這個片段的工作是:當我以列表的形式給出一個長的唯一 url 時,它將它轉換為一個短的 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();
        }
        
}

我有如下服務。 這個服務的返回值就是我要改成的List。 我在這里的幾個地方都遇到了問題,你能幫我修復代碼嗎?

@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();
        }
                
}

這里 httpClient.getRequest 拋出一個錯誤,因為它仍然是一項舊技術。 我想改用 RestTemplate。 但是我用對了嗎? 我怎樣才能將替換方法寫成 replaceAll?

使用 for 循環,將List中的每個 URL 縮短,並將它們添加到另一個List以返回。

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();
        }
                
}

試試這個。修改了一些部分。

在過程語言中,如果你有一些東西適用於一件事,而你需要支持多件事,那么解決方案在 99% 的情況下都是一個循環。

如果您已經有一個方法來處理一件事,您可以創建一個重載並將實際工作委托給這個方法。 這會起作用,但可能並不總是最有效的解決方案(例如考慮 N+1 select 問題)。 有些事情最好在循環之前完成一次,而不是每次執行循環體時都完成。

對於您的問題,最簡單的方法是提供重載(或類似命名的方法)。 如果您不想再調用單參數方法,可以將其標記為私有。

啟用列表的方法實例化要返回的新列表,調用原始方法並將其結果添加到列表中。 列表最終返回:

    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;
    }

當我有頁面時,如何在 Spring 引導中進行測試<object>作為返回類型<div id="text_translate"><p>我正在嘗試在我的服務 impl class 中測試我的保存方法。 它有 Page 作為返回類型。 測試成功,但我寫錯了,因為它在所有通常不應該的情況下都成功了請參閱下面的代碼。</p><p> 服務 Class 實施</p><pre> @Service @Transactional public class CompanyServiceImpl implements CompanyService { private final CompanyRepository companyRepository; public CompanyServiceImpl(CompanyRepository companyRepository) { this.companyRepository = companyRepository; } @Override public Page&lt;Company&gt; findAll(Pageable pageable) { Page&lt;Company&gt; result = companyRepository.findAll(pageable); return result; } @Override public Page&lt;Company&gt; searchCompany(String companyName, Long companyGroupId, Pageable pageable) { Page&lt;Company&gt; result = companyRepository.findByParametersWeb(companyName,companyGroupId,pageable); return result; } @Override public Optional&lt;Company&gt; findById(Long id) { Optional&lt;Company&gt; entity = companyRepository.findById(id); return entity; } @Override public Company save(Company company) { Company entity = companyRepository.save(company); return entity; } @Override public void delete(Long id) { companyRepository.deleteById(id); } }</pre><p> 測試服務 class</p><pre> class CompanyServiceImplTest { @Mock private CompanyRepository companyRepository; private CompanyService companyService; private Company company; @BeforeEach void setUp() { MockitoAnnotations.initMocks(this); companyService = new CompanyServiceImpl(companyRepository); company = new Company(); company.setName("company"); company.setCompanyGroupId(1L); } @Test void searchCompany() { List&lt;Company&gt; companies = new ArrayList&lt;&gt;(); Pageable pageable= PageRequest.of(0,5); Page&lt;Company&gt; result = new PageImpl&lt;&gt;(companies,pageable,1); when(companyRepository.findByParametersWeb(anyString(),anyLong(),any(Pageable.class))).thenReturn(result); Page&lt;Company&gt; newResult = companyService.searchCompany("giorgos",1L,pageable); assertEquals(newResult.getTotalElements(),result.getTotalElements()); } }</pre><p> 最后是我的公司存儲庫</p><pre>@Repository public interface CompanyRepository extends JpaRepository&lt;Company, Long&gt; { @Query("SELECT a FROM Company a WHERE (:name is null or ((a.name LIKE:name AND LENGTH(:name) &gt; 0) OR ( a.name = '%')))") List&lt;Company&gt; findByCompanyName(@Param("name") String name); @Query("SELECT a FROM Company a WHERE (:name is null or (LENGTH(:name) &gt; 0 " + " AND ((:option = 'yes' AND a.name =:name) or (:option = 'start' AND a.name LIKE CONCAT(:name,'%')) " + " or (:option = 'end' AND a.name LIKE CONCAT('%',:name)) or (a.name LIKE CONCAT('%',:name,'%'))))) " + " AND (:companyGroupId is null or a.companyGroupId =:companyGroupId) ORDER BY a.name") Page&lt;Company&gt; findByParametersWeb(String name,Long companyGroupId, Pageable pageable); List&lt;Company&gt; findAllByNameOrderByName(); }</pre></div></object>

[英]How can i make Testing in Spring boot when i have a Page<Object> as a return type

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

相關問題 如果返回類型是列表,我該如何鈎住 <string> 在xposed? 如何使用 Spring Boot 更改返回類型? 如何傳遞要返回的列表的類型? 變更清單類型<String> 我可以將字符串轉換為具有泛型類型的列表嗎? 在具有 void 返回類型的函數中返回字符串數組 當我有頁面時,如何在 Spring 引導中進行測試<object>作為返回類型<div id="text_translate"><p>我正在嘗試在我的服務 impl class 中測試我的保存方法。 它有 Page 作為返回類型。 測試成功,但我寫錯了,因為它在所有通常不應該的情況下都成功了請參閱下面的代碼。</p><p> 服務 Class 實施</p><pre> @Service @Transactional public class CompanyServiceImpl implements CompanyService { private final CompanyRepository companyRepository; public CompanyServiceImpl(CompanyRepository companyRepository) { this.companyRepository = companyRepository; } @Override public Page&lt;Company&gt; findAll(Pageable pageable) { Page&lt;Company&gt; result = companyRepository.findAll(pageable); return result; } @Override public Page&lt;Company&gt; searchCompany(String companyName, Long companyGroupId, Pageable pageable) { Page&lt;Company&gt; result = companyRepository.findByParametersWeb(companyName,companyGroupId,pageable); return result; } @Override public Optional&lt;Company&gt; findById(Long id) { Optional&lt;Company&gt; entity = companyRepository.findById(id); return entity; } @Override public Company save(Company company) { Company entity = companyRepository.save(company); return entity; } @Override public void delete(Long id) { companyRepository.deleteById(id); } }</pre><p> 測試服務 class</p><pre> class CompanyServiceImplTest { @Mock private CompanyRepository companyRepository; private CompanyService companyService; private Company company; @BeforeEach void setUp() { MockitoAnnotations.initMocks(this); companyService = new CompanyServiceImpl(companyRepository); company = new Company(); company.setName("company"); company.setCompanyGroupId(1L); } @Test void searchCompany() { List&lt;Company&gt; companies = new ArrayList&lt;&gt;(); Pageable pageable= PageRequest.of(0,5); Page&lt;Company&gt; result = new PageImpl&lt;&gt;(companies,pageable,1); when(companyRepository.findByParametersWeb(anyString(),anyLong(),any(Pageable.class))).thenReturn(result); Page&lt;Company&gt; newResult = companyService.searchCompany("giorgos",1L,pageable); assertEquals(newResult.getTotalElements(),result.getTotalElements()); } }</pre><p> 最后是我的公司存儲庫</p><pre>@Repository public interface CompanyRepository extends JpaRepository&lt;Company, Long&gt; { @Query("SELECT a FROM Company a WHERE (:name is null or ((a.name LIKE:name AND LENGTH(:name) &gt; 0) OR ( a.name = '%')))") List&lt;Company&gt; findByCompanyName(@Param("name") String name); @Query("SELECT a FROM Company a WHERE (:name is null or (LENGTH(:name) &gt; 0 " + " AND ((:option = 'yes' AND a.name =:name) or (:option = 'start' AND a.name LIKE CONCAT(:name,'%')) " + " or (:option = 'end' AND a.name LIKE CONCAT('%',:name)) or (a.name LIKE CONCAT('%',:name,'%'))))) " + " AND (:companyGroupId is null or a.companyGroupId =:companyGroupId) ORDER BY a.name") Page&lt;Company&gt; findByParametersWeb(String name,Long companyGroupId, Pageable pageable); List&lt;Company&gt; findAllByNameOrderByName(); }</pre></div></object> 如何使用spring AOP切入點表達式截取返回類型List 我可以在春季使用afterThrowing()方法返回自定義類型的對象嗎? 為什么我可以返回我的列表未指定類型的列表 <T> 退貨類型?
 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM