问题
I am trying to make a slightly better @Cached annotation by making it aware of the parameters of the function I call in my controllers.
so I have this Action :
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()
}
}
My question is this : I would like to cache the result of delegate.call() only if it is an Ok(). How can I check for that? Is there a property? a util? or do I need to Ok().getClass().isInstance(result)?
Thanks for any answers and hints.
PS : Why do I want to do that? Because I have some calls that generate few types of different results. Few enough results that caching them could be an option since I don't want to
回答1:
An ok result is actually a play.mvc.Results.Status which wraps its Scala counterpart play.api.mvc.Results.Status, which in turn has its status code set to 200.
So you call result.getWrappedResult() and check if the type is right, cast it to PlainResult (the lowest common denominator) and call status.
This looks very ugly though:
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
}
回答2:
Less sucky approach:
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);
Works as of 2.2.2.
回答3:
Just to update this page with the latest 2.3+ Playframework way of doing it.
Result result = //.....
int httpStatus = result.toScala().header().status();
easy enough.
回答4:
If you know your Result is an instance of play.mvc.Results.Status (which it is if you created it using any of the static helper methods from the play.mvc.Results class) you can cast it to Status, and get a SimpleResult object directly using getWrappedSimpleResult():
Status result = (Status) YourController.actionHandler();
int expected = Results.ok()
.getWrappedSimpleResult().header().status();
int actual = result.getWrappedSimpleResult().header().status();
Assert.assertEquals(expected, actual);
来源:https://stackoverflow.com/questions/15117643/check-that-a-result-is-an-ok-playframework