【问题标题】:Play Framework 2.5.12 - Get Method from CallPlay Framework 2.5.12 - 从调用中获取方法
【发布时间】:2019-06-07 00:42:51
【问题描述】:

我需要从 play.api.mvc.Call 实例中调用方法。 我已经注意到我的控制器的方法并使用反向路由我需要检查那些注释。

我正在使用 Play Framework 2.5.12

例子:

注释:

@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD, ElementType.TYPE})
public @interface MyAnnotation{
}

控制器:

public class MyController extends Controller {

    @MyAnnotation
    public Result home(int index){
      return ok(index);
    }
}

类:

public class MyClass{

    private Call call;

    public MyClass(Call call){
      this.call = call;
    }

    public boolean hasAnnotation(){
      //TODO
      return call.getControllerMethod().isAnnotationPresent(MyAnnotation.class);
    }
}

用途:

MyClass obj = new MyClass(routes.MyController.home(1));
if(obj.hasAnnotation()){
  //do something
}

显然call.getControllerMethod() 不存在,但我需要一些解决方案来从 URL 或调用实例中获取控制器的方法。

感谢您的支持。

【问题讨论】:

  • 我将您的解决方案移至社区 wiki 答案。

标签: java reflection playframework


【解决方案1】:

OP 的解决方案。

不幸的是,我解决了像这样创建调用包装器的问题:

public class CallRef extends Call {

    private Class<? extends Controller> controllerClass;
    private Method controllerMethod;

    public CallRef(Call call, Class<? extends Controller> controllerClass,
                   String controllerMethodName, Class<?>... methodArgs) throws NoSuchMethodException {

        this(call, controllerClass, controllerClass.getMethod(controllerMethodName, methodArgs));
    }

    public CallRef(Call call, Class<? extends Controller> controllerClass, Method controllerMethod) {
        this(call.method(), call.url(), call.fragment(), controllerClass, controllerMethod);
    }

    public CallRef(String method, String url, String fragment, Class<? extends Controller> controllerClass, Method controllerMethod) {
        super(method, url, fragment);
        this.controllerClass = controllerClass;
        this.controllerMethod = controllerMethod;
    }

    public CallRef(CallRef callRef){
            this(callRef, callRef.getControllerClass(), callRef.getControllerMethod());
    }

    public Class<? extends Controller> getControllerClass() {
        return controllerClass;
    }

    public Method getControllerMethod() {
        return controllerMethod;
    }
}

所以我需要在我的类CallRef 上手动创建实例,指定控制器、方法和参数。

【讨论】:

    【解决方案2】:

    1. play.api.mvc.Call 用于 Scala,Java 使用 play.mvc.Call

    2. Call 描述一个 HTTP 请求。您不能使用它从控制器方法中获取注释。只需像在任何其他情况下一样使用简单的反射来获取注释。

    更新

    你可以得到路由,然后看哪个模式代表你的URL,然后通过反射检查注解

    import com.google.inject.Provider;
    import play.routing.Router;
    import play.routing.Router.RouteDocumentation;
    
    ...
    
    @Inject 
    private Provider<Router> router;
    
    ...
    
    List<RouteDocumentation> docs = router.get().documentation();
    for(RouteDocumentation doc: docs){
        String protocol = doc.getHttpMethod();
        Sting pathPattern =  doc.getPathPattern();
        String methodStrign = doc.getControllerMethodInvocation());
    
        // Check the pathPattern against url
        // Get the annotation from the methodStrign by reflection.
    }
    

    【讨论】:

    • 好的,我知道 Call 描述了一个 HTTP 请求,但是有什么方法可以通过 url 获取方法实例(或者方法名称、控制器名称和参数类列表)?实际上我需要做 Play 在接收客户端 HTTP 请求时所做的工作:从 url 我需要知道需要调用什么方法。谢谢
    • 即您想用 @url("/myurl/here") 之类的方法注释该方法,然后如果 URL 在请求中,则调用该方法?
    • 我不会调用方法,但我只需要知道他的注释。我需要在应用程序启动时执行此操作,我有一个 URL/Call 列表并对其进行迭代,如果 url/Call 相关的方法有注释,我需要执行一些操作
    • 恐怕你需要解析路由文件,看我的更新。
    • 我怀疑不幸的是,我已经尝试过这种方式,但是在不知道参数类的情况下将路径模式与参数和反射调用匹配时遇到了一些问题
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-06-20
    • 1970-01-01
    • 1970-01-01
    • 2013-11-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多