Skip to content

Instantly share code, notes, and snippets.

@dluc
Created July 10, 2018 01:47
Show Gist options
  • Save dluc/063393a1ffa8f00ece2d27d2b39acb8f to your computer and use it in GitHub Desktop.
Save dluc/063393a1ffa8f00ece2d27d2b39acb8f to your computer and use it in GitHub Desktop.
Play Framework 2.6 Request Handler to ignore trailing slash
import com.google.inject.Inject;
import org.apache.commons.lang3.StringUtils;
import play.api.mvc.Handler;
import play.api.mvc.Handler$;
import play.api.mvc.RequestHeader;
import play.core.j.JavaHandler;
import play.core.j.JavaHandlerComponents;
import play.http.HandlerForRequest;
import play.http.HttpRequestHandler;
import play.libs.streams.Accumulator;
import play.mvc.EssentialAction;
import play.mvc.Http;
import play.mvc.Results;
import play.routing.Router;
import java.util.Optional;
public class IgnoreTrailingSlashesRequestHandler implements HttpRequestHandler {
private final Router router;
private final JavaHandlerComponents handlerComponents;
@Inject
public IgnoreTrailingSlashesRequestHandler(Router router, JavaHandlerComponents components) {
this.router = router;
this.handlerComponents = components;
}
@Override
public HandlerForRequest handlerForRequest(Http.RequestHeader request) {
Http.RequestHeader normalizedRequest = this.normalize(request);
Handler handler = this.getHandlerForRequest(normalizedRequest)
.orElse(EssentialAction.of(req -> Accumulator.done(Results.notFound())));
if (handler instanceof JavaHandler) {
handler = ((JavaHandler) handler).withComponents(handlerComponents);
}
return new HandlerForRequest(normalizedRequest, handler);
}
private Http.RequestHeader normalize(Http.RequestHeader request) {
String newPath = this.cleanPath(request.path());
RequestHeader scalaRequest = request.asScala();
return scalaRequest.withTarget(scalaRequest.target().withPath(newPath)).asJava();
}
private String cleanPath(String origPath) {
// https://commons.apache.org/proper/commons-lang
// org.apache.commons : commons-lang3 : 3.7
return StringUtils.stripEnd(origPath, "/");
}
// Get Play Framework request handler
private Optional<Handler> getHandlerForRequest(Http.RequestHeader request) {
return router
.route(request)
.map(handler ->
Handler$.MODULE$
.applyStages(request.asScala(), handler)
._2()
);
}
}
@dluc
Copy link
Author

dluc commented Jul 10, 2018

Note: entries in routes must have no trailing slash in order to be matched, e.g.

Correct:
GET /values @controllers.ValuesController.list

Wrong:
GET /values/ @controllers.ValuesController.list

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment