2013-05-05 61 views
1

最近我正在学习Spring。我创建了一个简单的Web应用程序,基本上应该有2种类型的用户:Spring MVC - Spring Security - 控制器通用架构 - 最佳实践

  • 客户
  • 联系

你能想象的应用作为一个典型的购物web应用程序,其中管理员有权限添加新项目,客户可以看到列出的项目并添加到他们的购物车。 我的问题是关于系统的通用体系结构,它应该是Spring Framework的最佳实践示例之一。

我可以在这里列出的点有关这一建筑的决定,你能告诉我,你是否会以另一种方式做这些:

我有2级不同的调度员的servlet。因此,公众下的网址将用于客户,管理员将用于管理员。

<servlet-mapping> 
    <servlet-name>public-dispatcher</servlet-name> 
    <url-pattern>/public/*</url-pattern> 
</servlet-mapping> 

<servlet-mapping> 
    <servlet-name>admin-dispatcher</servlet-name> 
    <url-pattern>/admin/*</url-pattern> 
</servlet-mapping> 

2-在Spring-security.xml文件我有一个这样的管理认证:

<intercept-url pattern="/admin/**" access="ROLE_ADMIN" /> 

(所有的URL /管理之下的行动/将密码保护)

每个Servlet都有一个viewResolver指向一个不同的文件夹,其中包含jsps:

/WEB-INF/admin-jsp/ (admin jsps) 
/WEB-INF/public-jsp/ (customer jsps) 

4-可以说我有这些域对象:Item,ShoppingCart,Customer等。对于每个域对象,我有一个Controller类,即ItemController,它处理关于某个项目的所有请求(客户和管理员)。

@Controller 
@RequestMapping("/item") 
@SessionAttributes({"cart"}) 
public class ItemController { ... 

这些决定中的每一个,当我一个一个考虑他们时都是有意义的。但实际上,很显然,因为我没有看到任何大的Spring应用程序(因特网包含很多小代码部分,它们并不能提供有关整体的信息),所以这里有些问题..

For Instance:我可以将这个url作为customer/public/item/addNewItem(实际上是为管理员)调用,并且该方法将被执行,因为ItemController(/ item)对每个人都是可见的。但是因为我在两个不同的位置有jsps,所以Spring会抛出视图不存在的错误。 同样作为一个管理员,当我可以打电话的URL /管理/项目/ addToCart ....

什么是最好的拱门。实施整体?我应该在安全配置中定义更多的URL吗?例如:

<intercept-url pattern="/admin/**" access="ROLE_ADMIN" /> 
<intercept-url pattern="/admin/addNewItem" access="ROLE_ADMIN" /> 

OR

如果我有不同的角色定义不同的控制器?

@RequestMapping("/public/item") 
    @SessionAttributes({"cart"}) 
    public class PublicItemController { ... 

@RequestMapping("/admin/item") 
    public class AdminItemController { ... 

OR

任何其他方式?在一个有很多角色,控制器等发生的大系统中应该如何实现。

回答

2

我知道我迟到了这个讨论(你现在可能已经解决你的问题),但在这里,这是所有迟来像我:)

使用Spring安全性(或任何安全框架),我们通常控制对我们的应用程序“资源”(可通过​​应用程序URL访问)的访问,为此我们需要一个ROLE-TO-RESOURCE映射。

  1. 它是不是有2周不同的调度员的servlet,除非你有专门的非常有力的理由一个好方法。要使用“Spring Security”,就足够了。

  2. 这是您应该从头开始的方法,允许访问基于用户ROLE的URL模式。在允许访问请求的URL之前,Spring安全框架类用于检查用户ROLE。

  3. 我们正在保护逻辑资源,我们无论如何都不允许用户直接访问我们的物理资源。将您的JSP保存在WEB-INF内,并且您很好。

  4. 对于不同的ROLE,您不需要有不同的控制器。控制器方法用于为Web请求提供服务,如果用户不被允许访问特定的URL,那么提供该URL的Controller方法将永远不会被执行。

1

非常有趣的方法。您可以通过为每个调度程序servlet定义两个不同的控制器列表来解决实际问题。有多种方法来存档它,例如:

  1. 而不是使用组件扫描在XML中手动声明每个控制器。
  2. 如果你有几个例外,那么你可以使用filters。创建两个新注释,OnlyForAdminControllerOnlyForPublicController。注释相应的类。然后自定义组件的扫描选项每个调度的servlet:
<!-- For public --> 
<context:component-scan base-package="com.yourproject.conrollers"> 
    <context:exclude-filter type="annotation" expression="com.yourproject.annotation.OnlyForAdminController"/> 
</context:component-scan> 


<!-- For admin --> 
<context:component-scan base-package="com.yourproject.conrollers"> 
    <context:exclude-filter type="annotation" expression="com.yourproject.annotation.OnlyForPublicController"/> 
</context:component-scan> 

在这种类型的(网上商店)的大部分时间,你将有公共和管理用户的一些特殊要求的真正的系统。例如,在ItemController的情况下,管理员用户可以看到一些销售统计作为附加信息,其中公共用户可以看到5个之前查看的项目的列表。所以从性能的角度来看,你将有两个独立的控制器。在任何情况下,您都可以在可能的情况下重新使用某些控制器,并在稍后请求某些特殊行为时为每个用户分配这些控制器。当你在两种类型的用户之间只有很小的差异时,你的技术会更加有趣。

2
  1. 通常在Spring应用程序中有一个调度程序servlet。我不认为有一个用于公共请求,一个用于管理请求会为您购买任何东西。

  2. 是的,听起来不错

  3. 同样,我不明白如何分割管理和公共的JSP到不同的目录是要帮助你。如果您拥有两个区域共有的JSP,最终可能会让您感到困惑

  4. 这取决于您的个人偏好。我定义XML我的安全的东西,但很多人更喜欢注解

+0

谢谢。 4.点实际上更多关于控制器类计数专业领域对象,比基于注释的配置;) – akcasoy 2013-05-06 11:15:39

+0

啊,OK。在这种情况下,我可能会有单独的控制器的管理员和公共项目控制器。 – ashario 2013-05-07 03:43:35