简体   繁体   English

玩! 框架-SaaS子域名过滤器

[英]Play! Framework - SaaS subdomain name filter

I know this question has been asked quite a few times, however, I have a different approach of what I want to achieve. 我知道这个问题已经问了好几次了,但是,我要达到的目标却有不同的方法。

Since Play 1.1, you're able to match hosts. 从Play 1.1开始,您可以匹配主机。 This is very useful, however, it means that for every controller, I will need to pass through the subdomain route param. 这非常有用,但是,这意味着对于每个控制器,我都需要传递subdomain路由参数。 This is quite a burden and repeatful if I have hundreds of controllers which use the subdomain param. 如果我有成百上千个使用subdomain参数的控制器,这将是一个负担,并且是可重复的。

Is there not a way to create a filter which looks at the host name before everything else is executed and then sets an on-the-fly config value for that request? 有没有办法创建一个过滤器,该过滤器在执行所有其他操作之前先查看主机名,然后为该请求设置即时配置值?

For example (brainstorming), a filter would do the following: 例如(头脑风暴),过滤器将执行以下操作:

    // use request host, but hard-coded for now...
    String host = "test.example.com";
    Pattern p = Pattern.compile("^([a-z0-9]+)\\.example\\.com$");
    Matcher m = p.matcher(host);
    if (m.matches()) {
        // OUT: test
        System.out.println(m.group(1));
        System.setProperty("host", m.group(1));
    }

And in the models I'd do something like System.getProperty("host"); 在模型中,我会做类似System.getProperty("host");

I know this isn't how it should be done, but I'm just brainstorming. 我知道这不是应该怎么做,但我只是在集思广益。

At least with this way: 至少通过这种方式:

  1. I don't have to pass the subdomain param through to every controller. 我不必将subdomain参数传递给每个控制器。
  2. I don't have to pass the subdomain param through to any models either 我也不subdomain参数传递给任何模型
  3. Models have direct access to the subdomain value so I can filter out objects that belong to the client 模型可以直接访问subdomain值,因此我可以过滤出属于客户端的对象

Also, I'm aware that System.setProperty() always applies to the entire JVM; 另外,我知道System.setProperty()始终适用于整个JVM。 which is a problem. 这是一个问题。 I only want this value to be available throughout the duration of the request. 我只希望此值在整个请求期间都可用。 What should I use? 我应该使用什么?

Let's analyse. 让我们分析一下。 How would you do it? 你会怎么做? What would be a good approach? 有什么好的方法? Is this possible with Play? Play有可能吗? I'm sure there are quite a few running into this problem. 我敢肯定有很多遇到这个问题。 Your input is highly appreciated. 非常感谢您的投入。

I think you are close. 我觉得你很亲密。 If I had to do this, I would write a controller annotated with @Before and have that method extract the hostname from the request headers and put it in renderArgs. 如果必须这样做,我将编写一个带有@Before注释的控制器, @Before该方法从请求标头中提取主机名,并将其放入renderArgs中。

Something like this (I haven't tested it): 像这样的东西(我还没有测试过):

public class HostExtractor extends Controller {

    @Before
    public static void extractHost() {
       // Code to read from request headers and extract whatever you need here.
       String host = 'Your Code Here'
       renderArgs.put("hostname", host);
    }
}

Then, in your other controllers, you tell it you want to use that controller above as a filter. 然后,在其他控制器中,告诉您要使用上面的该控制器作为过滤器。

@With(HostExtractor.class)
public class MyController extends Controller {

    public static void homepage() {
        String hostname = renderArgs.get("host", String.class);
        // Do whatever logic you need to render the page here.
    }
}

Again, I haven't tested this, but I'm doing something similar to cache objects in memcache. 再说一次,我还没有测试过,但是我正在做类似于在内存缓存中缓存对象的事情。 I hope that helps! 希望对您有所帮助!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM