5

我有一个 Spring mvc (3.1.1) 应用程序,我想定义超出 RequestMapping 中可用的条件。我有几件事想用它来做。

首先,如果我可以为不同的用户类型显示不同的主页,那就太好了:

@Controller
public class HomepageController {

    @RequestMapping(value = "/")
    @CustomCondition(roles = Guest.class)
    public String guestHome() { /*...*/ }

    @RequestMapping(value = "/")
    @CustomCondition(roles = Admin.class)
    public String adminHome() { /*...*/ }

}

其次,我希望该应用程序既可用作网站又可用作 REST 服务(例如,对于移动应用程序),因此我想让网站同时访问 html 和 json 操作,并仅让服务(不同的子域)访问 json 操作(其中某种@CustomCondition(web = true)只匹配网站 url)

这可以用于我计划的两种用途中的任何一种吗?

我发现关于自定义条件的文档很少,但我确实找到了一个实现自定义条件的示例,这可能是我想要的,但它使用一个@Configuration类而不是我正在使用的 XML 配置,我不想移动我的整个spring xml定义到一个@Configuration类。

我可以RequestMappingHandlerMapping在 XML 中定义 customMethodCondition 吗?

我尝试了 subclassingRequestMappingHandlerMapping和 override getCustomMethodCondition,以返回我的 custom RequestCondition,但它没有用 -getMatchingCondition()在我的情况下没有触发。

任何帮助将不胜感激!

更新

我读了更多,它看起来像是RequestMappingHandlerMapping一个新课程(从 3.1 版开始)。

在我的应用程序中发生的情况是,试图覆盖并因此重新定义requestMappingHandlerMappingbean 的 @Configuration 确实有效,但 url 映射( s@RequestMapping中的方法@Controller)似乎被处理了两次,一次由子类处理,ExtendedRequestMappingHandlerMapping一次由原始RequestMappingHandlerMapping--first 处理自定义条件,然后再没有它。

底线是我的自定义条件被简单地忽略了。

这应该是一种高级模式,但 IMO 它应该很常见......

评论有人吗?

4

2 回答 2

3

Spring MVC 已经提供了一种区分 json 和 html 的机制,RequestMapping 注解采用了一个查看请求内容类型的消费者属性...

// REST version, Content-type is "application/json"
@RequestMapping(value = "/", consumes = "application/json")
public void myRestService() {
...

// HTML version, Content-type is not "application/json"
@RequestMapping(value = "/", consumes = "!application/json")
public void myHtmlService() {
...

使用相同 url 但具有不同方法的另一种方法是使用 param 或 headers 属性...

// the url is /?role=guest
@RequestMapping(value = "/", param = "role=guest")
public void guestService() {

// the url is / with header role=admin
@RequestMapping(value = "/", headers = "role=admin")
public void adminService() {

我认为您会想要不同的网址以确保安全。通常,使用 Spring Security 之类的东西,您会将所有管理功能放在 /admin 下,并让框架管理它们......

<http auto-config="true">
  <intercept-url pattern="/admin/**" access="ROLE_ADMIN" />
...

这对于您的用例是否足够?

于 2012-06-06T20:27:48.213 回答
1

如果您扩展了 RequestMappingHandlerMapping(例如 ExtendedRequestMappingHandlerMapping),则必须在应用程序上下文 xml 中注册这个新映射略有不同。

您不能使用<mvc:annotation-driven/>Spring MVC 来配置它,因为它在内部定义了它自己的 handlerMapping,您可以按照这些方式做一些事情(或按照@Configuration您提供的链接中的方法):

<bean name="handlerAdapter" class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter">
    <property name="webBindingInitializer">
        <bean class="org.springframework.web.bind.support.ConfigurableWebBindingInitializer">
            <property name="conversionService" ref="conversionService"></property>
            <property name="validator">
                <bean class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean"/>
            </property>
        </bean>
    </property>
    <property name="messageConverters">
        <list>
            <bean class="org.springframework.http.converter.ByteArrayHttpMessageConverter"></bean>
            <bean class="org.springframework.http.converter.StringHttpMessageConverter"></bean>
            <bean class="org.springframework.http.converter.ResourceHttpMessageConverter"></bean>
            <bean class="org.springframework.http.converter.xml.SourceHttpMessageConverter"></bean>
            <bean class="org.springframework.http.converter.xml.XmlAwareFormHttpMessageConverter"></bean>
            <bean class="org.springframework.http.converter.xml.Jaxb2RootElementHttpMessageConverter"></bean>
            <bean class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter"></bean>
        </list>
    </property>
</bean>

<bean name="handlerMapping" class="..ExtendedRequestMappingHandlerMapping">
</bean>

这应该确保您的映射生效,并确保组件handler method找到适当的映射handlerAdapter

于 2012-06-06T21:19:45.337 回答