2016-04-06 17 views
1

Üç paralel HTTP çağrısı yaptığım bir eylem var (diğer hizmetlere), sonra yanıtların içeriğini bir belgede birleştiririm ve sonunda onu istemciye geri gönderirim. Bu kodun bir çalışma örneğidir:Çerçeveyi paralel oynatır WSClient çağrıları hata yönetimi

servislerinden biri mevcut değilse
@Inject 
WSClient wsc; 

public CompletionStage<Result> getUrlData() throws Exception { 

    List<CompletionStage<WSResponse>> stages = new ArrayList<>(); 
    stages.add(wsc.url("http://jsonplaceholder.typicode.com/posts/1").get()); 
    stages.add(wsc.url("http://jsonplaceholder.typicode.com/posts/2").get()); 
    stages.add(wsc.url("http://jsonplaceholder.typicode.com/posts/3").get()); 

    return Futures 
      .sequence(stages) 
      .thenApply(responses -> { 
       StringBuilder builder = new StringBuilder("["); 
       responses.stream().forEach(response -> builder.append(response.getBody()).append(",")); 
       builder.deleteCharAt(builder.length()-1).append("]"); 
       return ok(builder.toString()); 
      }) 
      .exceptionally(ex -> ok("{\"error\": \"An error has occurred\"}")); 

(olmayan bir varolan birine URL'lerin birinin alanı adını değiştirerek bu davranışı taklit edebilir), sayfa içeriyor döndü Sadece istisnai() kısımda yer alan mesaj, doğru aramaların içeriğini ve başarılı olmayan aramanın hata mesajını geri göndermem gerekir. Nasıl yapılacağına dair bir ipucu var mı?

Oyna 2.5.1 kullanıyorum.

sayesinde Andrea

cevap

1

Temelde sadece her arama için ayrı ayrı .exceptionally(..) işlemek istiyorum. Böyle bir şey çalışması gerekir:

  1. tamamlama aşamalarında listesine Futures.sequence geçmek olduğunu dönüştürmek (hata JSON dönen) işleme Hatanızı birleştiren bir birey URL için bir CompletionStage döndüren bir işlev oluşturmak
  2. bir kenara olarak

, programlama yoluyla nesnelerin oluşturulması kullanarak JSON manipülasyon biraz daha hoş yapabilir Jackson'ın ObjectMapper.createObjectNode() ve ObjectMapper.createArrayNode():

private static final ObjectMapper mapper = new ObjectMapper(); 

private CompletionStage<JsonNode> getDataFromUrl(String url) { 
    return wsc.url(url) 
      .get() 
      .thenApply(WSResponse::asJson) 
      .exceptionally(ex -> { 
       ObjectNode error = mapper.createObjectNode(); 
       error.put("error", ex.getMessage()); 
       return error; 
      }); 
} 

public CompletionStage<Result> getUrlData() throws Exception { 

    List<String> urls = new ArrayList<>(); 
    urls.add("http://jsonplaceholder.typicode.com/posts/1"); 
    urls.add("http://jsonplaceholder.typicode.com/posts/2"); 
    urls.add("http://jsonplaceholder.typicode.com/posts/3"); 

    // Convert to a list of promises 
    List<CompletionStage<JsonNode>> stages = urls 
      .stream() 
      .map(this::getDataFromUrl) 
      .collect(Collectors.toList()); 

    return Futures 
      .sequence(stages) 
      .thenApply(responses -> { 
       ArrayNode arrayNode = mapper.createArrayNode(); 
       responses.stream().forEach(arrayNode::add); 
       return ok(arrayNode); 
      }); 
} 
+0

aslında benim yaptığım JSON manipülasyonu burada gönderdiğim örnekden daha karmaşık, ancak ObjectMapper çok iyi bir ipucu. Teşekkürler! –