Java 多路由处理-使用自己的requesthandler时获取异常

Java 多路由处理-使用自己的requesthandler时获取异常,java,playframework,Java,Playframework,我正在使用Play2.5.3,子项目下有2个路由文件。想法是使用与域相关的路由文件。 代码结构: root - modules - core - admin - admin.routes - web - web.routes 我的RequestHandler看起来像这样-- 获取以下异常- 2016-05-10 13:02:29,956 - [ERROR] - p.c.s.n.PlayRequestHandler - Exception caught in Nett

我正在使用Play2.5.3,子项目下有2个路由文件。想法是使用与域相关的路由文件。 代码结构:

root
- modules
  - core
  - admin
    - admin.routes
  - web
    - web.routes
我的RequestHandler看起来像这样--

获取以下异常-

2016-05-10 13:02:29,956 - [ERROR] - p.c.s.n.PlayRequestHandler - Exception caught in Netty
scala.MatchError: Right((play.core.routing.HandlerInvokerFactory$JavaActionInvokerFactory$$anon$14$$anon$3@50a3f51b,play.api.DefaultApplication@2072c28f)) (of class scala.util.Right)
        at play.core.server.netty.PlayRequestHandler.handle(PlayRequestHandler.scala:93)
        at play.core.server.netty.PlayRequestHandler.channelRead(PlayRequestHandler.scala:163)
        at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:292)
        at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:278)
        at com.typesafe.netty.http.HttpStreamsHandler.channelRead(HttpStreamsHandler.java:129)
        at com.typesafe.netty.http.HttpStreamsServerHandler.channelRead(HttpStreamsServerHandler.java:96)
        at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:292)
        at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:278)
        at io.netty.handler.codec.MessageToMessageDecoder.channelRead(MessageToMessageDecoder.java:103)
        at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:292)
2016-05-10 13:02:34,020 - [ERROR] - p.c.s.n.PlayRequestHandler - Exception caught in Netty
请在这方面帮助我们。或者让我们知道还有其他方法

  • 如果您有Java控制器,则需要使用play.api.http.JavaCompatibleHttpRequestHandler在Scala中实现它,或者使用play.http.DefaultHttpRequestHandler在Java中实现它。一般的假设是Java用户将使用play.http.*类,Scala用户将使用play.api.http.*类

  • 由于处理程序是play.api.mvc.Handler(Scala),因此实际上,路由仅在路由到Scala控制器时有效。如果您试图路由到Java控制器,那么您将得到我上面描述的错误。 因此,如果返回的处理程序是JavaHandler,则需要调用Handler.withComponents(components),其中components是注入的JavaHandlerComponents。这将返回Play Netty服务器能够处理的EssentialAction实例


  • (覆盖def RouterRequest)

    基于安德烈·克鲁伊的建议,我得出了这个解决方案:

    import play.api.mvc.Handler;
    import play.core.j.JavaHandler;
    import play.core.j.JavaHandlerComponents;
    import play.http.HandlerForRequest;
    import play.http.HttpRequestHandler;
    import play.mvc.Http;
    import router.Routes;
    
    import javax.inject.Inject;
    
    public class MyCustomHttpRequestHandler implements HttpRequestHandler {
    
        private final Routes myRoutes;
        private final JavaHandlerComponents components;
    
        @Inject
        public MyCustomHttpRequestHandler(router.Routes myRoutes, JavaHandlerComponents components) {
            this.myRoutes = myRoutes;
            this.components = components;
        }
    
    
        @Override
        public HandlerForRequest handlerForRequest(Http.RequestHeader request) {
            JavaHandler handler = (JavaHandler) myRoutes.asJava().route(request).get();
            Handler newHandler = handler.withComponents(components);
    
            return new HandlerForRequest(request, newHandler);
        }
    }
    
    我注意到在上述情况下,
    DefaultHttpErrorHandler
    会出现一些问题(例如404页面将无法工作)。要在
    handlerForRequest
    中修复此问题,我需要检查:

    Optional<Handler> route = myRoutes.asJava().route(request);
    if (route.isPresent()) {
        JavaHandler handler = (JavaHandler) route.get();
        Handler newHandler = handler.withComponents(components);
        return new HandlerForRequest(request, newHandler);
    } else {
        // this is the default behaviour from play.http.DefaultHttpRequestHandler
        Tuple2<RequestHeader, Handler> result = underlying.handlerForRequest(request._underlyingHeader());
        return new HandlerForRequest(new RequestHeaderImpl(result._1()), result._2());
    }
    
    Optional route=myRoutes.asJava().route(请求);
    if(route.isPresent()){
    JavaHandler=(JavaHandler)route.get();
    Handler newHandler=Handler.withComponents(组件);
    返回新HandlerForRequest(request,newHandler);
    }否则{
    //这是play.http.DefaultHttpRequestHandler的默认行为
    Tuple2 result=底层.handlerForRequest(request.\u underyingheader());
    返回新的HandlerForRequest(新的RequestHeaderImpl(result._1()),result._2());
    }
    
    这对我很有效。需要创建与Java兼容的RequestHandler。我改变了我的代码如下。不再是404了

    public class MyRequestHandler implements HttpRequestHandler { 
    private play.api.http.JavaCompatibleHttpRequestHandler adminRequestHandler;
    private play.api.http.JavaCompatibleHttpRequestHandler webRequestHandler;
    
    @Inject
    public MyRequestHandler(web.Routes webRoutes, HttpErrorHandler httpErrorHandler,admin.Routes adminRoutes,
                            HttpConfiguration configuration, HttpFilters httpFilters,
                            JavaHandlerComponents components) {
        adminRequestHandler = new JavaCompatibleHttpRequestHandler(adminRoutes,httpErrorHandler
                ,configuration, httpFilters,components);
        webRequestHandler = new JavaCompatibleHttpRequestHandler(webRoutes,httpErrorHandler
                ,configuration, httpFilters,components);
    }
    
     @Override
    public HandlerForRequest handlerForRequest(Http.RequestHeader request) {
        Logger.info("Request ---> ["+ request.method()+"] "+request.host() + request.uri() );
        if("admin".equalsIgnoreCase(getSubDomain(request))){
            Tuple2<RequestHeader, Handler> result = adminRequestHandler.handlerForRequest(request._underlyingHeader());
            return new HandlerForRequest(new RequestHeaderImpl(result._1()), result._2());
        }else {
            Tuple2<RequestHeader, Handler> result = webRequestHandler.handlerForRequest(request._underlyingHeader());
            return new HandlerForRequest(new RequestHeaderImpl(result._1()), result._2());
        }
    }
    
    公共类MyRequestHandler实现HttpRequestHandler{
    private play.api.http.JavaCompatibleHttpRequestHandler adminRequestHandler;
    private play.api.http.JavaCompatibleHttpRequestHandler webRequestHandler;
    @注入
    public MyRequestHandler(web.Routes webRoutes、HttpErrorHandler、HttpErrorHandler、admin.Routes adminRoutes、,
    HttpConfiguration配置,HttpFilters HttpFilters,
    JavaHandlerComponents(组件){
    adminRequestHandler=新的JavaCompatibleHttpRequestHandler(adminRoutes,httpErrorHandler
    ,配置,httpFilters,组件);
    webRequestHandler=新的JavaCompatibleHttpRequestHandler(webRoutes,httpErrorHandler
    ,配置,httpFilters,组件);
    }
    @凌驾
    公共HandlerForRequest HandlerForRequest(Http.RequestHeader请求){
    Logger.info(“请求-->[“+Request.method()+”]”“+Request.host()+Request.uri());
    if(“admin”.equalsIgnoreCase(getSubDomain(请求))){
    Tuple2 result=adminRequestHandler.handlerForRequest(request.\u underyingHeader());
    返回新的HandlerForRequest(新的RequestHeaderImpl(result._1()),result._2());
    }否则{
    Tuple2 result=webRequestHandler.handlerForRequest(request.\u underyingHeader());
    返回新的HandlerForRequest(新的RequestHeaderImpl(result._1()),result._2());
    }
    }
    
    我们也遇到了同样的问题。您找到解决方案了吗?我能够解决。Miph给出的答案与我的答案类似
    public class MyRequestHandler implements HttpRequestHandler { 
    private play.api.http.JavaCompatibleHttpRequestHandler adminRequestHandler;
    private play.api.http.JavaCompatibleHttpRequestHandler webRequestHandler;
    
    @Inject
    public MyRequestHandler(web.Routes webRoutes, HttpErrorHandler httpErrorHandler,admin.Routes adminRoutes,
                            HttpConfiguration configuration, HttpFilters httpFilters,
                            JavaHandlerComponents components) {
        adminRequestHandler = new JavaCompatibleHttpRequestHandler(adminRoutes,httpErrorHandler
                ,configuration, httpFilters,components);
        webRequestHandler = new JavaCompatibleHttpRequestHandler(webRoutes,httpErrorHandler
                ,configuration, httpFilters,components);
    }
    
     @Override
    public HandlerForRequest handlerForRequest(Http.RequestHeader request) {
        Logger.info("Request ---> ["+ request.method()+"] "+request.host() + request.uri() );
        if("admin".equalsIgnoreCase(getSubDomain(request))){
            Tuple2<RequestHeader, Handler> result = adminRequestHandler.handlerForRequest(request._underlyingHeader());
            return new HandlerForRequest(new RequestHeaderImpl(result._1()), result._2());
        }else {
            Tuple2<RequestHeader, Handler> result = webRequestHandler.handlerForRequest(request._underlyingHeader());
            return new HandlerForRequest(new RequestHeaderImpl(result._1()), result._2());
        }
    }