如何在拦截器中获取路径变量

时间:2015-04-06 08:15:21

标签: java playframework annotations playframework-2.2

我正在使用Play framework 2.0,它有一个非常简单的流程... routes - >控制器 - >服务 - >模型 - >控制器 - >结果

嗯,接下来我有一个控制器,它从路径接收一个路径变量。

GET / user /:userId controller.user.getUser(userId:String)

正如你可以看到的,这实际上是一个userId,我想验证这个userId(检查它是否存在于我们的数据库中)但不是在控制器中,而是使用一些注释,就像这样..

//My annotation for validating userId
@ValidateUserId(userId)
public static Result getUser(userId)

1 个答案:

答案 0 :(得分:0)

这个概念的主要问题是注释的参数必须是常数,@ see topic about this因此你将无法使用userId代码。相反,您可以创建一个读取上下文本身的注释,然后解析URI以获取用户的ID。即:

应用/ myannotations / MyAnnotations.class

package myannotations;

import play.mvc.With;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;


public class MyAnnotations {

    @With(ValidateUserIdAction.class)
    @Target({ElementType.TYPE, ElementType.METHOD})
    @Retention(RetentionPolicy.RUNTIME)
    public @interface ValidateUserId {
        String patternToReplace();
        String redirectTo();
    }

}

应用/ myannotations / ValidateUserIdAction.class

package myannotations;

import play.mvc.Action;
import play.mvc.Http;
import play.mvc.Result;

import static play.libs.F.Promise;

public class ValidateUserIdAction extends Action<MyAnnotations.ValidateUserId> {

    public Promise<Result> call(Http.Context ctx) throws Throwable {
        boolean isValid = false;

        // This gets the GET path from request
        String path = ctx.request().path();
        try {
            // Here we try to 'extract' id value by simple String replacement (basing on the annotation's param)
            Long userId = Long.valueOf(path.replace(configuration.patternToReplace(), ""));

            // Here you can put your additional checks - i.e. to verify if user can be found in DB
            if (userId > 0) isValid = true;

        } catch (Exception e) {
            // Handle the exceptions as you want i.e. log it to the logfile
        }

        // Here, if ID isValid we continue the request, or redirect to other URL otherwise (also based on annotation's param)
        return isValid
                ? delegate.call(ctx)
                : Promise.<Result>pure(redirect(configuration.redirectTo()));
    }    
}

因此您可以将其用于以下操作:

@MyAnnotations.ValidateUserId(
   patternToReplace = "/user/", 
   redirectTo = "/redirect/to/url/if/invalid"
)
public static Result getUser(userId){
     ....
}

当然这是非常基本的样本,您可能希望/需要使您的validationAction类中的条件更复杂,或者添加更多参数以使其更通用,所有这些都取决于您。