Добавление пользовательских RequestCondition в Spring mvc 3.1

У меня есть приложение Spring mvc (3.1.1), и я хочу определить условия, выходящие за рамки того, что доступно в RequestMapping. У меня есть пара вещей, для которых я хочу использовать это.

Во-первых, было бы неплохо, если бы я мог показать другую домашнюю страницу для разных типов пользователей:

<code>@Controller
public class HomepageController {

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

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

}
</code>

Во-вторых, я хочу, чтобы приложение функционировало как веб-сайт и как служба REST (например, для мобильных приложений), поэтому я хочу, чтобы веб-сайт имел доступ как к действиям html, так и к json, и разрешил только службе (другому поддомену) Доступ к действиям JSON (какой-то@CustomCondition(web = true) который соответствует только URL сайта)

Может ли это работать для любого из двух видов использования, которые я планирую?

Я нашел очень мало документации о пользовательских условиях, но я нашелодин пример тотреализует пользовательские условия что может быть то, что я хочу, но он использует@Configuration класс вместо конфигурации XML, которую я использую, и я не хочу перемещать все мои определения Spring XML в@Configuration учебный класс.

Могу ли я определить customMethodCondition дляRequestMappingHandlerMapping в XML?

Я пробовал создавать подклассыRequestMappingHandlerMapping и переопределитьgetCustomMethodCondition, чтобы вернуть мой обычайRequestCondition, но это не сработало -getMatchingCondition() в моем состоянии не стрелял.

Любая помощь будет принята с благодарностью!

UPDATE

Я читаю немного больше, и это выглядит какRequestMappingHandlerMapping это новый класс (начиная с версии 3.1).

В моем приложении происходит то, что @Configuration пытается переопределить и, таким образом, переопределитьrequestMappingHandlerMapping бин на самом деле работает, но отображение URL (@RequestMapping методы в@Controllers) кажетсяget processed twiceоднажды подклассомExtendedRequestMappingHandlerMapping и однажды по оригиналуRequestMappingHandlerMapping - сначала с пользовательским условием, а затем снова без него.

Суть в том, что мои пользовательские условия просто игнорируются.

Предполагается, что это продвинутая модель, но IMO должна быть довольно распространенной ...

Комментарии кто-нибудь?

Ответы на вопрос(2)

MappingHandlerMapping), вы должны зарегистрировать это новое отображение немного по-другому в контексте приложения 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 составная часть.

 ori09 июн. 2012 г., 15:20
Это имеет смысл. Я попробую.

аннотация 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() {

Я бы подумал, что вам нужны отдельные URL для безопасности. Обычно с Spring Security вы помещаете все функции администратора в / admin и позволяете инфраструктуре управлять всем этим ...

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

Будет ли этого достаточно для ваших вариантов использования?

 ori09 июн. 2012 г., 15:17
Моя цель состояла в том, чтобы иметь программный доступ к механизму сопоставления, чтобы обеспечить соблюдение определенных ограничений. Фильтры, которые вы упомянули, ограничены свойствами запроса и, следовательно, не решают мою проблему.

Ваш ответ на вопрос