Spring-Social/Twitter ConnectController не отвечает на /connect?

ОК, поэтому я целую вечность дергал себя за волосы (по крайней мере, так кажется!), Пытаясь понять, что я делаю неправильно: у меня есть проект Java, в котором я хочу разрешить пользователям, которые входят в систему (через обычный Spring -Репозиторий с поддержкой JDBC безопасности), чтобы предоставить доступ к своей учетной записи Twitter моему приложению. Я зарегистрировал приложение в Twitter и т. д., и у меня есть секретные ключи и ключи доступа, а также все остальное, необходимое для тестирования, однако, несмотря на все прочитанные документы и все испробованные конфигурации, даже несмотря на то, что моя весенняя конфигурация создает ConnectController, всякий раз, когда я нажимаю /connect/twitter, я получаю a 404 (не найдено), хотя во время появления контекста в Tomcat не возникает абсолютно никаких ошибок, и все остальное работает нормально (т.е. все мои bean-компоненты создаются, и все представления/контроллеры работают и т. д.).

Насколько я понимаю, хотя я действительно борюсь с документацией Spring Social, тем более, что некоторые из показанных примеров работают только с определенными версиями! -- просто создание экземпляра этого контроллера должно позаботиться обо всем остальном -- но, может быть, я ошибаюсь???

Вот как выглядит мой конфиг -- да, он везде разный:

/WEB-INF/web.xml

<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd">
<web-app>
    <display-name>legototies</display-name>
    <servlet>
        <servlet-name>legototies</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>

    <servlet-mapping>
        <servlet-name>legototies</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>

    <!-- allow robots.txt -->
    <servlet-mapping>
        <servlet-name>default</servlet-name>
        <url-pattern>*.txt</url-pattern>
    </servlet-mapping>

    <!-- allow favicon.ico -->
    <servlet-mapping>
        <servlet-name>default</servlet-name>
        <url-pattern>*.ico</url-pattern>
    </servlet-mapping>

    <!-- allow everything under /static/ -->
    <servlet-mapping>
        <servlet-name>default</servlet-name>
        <url-pattern>/static/*</url-pattern>
    </servlet-mapping>

    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>

    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>
            /WEB-INF/applicationContext.xml,
            /WEB-INF/spring-security.xml
        </param-value>
    </context-param>

    <!-- Spring Security -->
    <filter>
        <filter-name>springSecurityFilterChain</filter-name>
        <filter-class>
            org.springframework.web.filter.DelegatingFilterProxy
        </filter-class>
    </filter>

    <filter-mapping>
        <filter-name>springSecurityFilterChain</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
</web-app>

/WEB-INF/legototies-servlet.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:mvc="http://www.springframework.org/schema/mvc"
    xsi:schemaLocation="
        http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd
        http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd">

    <context:component-scan base-package="com.lt" />

    <bean id="viewResolver"
        class="org.springframework.web.servlet.view.InternalResourceViewResolver" p:order="1">
        <property name="viewClass" value="org.springframework.web.servlet.view.JstlView" />
        <property name="prefix" value="/WEB-INF/jsp/" />
        <property name="suffix" value=".jsp" />
    </bean>
    <bean id="tilesviewResolver" class="org.springframework.web.servlet.view.tiles2.TilesViewResolver" p:order="0"/>

    <bean id="tilesConfigurer" class="org.springframework.web.servlet.view.tiles2.TilesConfigurer">
        <property name="definitions">
            <list>
                <value>/WEB-INF/tiles.xml</value>
            </list>
        </property>
    </bean>

</beans>

/WEB-INF/applicationContext.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:task="http://www.springframework.org/schema/task"
    xmlns:twitter="http://www.springframework.org/schema/social/twitter"
    xmlns:social="http://www.springframework.org/schema/social"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
       http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd
       http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-3.2.xsd
       http://www.springframework.org/schema/social/twitter http://www.springframework.org/schema/social/spring-social-twitter.xsd
       http://www.springframework.org/schema/social http://www.springframework.org/schema/social/spring-social-1.1.xsd">

    <!-- **** BEGIN: Config files **** -->
    <bean
        class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
        <property name="locations">
            <list>
                <value>classpath*:config/*.properties</value>
            </list>
        </property>
        <property name="ignoreResourceNotFound" value="true" />
    </bean>
    <!-- **** END: Config files **** -->

    <context:component-scan base-package="com.lt" />


    <!-- **** BEGIN: Database **** -->
    <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
        destroy-method="close">
        <property name="driverClassName" value="${database.driverClassName}" />
        <property name="url" value="${database.url}" />
        <property name="username" value="${database.username}" />
        <property name="password" value="${database.password}" />
        <property name="initialSize" value="${database.initial.size}" />
        <property name="maxActive" value="${database.max.active}" />
    </bean>
    <bean id="localJdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
        <constructor-arg>
            <ref bean="dataSource" />
        </constructor-arg>
    </bean>

    <bean id="txManager"
        class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource" />
    </bean>

    <bean id="sessionFactory"
        class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
        <property name="configLocation">
            <value>classpath:hibernate.cfg.xml</value>
        </property>
    </bean>
    <!-- **** END: Database **** -->


    <bean id="messageAssembler" class="com.lt.message.MessageAssembler" />


    <!-- **** BEGIN: Scheduler **** -->
    <!-- Tasks -->
    <bean id="createTweetsScheduler" class="com.lt.scheduller.CreateTweetsScheduler">
        <constructor-arg index="0" ref="sessionFactory" />
        <constructor-arg index="1" ref="execSendTweet" />
        <constructor-arg index="2" ref="messageAssembler" />
    </bean>
    <bean id="bookScrapingNeededTask" class="com.lt.scheduller.BooksScrapingNeededCheckTask">
        <constructor-arg index="0" ref="sessionFactory" />
        <constructor-arg index="1" ref="execPageScraping" />
        <constructor-arg index="2" value="${shefari.htmlpath}" />
    </bean>

    <!-- Schedulers -->
    <task:executor id="execPageScraping" pool-size="${page.scrape.threadpool.size}" />
    <task:executor id="execSendTweet" pool-size="${broadcastTweets.threadpool.size}" />

    <task:scheduler id="mainScheduler" pool-size="${mainScheduler.size}" />
    <task:scheduled-tasks scheduler="mainScheduler">
        <task:scheduled ref="createTweetsScheduler" method="run"
            fixed-rate="${selectTweets.period.ms}" initial-delay="${selectTweets.initial.delay.ms}" />
        <task:scheduled ref="bookScrapingNeededTask" method="run"
            fixed-rate="${page.scrape.check.period.ms}" initial-delay="${page.scrape.check.initial.delay.ms}" />
    </task:scheduled-tasks>
    <!-- **** END: Scheduler **** -->


    <bean id="textEncryptor" class="org.springframework.security.crypto.encrypt.Encryptors"
        factory-method="noOpText" />
    <bean id="passwordEncoder"
        class="org.springframework.security.crypto.password.NoOpPasswordEncoder"
        factory-method="getInstance" />


    <!-- **** BEGIN: twitter/social **** -->
    <social:jdbc-connection-repository />
    <twitter:config app-id="${twitter.app.consumer.key}"
        app-secret="${twitter.app.consumer.secret}" />
    <bean id="userIdSource"
        class="org.springframework.social.security.AuthenticationNameUserIdSource" />
    <bean id="connectController"
        class="org.springframework.social.connect.web.ConnectController">
        <property name="connectInterceptors">
            <list>
                <bean class="com.lt.utils.TweetAfterConnectInterceptor">
                    <constructor-arg index="0" value="${twitter.app.connect.msg}" />
                </bean>
            </list>
        </property>
        <property name="applicationUrl" value="http://localhost:8080/" />
    </bean>
    <!-- **** END: twitter/social **** -->
</beans>

/WEB-INF/spring-security.xml

<beans:beans xmlns="http://www.springframework.org/schema/security"
    xmlns:beans="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
    http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.1.xsd">

    <global-method-security secured-annotations="enabled" />

    <http auto-config="true" use-expressions="true">
        <intercept-url pattern="/static/**" access="permitAll" />
        <intercept-url pattern="/home" access="permitAll" />
        <intercept-url pattern="/**" access="hasRole('ROLE_USER')" />
    </http>

    <authentication-manager>
        <authentication-provider>
            <jdbc-user-service data-source-ref="dataSource"

           users-by-username-query="select username,password, enabled from users where username=?" 

           authorities-by-username-query="select u.username, ur.authority from users u, user_roles ur 
              where u.id = ur.user_id and u.username =?  " 

            />
        </authentication-provider>
    </authentication-manager>
</beans:beans>

Я не включаю здесь /WEB-INF/tiles.xml, так как не думаю, что это актуально — он просто определяет некоторые основные шаблоны.

Наконец, это проект pom.xml — обратите внимание, что я использую последнюю весеннюю веху социальных сетей (M4):

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>liviutudor</groupId>
    <artifactId>legototies</artifactId>
    <packaging>war</packaging>
    <version>1.0.0-SNAPSHOT</version>
    <name>legototies</name>
    <inceptionYear>2013</inceptionYear>
    <description>This is "lego toties"</description>
    <url>http://legototies.com</url>
    <developers>
        <developer>
            <name>Liviu Tudor</name>
            <id>liviut</id>
            <email>me at liviutudor.com</email>
        </developer>
    </developers>
    <repositories>
        <repository>
            <snapshots>
                <enabled>false</enabled>
            </snapshots>
            <id>central</id>
            <name>Maven Repository Switchboard</name>
            <url>http://repo1.maven.org/maven2</url>
        </repository>
        <repository>
            <id>spring-snapshots</id>
            <name>Spring Snapshots</name>
            <url>http://repo.spring.io/snapshot</url>
            <snapshots>
                <enabled>true</enabled>
            </snapshots>
        </repository>
        <repository>
            <id>spring-milestones</id>
            <name>Spring Milestones</name>
            <url>http://repo.spring.io/milestone</url>
            <snapshots>
                <enabled>false</enabled>
            </snapshots>
        </repository>
    </repositories>

    <properties>
        <project.build.jdkVersion>1.6</project.build.jdkVersion>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>

        <hibernate.version>3.6.10.Final</hibernate.version>
        <jsoup.version>1.7.2</jsoup.version>
        <junit.version>4.10</junit.version>
        <spring.version>3.2.3.RELEASE</spring.version>
        <spring.social.version>1.1.0.M4</spring.social.version>
        <spring.security.version>3.1.4.RELEASE</spring.security.version>
        <tiles.version>2.2.2</tiles.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>servlet-api</artifactId>
            <version>2.5</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>jstl</artifactId>
            <version>1.2</version>
        </dependency>

        <!-- Spring -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-core</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-aop</artifactId>
            <version>${spring.version}</version>
            <exclusions>
                <exclusion>
                    <groupId>commons-logging</groupId>
                    <artifactId>commons-logging</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-jdbc</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-orm</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-web</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>${spring.version}</version>
            <exclusions>
                <exclusion>
                    <groupId>commons-logging</groupId>
                    <artifactId>commons-logging</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>${spring.version}</version>
        </dependency>

        <!-- Spring security -->
        <dependency>
            <groupId>org.springframework.security</groupId>
            <artifactId>spring-security-core</artifactId>
            <version>${spring.security.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.security</groupId>
            <artifactId>spring-security-web</artifactId>
            <version>${spring.security.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.security</groupId>
            <artifactId>spring-security-config</artifactId>
            <version>${spring.security.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.security</groupId>
            <artifactId>spring-security-taglibs</artifactId>
            <version>${spring.security.version}</version>
        </dependency>
        <dependency> <!-- needed by spring social twitter -->
            <groupId>org.springframework.security</groupId>
            <artifactId>spring-security-crypto</artifactId>
            <version>${spring.security.version}</version>
        </dependency>
        <!-- Spring Social -->
        <dependency>
            <groupId>org.springframework.social</groupId>
            <artifactId>spring-social-twitter</artifactId>
            <version>${spring.social.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.social</groupId>
            <artifactId>spring-social-web</artifactId>
            <version>${spring.social.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.social</groupId>
            <artifactId>spring-social-security</artifactId>
            <version>${spring.social.version}</version>
        </dependency>

        <!-- Hibernate -->
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-core</artifactId>
            <version>${hibernate.version}</version>
        </dependency>
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-entitymanager</artifactId>
            <version>${hibernate.version}</version>
        </dependency>
        <dependency>
            <groupId>org.hibernate.javax.persistence</groupId>
            <artifactId>hibernate-jpa-2.0-api</artifactId>
            <version>1.0.0.Final</version>
        </dependency>
        <!-- this is needed for hibernate -->
        <dependency>
            <groupId>javassist</groupId>
            <artifactId>javassist</artifactId>
            <version>3.12.0.GA</version>
        </dependency>

        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.0.5</version>
        </dependency>

        <dependency>
            <groupId>commons-dbcp</groupId>
            <artifactId>commons-dbcp</artifactId>
            <version>1.4</version>
        </dependency>

        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-lang3</artifactId>
            <version>3.1</version>
        </dependency>

        <dependency>
            <groupId>org.jsoup</groupId>
            <artifactId>jsoup</artifactId>
            <version>${jsoup.version}</version>
        </dependency>

        <dependency>
            <groupId>org.apache.tiles</groupId>
            <artifactId>tiles-extras</artifactId>
            <version>${tiles.version}</version>
        </dependency>

        <!-- Test dependencies -->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>${junit.version}</version>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-test</artifactId>
            <version>${spring.version}</version>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <finalName>legototies</finalName>
        <defaultGoal>install</defaultGoal>
        <resources>
            <resource>
                <filtering>false</filtering>
                <directory>src/main/java</directory>
                <includes>
                    <include>**/*.properties</include>
                    <include>**/*.xml</include>
                </includes>
            </resource>
            <resource>
                <filtering>false</filtering>
                <directory>src/main/resources</directory>
                <includes>
                    <include>**/*.properties</include>
                    <include>**/*.xml</include>
                </includes>
            </resource>
        </resources>
        <plugins>
            <plugin>
                <artifactId>maven-compiler-plugin</artifactId>
                <configuration>
                    <source>${project.build.jdkVersion}</source>
                    <target>${project.build.jdkVersion}</target>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-resources-plugin</artifactId>
                <configuration>
                    <encoding>${project.build.sourceEncoding}</encoding>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

Как я уже сказал, все работает просто отлично, однако, учитывая вышеизложенное, даже если определено ConnectController, /connect/twitter (или любой другой URL-адрес /connect/...) возвращает 404 не найдено. Что мне не хватает?

Обновление: сегмент журнала, касающийся контроллера подключения

5148 [main] INFO org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping - Mapped "{[/connect/{providerId}],methods=[POST],params=[],headers=[],consumes=[],produces=[],custom=[]}" onto public org.springframework.web.servlet.view.RedirectView org.springframework.social.connect.web.ConnectController.connect(java.lang.String,org.springframework.web.context.request.NativeWebRequest)
5148 [main] INFO org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping - Mapped "{[/connect/{providerId}],methods=[DELETE],params=[],headers=[],consumes=[],produces=[],custom=[]}" onto public org.springframework.web.servlet.view.RedirectView org.springframework.social.connect.web.ConnectController.removeConnections(java.lang.String,org.springframework.web.context.request.NativeWebRequest)
5148 [main] INFO org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping - Mapped "{[/connect/{providerId}/{providerUserId}],methods=[DELETE],params=[],headers=[],consumes=[],produces=[],custom=[]}" onto public org.springframework.web.servlet.view.RedirectView org.springframework.social.connect.web.ConnectController.removeConnection(java.lang.String,java.lang.String,org.springframework.web.context.request.NativeWebRequest)
5149 [main] INFO org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping - Mapped "{[/connect/{providerId}],methods=[GET],params=[],headers=[],consumes=[],produces=[],custom=[]}" onto public java.lang.String org.springframework.social.connect.web.ConnectController.connectionStatus(java.lang.String,org.springframework.web.context.request.NativeWebRequest,org.springframework.ui.Model)
5150 [main] INFO org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping - Mapped "{[/connect],methods=[GET],params=[],headers=[],consumes=[],produces=[],custom=[]}" onto public java.lang.String org.springframework.social.connect.web.ConnectController.connectionStatus(org.springframework.web.context.request.NativeWebRequest,org.springframework.ui.Model)
5150 [main] INFO org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping - Mapped "{[/connect/{providerId}],methods=[GET],params=[oauth_token],headers=[],consumes=[],produces=[],custom=[]}" onto public org.springframework.web.servlet.view.RedirectView org.springframework.social.connect.web.ConnectController.oauth1Callback(java.lang.String,org.springframework.web.context.request.NativeWebRequest)
5151 [main] INFO org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping - Mapped "{[/connect/{providerId}],methods=[GET],params=[code],headers=[],consumes=[],produces=[],custom=[]}" onto public org.springframework.web.servlet.view.RedirectView org.springframework.social.connect.web.ConnectController.oauth2Callback(java.lang.String,org.springframework.web.context.request.NativeWebRequest)
5152 [main] INFO org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping - Mapped "{[/connect/{providerId}],methods=[GET],params=[error],headers=[],consumes=[],produces=[],custom=[]}" onto public org.springframework.web.servlet.view.RedirectView org.springframework.social.connect.web.ConnectController.oauth2ErrorCallback(java.lang.String,java.lang.String,java.lang.String,java.lang.String,org.springframework.web.context.request.NativeWebRequest)

person Liv    schedule 23.10.2013    source источник
comment
Кстати, значение для http://localhost:8080 в определении ConnectController установлено только для целей локального тестирования, чтобы убедиться, что это не вызывает никаких проблем.   -  person Liv    schedule 24.10.2013
comment
На самом деле я думаю, что проблема может быть с элементом <twitter:config>, поскольку я только что понял, что /connect/ сам по себе как путь работает, но /connect/<service> -- например. /connect/twitter -- возвращает 404.   -  person Liv    schedule 26.10.2013
comment
Просто хедз-ап для всех, кто ответил на это: большое вам спасибо! Я был занят и не смог проверить это, но потрачу время на выходных и выберу лучший ответ к воскресенью/понедельнику. (Я тоже в Калифорнии, так что часовой пояс PST просто для сравнения).   -  person Liv    schedule 02.11.2013
comment
Итак, я боюсь, что пока не могу присудить награду кому-либо :( На самом деле рад удвоить награду, если это возможно, пока я разбираюсь с этим. Теперь я действительно думаю, что проблема с <twitter:config> - кажется, что ConnectController запускается, но не регистрирует твиттер-сервис (и да, приложения/секретные ключи валидны, они прекрасно работают в отдельной ветке с библиотекой Twitter4J, так что дело не в этом)! вещь, которая связывает контроллер с сервисом Twitter... есть идеи?   -  person Liv    schedule 02.11.2013
comment
Вы используете плитки для разрешения представлений, убедитесь, что плитки знают, какие представления разрешать.   -  person M. Deinum    schedule 04.11.2013
comment
@М. Deinum, обратите внимание, что есть 2 распознавателя представлений, взвешенных по-разному, сначала будут распознаватели тайлов, а затем возвращаются к jsp. Разрешение представления отлично работает для всех остальных путей, кроме /connect/..., так что это не может быть так.   -  person Liv    schedule 05.11.2013
comment
Я полностью пропустил InternalResourceViewResolver, наверное, мне нужны новые очки :s   -  person M. Deinum    schedule 05.11.2013
comment
Обновление: см. мой разговор здесь: chat.stackoverflow.com/rooms/41225/ похоже, возникла проблема с настройкой bean-компонента connectionRepository, из-за чего #{request.userPrincipal.name} выдает исключение...   -  person Liv    schedule 16.11.2013


Ответы (4)


Ваш ConnectController находится в неправильном файле конфигурации. Вы должны переместить его в папку legototies-servlet.xml.

Используемые реализации HandlerMapping обнаруживают только компоненты (@)Controller в локальном контексте (тот, который загружен DispatcherServlet), а НЕ в родительском контексте (загруженном ContextLoaderListener). Итак, ваш ConnectController настроен, но ничего не делает, потому что не обнаружен.

Есть еще одна проблема с вашей конфигурацией, вы загружаете все bean-компоненты дважды. Это связано с тем, как вы настроили сканирование компонентов. В обоих файлах конфигурации есть <context:component-scan base-package="com.lt" />, который в основном дублирует все bean-компоненты. В общем, вы должны настроить DispatcherServlet для загрузки только @Controllers и ContextLoaderListener для загрузки всего, НО @Controllers.

<context:component-scan base-package="com.lt">
    <context:exclude-filter type="annotation" value="org.springframework.stereotype.Controller" />
</context:component-scan>

и для DispatcherServlet

<context:component-scan base-package="com.lt" use-default-filters="false">
    <context:include-filter type="annotation" value="org.springframework.stereotype.Controller" />
</context:component-scan>

И на первый взгляд у вас тоже ошибка в конфигурации базы данных. Вы используете спящий режим, но настроили DataSourceTransactionManager, тогда как вам следует настроить HibernateTransactionManager. Последний вполне способен управлять простыми транзакциями JDBC.

person M. Deinum    schedule 30.10.2013
comment
просто попробуйте это - в качестве предупреждения, пример, который вы привели, немного неверен: для <context:exclude-filter> и <context:include-filter> атрибут не value=..., а expression=... - person Liv; 02.11.2013
comment
добавив <connect:include-filter> в applicationContext.xml и <connect:exclude-filter> в legototies-servlet.xml, я все еще вижу точно такой же результат - 404 везде! :( Значит не то :( - person Liv; 02.11.2013
comment
Также я переместил ‹context:component-scan› полностью в legototies-servlet.xml с тем же результатом :( - person Liv; 02.11.2013
comment
Ошибка в том, что ваш ConnectController находится в неправильном контексте и не обнаружен, другие - это предложения по улучшению вашего контекста (вероятно, нужно было указать это в комментарии). Чтобы получить представление о том, что происходит, включите ведение журнала DEBUG для org.springframework.web (и, возможно, org.springframework.social), и вы должны получить больше информации о том, что происходит не так. - person M. Deinum; 04.11.2013
comment
Хорошо, я думаю, мне следует настроить расширенное ведение журнала отладки и просмотреть его построчно. Но в качестве предупреждения, простое объявление контроллера подключения в отдельном файле не имело никакого значения. (Мне нужно также переместить все, что связано с конфигурацией твиттера, в legototies-servlet.xml?) - person Liv; 05.11.2013
comment
Перемещение его в другой файл не имеет значения, он должен быть загружен DispatcherServlet, чтобы быть обнаруженным. Пока этого не происходит, контроллер практически не обнаруживается. - person M. Deinum; 05.11.2013
comment
Я сделаю это, как только настрою его и запущу - в настоящее время, будучи в спешке, я не настроил ведение журнала, поэтому просто настроил на нем SLF5J. - person Liv; 05.11.2013
comment
Только что получил дамп журнала - я обновляю основную часть этого. - person Liv; 06.11.2013
comment
На самом деле оказалось, что файл журнала слишком велик и не может добавить его к основному тексту :( Я не вижу там ничего о весенних социальных сетях, я должен сказать - в частности, нет никакой ссылки на Твиттер! Я вижу Контроллер подключения инициализирован и правильно отображает данные, но я вернулся к своему первому выводу, что бит твиттера на самом деле никогда не работает. - person Liv; 06.11.2013
comment
Дерьмо! Я тоже не могу добавить сюда несколько строк лога :( блин! - person Liv; 06.11.2013
comment
Вы можете выложить его на pastebin и разместить здесь ссылку. Что меня интересует, так это то, что происходит, когда запрос обрабатывается DispatcherServlet, потому что с моей точки зрения это все еще выглядит так, как будто контроллер не вызывается. - person M. Deinum; 06.11.2013
comment
Кстати, когда я получаю доступ к чему-либо под /connect/*, нет регистрации. - person Liv; 08.11.2013
comment
Должна быть какая-то регистрация DispatcherServlet получения и обработки запроса. Вы только добавили журнал запуска, мне было бы интересно увидеть журнал входящего запроса. Журнал, по крайней мере, показывает, что контроллер обнаружен и зарегистрирован. - person M. Deinum; 08.11.2013
comment
Я проверял и проверял еще раз, как только это начнется, это все, что я получаю в журнале: O доступ к любому URL-адресу ничего не отображает в консоли... Вот мой log4j.xml файл: pastebin.com/xUpea0Xu - person Liv; 15.11.2013
comment
Тогда либо у вас проблема с конфигурацией ведения журнала, либо ваш DispatcherServlet вообще ничего не делает. - person M. Deinum; 15.11.2013
comment
Я слышу вас... если диспетчер ничего не сделал, то почему он направляет запросы на /signup, /books/ и т. д. правильному контроллеру? : O Нажатие на те URL-адреса, которые отображаются в журналах (например, /in/books и т. Д.), Определенно заканчиваются на правильной странице ... хотя ведение журнала не создается : O - person Liv; 15.11.2013
comment
Это довольно просто: O pastebin.com/xUpea0Xu Он передается tomcat как -Dlog4j.configuration.file=file:/.... - person Liv; 15.11.2013
comment
Ну, вы должны хотя бы видеть, что DispatcherServlet обрабатывает запрос. Попробуйте включить ведение журнала trace для org.springframework.web. Но, как уже упоминалось, вы уже должны что-то увидеть. - person M. Deinum; 15.11.2013
comment
давайте продолжим это обсуждение в чате - person Liv; 15.11.2013
comment
Всем, кто следил за этим, я, кажется, нашел проблему - см. мой собственный ответ ниже. Я посмотрю, смогу ли я наградить @M. Deinum несколько баллов за все его текущие предложения. - person Liv; 16.11.2013
comment
Чем больше я вникал в это, тем больше вы были правы в том, что контроллер находится в неправильном конфигурационном файле и во многих других вещах, поэтому я награждаю вас этой наградой. - person Liv; 22.11.2013

Здесь вам нужно переопределить некоторые методы из ConnectController. Здесь я даю вам фрагмент кода (с комментариями), который может быть вам полезен. Представление по умолчанию для ConnectController — это /connect/{providerID}Connected — после авторизации и подключения и /connect/{providerID}Connect — после отключения это представление по умолчанию. Вы получаете ошибку 404, потому что у вас нет папки подключения и twitterConnected.jsp внутри нее. Просто для проверки создайте папку подключения и поместите в нее 1.twitterConnected.jsp и 2.twitterConnect.jsp и попробуйте подключить ее, прежде чем создавать подкласс ConnectController, как показано ниже.

@Controller
public class CustomConnectController extends ConnectController {
    @Inject
    public CustomConnectController(
            ConnectionFactoryLocator connectionFactoryLocator,
            ConnectionRepository connectionRepository) {
        super(connectionFactoryLocator, connectionRepository);
    }
    //This connectedView will be called after user authorize twitter app.  So here you can redirect   
    //users to the page you need.
    @Override
    protected String connectedView(String providerId){
        return "redirect:/user/profile";
    }
    //This connectView will be called if user disconnect from social media.  Here you can redirect 
    //them once they got disconnected.  
    @Override
    protected String connectView(String providerId) {
        return "redirect:/connect";
    }
}

Просто попробуйте и дайте мне знать ваш результат.

person Vignesh Gopalakrishnan    schedule 31.10.2013
comment
Смотрите мои комментарии выше, у меня ДЕЙСТВИТЕЛЬНО есть 2 взгляда, которые вы упомянули. Тем не менее, я закомментировал исходный ConnectController и реализовал предложенный вами вариант. И все еще нажатие /connect/twitterConnect отображает 404. (хотя bean-компонент контроллера создается, но, похоже, ничего не делает!) - person Liv; 02.11.2013

1) Идет поверх web.xml (вы хотите, чтобы фильтр безопасности был первым, кто получил запрос)

 <filter>
        <filter-name>springSecurityFilterChain</filter-name>
        <filter-class>
            org.springframework.web.filter.DelegatingFilterProxy
        </filter-class>
    </filter>

    <filter-mapping>
        <filter-name>springSecurityFilterChain</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

2) вы используете плитки, поэтому вы не будете использовать преобразователь представления jsp. изменить его на

<bean id="viewResolver"
        class="org.springframework.web.servlet.view.UrlBasedViewResolver">
        <property name="viewClass"
            value="org.springframework.web.servlet.view.tiles2.TilesView" />
    </bean>

3) имя сервлета должно соответствовать имени файла конфигурации сервлета.

EDIT: Также правильный способ загрузки контекста

  <servlet>
            <servlet-name>appServlet</servlet-name>
            <servlet-class>org.springframework.web.servlet.DispatcherServlet
            </servlet-class>
            <init-param>
                <param-name>contextConfigLocation</param-name>
                <param-value>/WEB-INF/appServlet-context.xml</param-value>
            </init-param>
            <load-on-startup>1</load-on-startup>
        </servlet>

измените appServlet на файл конфигурации вашего сервлета.

person kyla    schedule 01.11.2013
comment
Не могли бы вы также опубликовать свой контроллер? - person kyla; 01.11.2013
comment
у вас настроен преобразователь представления плиток, а также преобразователь представления jsp. скажем, вы возвращаете имя представления (индекс) в свой контроллер, когда запрос приходит как подключение/твиттер, поэтому здесь происходит одна из вещей: он либо идет и пытается найти (вtiles.xml) ‹definition name=index ...› , или преобразователь представления jsp добавит /WEB-INF/jsp/index.jsp. Итак, для вас приложение, которое подходит? Удалите другой (используйте только один). - person kyla; 04.11.2013
comment
Пожалуйста, смотрите мой комментарий выше, у вас может быть 2 преобразователя представлений, они взвешиваются по-разному, поэтому они связаны. - person Liv; 05.11.2013
comment
поскольку вы пытаетесь использовать несколько преобразователей представлений, вот сообщение об этом stackoverflow.com/questions/1029193/ - person kyla; 05.11.2013
comment
Спасибо, похоже, что он основан на более старой библиотеке Spring. Использованное выше пространство имен p обеспечивает то же самое: docs.spring.io/spring/docs/3.0.x/spring-framework-reference/ - person Liv; 05.11.2013

Итак, я заставил его работать, хотя почему-то до сих пор не уверен, в чем проблема - я думаю, что это где-то между проблемой с тегами Spring «ярлык» и неправильно настроенным путем безопасности. Итак, получается, что мой spring-security разрешил незарегистрированный доступ к /connect/...., после чего #{request.userPrincipal.name} неправильно оценил и выдал исключение. Будучи весной, без включения ведения журнала, я никогда этого не замечал, и все тихо терпело неудачу. Перенастроив всю твиттер/социальную поддержку следующим образом:

    <bean id="connectionFactoryLocator"
        class="org.springframework.social.connect.support.ConnectionFactoryRegistry">
        <property name="connectionFactories">
            <list>
                <ref bean="twitterConnectFactory" />
            </list>
        </property>
    </bean>
    <bean id="twitterConnectFactory" class="org.springframework.social.twitter.connect.TwitterConnectionFactory">
        <constructor-arg value="${twitter.app.consumer.key}" />
        <constructor-arg value="${twitter.app.consumer.secret}" />
    </bean> 

    <bean id="usersConnectionRepository"
        class="org.springframework.social.connect.jdbc.JdbcUsersConnectionRepository">
        <constructor-arg ref="dataSource" />
        <constructor-arg ref="connectionFactoryLocator" />
        <constructor-arg ref="textEncryptor" />
    </bean>

    <bean id="connectionRepository" factory-method="createConnectionRepository"
        factory-bean="usersConnectionRepository" scope="request">
        <constructor-arg value="#{request.userPrincipal.name}" />
        <aop:scoped-proxy proxy-target-class="false" />
    </bean>

Также был настроен контроллер подключения:

<bean id="connectController"
    class="org.springframework.social.connect.web.ConnectController">
    <constructor-arg ref="connectionFactoryLocator" />
    <constructor-arg ref="connectionRepository" />
    <property name="connectInterceptors">
        <list>
            <bean class="com.lt.utils.TweetAfterConnectInterceptor">
                <constructor-arg index="0" value="${twitter.app.connect.msg}" />
            </bean>
        </list>
    </property>
</bean>

И внес изменения в мою весеннюю безопасность, чтобы пользователь действительно вошел в систему, чтобы получить доступ к URL-адресам /connect..., теперь это работает. Я также не использовал настраиваемый контроллер подключения, как предлагается здесь, и полагался на стандартный. Вот мой spring-security.xml для справки:

<beans:beans xmlns="http://www.springframework.org/schema/security"
    xmlns:beans="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
    http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.1.xsd">

    <global-method-security secured-annotations="enabled" />

    <http auto-config="true" use-expressions="true">
        <intercept-url pattern="/in/**" access="hasRole('ROLE_USER')" />
        <intercept-url pattern="/connect" access="hasRole('ROLE_USER')" />
        <intercept-url pattern="/connect/**" access="hasRole('ROLE_USER')" />
        <intercept-url pattern="/*" access="permitAll" />
        <intercept-url pattern="/static/**" access="permitAll" />
        <intercept-url pattern="/login" access="permitAll" />
        <intercept-url pattern="/loginfailed" access="permitAll" />


        <form-login login-page="/login" default-target-url="/" authentication-failure-url="/loginfailed" />
        <logout logout-success-url="/logout" />
    </http>

    <authentication-manager>
        <authentication-provider>
            <jdbc-user-service data-source-ref="dataSource"
                users-by-username-query="select username,password, enabled from users where username=?"
                authorities-by-username-query="select u.username, ur.authority from users u, user_roles ur 
              where u.id = ur.user_id and u.username =?" />
        </authentication-provider>
    </authentication-manager>
</beans:beans>
person Liv    schedule 16.11.2013