0

我目前正在开发一个基于 Spring 的 Web 应用程序,并且有一个 Spring MVC 似乎没有(至少不是开箱即用)提供的特殊要求。该应用程序为多个用户提供数据,每个用户都组织在自己的“公司”中。用户登录后,我可以识别他所属的公司。

应用程序本身是由多个“模块”构建的,每个模块都有自己的域对象、DAO、服务和控制器类。这个概念背后的想法是,例如,我可以根据用户扩展某个控制器类(假设使用不同的服务类),这就是我的问题。

由于我不想更改某些用户的请求路径,因此我目前正在寻找一种方法,如何根据发出请求的用户为在某个请求路径上发出的请求提供不同的控制器实例。我想出了为公司附加一个 HTTP 标头字段的想法示例:

X-Company:12345

并让我的控制器配置如下:

@Controller
@RequestMapping(value="/foo/")
public class FooController { 
 // ...
}

@Controller
@RequestMapping(value="/foo" headers="X-Company=12345")
public class SpecialFooController extends FooController {
 // ...
}

然而这是不可能的,因为 Spring MVC 将每个标头(Content-Type 和 Accept 除外)视为一种限制,因此在我的情况下,除非我添加“标头”限制,否则它将使用 FooController 而不是 SpecialFooController 处理所有请求在 FooController 上也是如此,这是不切实际的。有什么方法可以自定义这种行为或可以指向我寻找的方向吗?或者也许有人有另一个想法如何实现这一点。将不胜感激。谢谢!

4

3 回答 3

0

我不确定,但我认为您可以使用HandlerMapping来做到这一点。看看文档

于 2013-04-26T19:38:59.893 回答
0

要采纳您自己的建议,您可以@RequestHeader在控制器方法中使用注释:

@Controller
public class MyController {

    @RequestMapping("/someAction")
    public void myControllerMethod(@RequestHeader('X-Company-Id') String companyId) {

    }
}

或者你可以使用@PathVariable

@Controller
public class MyController {

    @RequestMapping("/{companyId}/someAction")
    public void myControllerMethod(@PathVariable("companyId") String companyId) {

    }
}

使用这种方法意味着实际上每个公司的 URL 是不同的,但是如果您可以设置公司 ID 标头,我想您也可以在 URL 后加上公司 ID。

但也有其他可能性。您可以编写一个拦截器,将公司 ID 放入会话或请求变量中。然后您不必将注释添加到每个控制器方法。您也可以为每个公司使用一个子域,但如果公司 id 是一个随机的字母数字字符串,那看起来就不太漂亮了。例如:companyone.mydomain.com,companytwo.mydomain.com

编辑

@RequestMapping如您所知,可以添加到控制器级别,所以您应该能够做到

@Controller
@RequestMapping("/controller/{companyId}")

作为基本网址,如果这是一个更好的选择。

于 2013-04-26T19:44:05.717 回答
0

我能够通过使用定制的RequestCondition来满足要求。通过定义您自己的注释,该注释可以放置在控制器的类型和方法级别。通过您自己的实现扩展RequestMappingHandlerMapping并覆盖 getCustomTypeCondition() 和 getCustomMethodCondition() 方法将控制器注释转换为您自己的 RequestCondition。

当请求进入时,将评估自定义的 RequestCondition,然后调用带注释的控制器(方法)来处理请求。然而,这有一个缺点,需要删除一个 servlet-context.xml 文件并切换到 WebMvcConfigurationSupport 类,以便能够使用您自定义的 RequestMappingHandlerMapping 类。

这个问题也在这里讨论过。

编辑:一个很好的例子可以在这里找到。

于 2013-04-27T16:06:37.413 回答