2013-02-27 9 views
7

Próbuję zrobić nieco lepszą adnotację z poziomu podręcznika, informując o parametrach funkcji, którą wywołuję w kontrolerach.Sprawdź, czy wynik jest poprawny dla playframework

więc mam to działanie:

public class ContextualCachedAction extends Action<ContextualCached> { 

    @Override 
    public Result call(Context ctx) throws Throwable { 
     try { 
      String key = makeKey(ctx); 
      Integer duration = configuration.duration(); 
      Result result = (Result) Cache.get(key); 
      if (result == null) { 
       result = delegate.call(ctx); 

       //TODO find a way to cache only successful calls 

       Cache.set(key, result, duration); 
      } 
      return result; 
     } catch (RuntimeException e) { 
      throw e; 
     } catch (Throwable t) { 
      throw new RuntimeException(t); 
     } 
    } 

    private String makeKey(Context ctx) { 
     //makes the key from some parameters in the ctx.request() 
    } 
} 

Moje pytanie jest takie: Chciałbym buforować wynik delegate.call() tylko wtedy, gdy jest to OK(). Jak mogę to sprawdzić? Czy jest nieruchomość? a util? lub czy potrzebuję Ok(). GetClass(). IsInstance (wynik)?

Dzięki za wszelkie odpowiedzi i wskazówki.

PS: Dlaczego chcę to zrobić? Ponieważ mam połączenia, które generują kilka typów różnych wyników. wystarczającej kilka wyników, które ich buforowanie może być opcja, ponieważ nie chcę, aby

Odpowiedz

6

ok wynik jest rzeczywiście play.mvc.Results.Status który owija swój odpowiednik play.api.mvc.Results.Status Scala, który z kolei jego kod status ustawiony na 200.

Zadzwoń więc pod numer result.getWrappedResult() i sprawdź, czy typ jest właściwy, rzuć go na PlainResult (najniższy wspólny mianownik) i zadzwoń pod numer status.

To wygląda bardzo brzydki choć:

play.api.mvc.Result wrappedResult = result.getWrappedResult(); 
    if (wrappedResult instanceof play.api.mvc.PlainResult) { 
    play.api.mvc.PlainResult plainResult = (play.api.mvc.PlainResult)wrappedResult; 
    int code = plainResult.header().status(); 
    if (code == OK) 
     // Cache 
    } 
+0

To zadziałało ... dzięki –

+3

Czy to jest zalecany sposób, aby to zrobić? Wydaje się to naprawdę niezręczne i skomplikowane, aby osiągnąć coś prostego, jak sprawdzanie kodu statusu odpowiedzi – knittl

+0

Co, jeśli to nie jest instancja 'PlainResult'? – jlars62

2

Jeśli znasz swój Result jest instancją play.mvc.Results.Status (co to jest, jeśli stworzył go za pomocą dowolnego z statycznych metod z klasy play.mvc.Results) można oddać go Status, a otrzymasz SimpleResult obiekt bezpośrednio za pomocą getWrappedSimpleResult():

Status result = (Status) YourController.actionHandler(); 
int expected = Results.ok() 
     .getWrappedSimpleResult().header().status(); 
int actual = result.getWrappedSimpleResult().header().status(); 
Assert.assertEquals(expected, actual); 
8

Mniej sucky podejście:

import org.junit.*; 
import static org.fest.assertions.Assertions.assertThat; 
import static play.test.Helpers.*; 

/* do stuff */ 

Result result = doSomethingWithController(); 
assertThat(status(result)).isEqualTo(OK); 

Działa od wersji 2.2.2.

+0

To działa, ale aby użyć tego w kodzie produkcyjnym (nie w kodzie testowym), musiałem wyraźnie dodać zależność do bibliotek testowych, np. (dla Play z Javą 2.2.1): '" com.typesafe.play "%" play-test_2.10 "%" 2.2.1 "' –

+0

Gdzie zdefiniowano "OK"? –

3

Tylko po to, aby zaktualizować tę stronę za pomocą najnowszej wersji 2.3+ Playframework.

Result result = //..... 
int httpStatus = result.toScala().header().status(); 

łatwe.