PagedResourcesAssembler instanciation impossible
Bonjour,
Je souhaite utiliser la pagination de Spring mais j'ai une exception lors de l'instanciation de PagedResourcesAssembler à l'appel de ma méthode REST:
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
|
GRAVE: Servlet.service() for servlet [servlet-dispatcher] in context with path [/RestSpringToken] threw exception [Request processing failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.data.web.PagedResourcesAssembler]: No default constructor found; nested exception is java.lang.NoSuchMethodException: org.springframework.data.web.PagedResourcesAssembler.<init>()] with root cause
java.lang.NoSuchMethodException: org.springframework.data.web.PagedResourcesAssembler.<init>()
at java.lang.Class.getConstructor0(Class.java:3082)
at java.lang.Class.getDeclaredConstructor(Class.java:2178)
at org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:104)
at org.springframework.web.method.annotation.ModelAttributeMethodProcessor.createAttribute(ModelAttributeMethodProcessor.java:137)
at org.springframework.web.servlet.mvc.method.annotation.ServletModelAttributeMethodProcessor.createAttribute(ServletModelAttributeMethodProcessor.java:80)
at org.springframework.web.method.annotation.ModelAttributeMethodProcessor.resolveArgument(ModelAttributeMethodProcessor.java:106)
at org.springframework.web.method.support.HandlerMethodArgumentResolverComposite.resolveArgument(HandlerMethodArgumentResolverComposite.java:78)
at org.springframework.web.method.support.InvocableHandlerMethod.getMethodArgumentValues(InvocableHandlerMethod.java:162)
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:129)
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:110)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:806)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:729)
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:85)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:959)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:893)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:970)
at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:861)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:624) |
Voici mon pom.xml:
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177
|
<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>TestAngularRestToken</groupId>
<artifactId>TestAngularRestToken</artifactId>
<packaging>war</packaging>
<version>0.0.1-SNAPSHOT</version>
<name>TestAngularRestToken Maven Webapp</name>
<url>http://maven.apache.org</url>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.5</version>
<scope>compile</scope>
</dependency>
<!-- Utilisation de cette bibliothèque pour jeton JWT -->
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>0.7.0</version>
</dependency>
<!-- Utilisation de Spring (on indique ici toutes les dépendances car spring-security contient aussi
des dépendances vers des jars de Spring - exemple: spring-core est référencée par spring-orm dans une
version 4.x ici mais aussi par spring-security-core dans sa version 3.2.x ici - donc en les indiquant
on indique explicitement quelle version Maven va considérer) -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>4.2.2.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>4.2.2.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>4.2.2.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>4.2.2.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>4.2.2.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>4.2.2.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-expression</artifactId>
<version>4.2.2.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>4.2.2.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>4.2.2.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.hateoas</groupId>
<artifactId>spring-hateoas</artifactId>
<version>0.21.0.RELEASE</version>
</dependency>
<!-- Permet de créer HibernateAwareObjectMapper -->
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-hibernate4</artifactId>
<version>2.8.2</version>
</dependency>
<!-- Utilisation de Spring Security -->
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-core</artifactId>
<version>4.0.0.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-web</artifactId>
<version>4.0.0.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-config</artifactId>
<version>4.0.0.RELEASE</version>
</dependency>
<!-- Utilisation de JpaRepository -->
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-jpa</artifactId>
<version>1.8.0.RELEASE</version>
</dependency>
<!-- Utilisation de Swagger -->
<!-- <dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-common</artifactId>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-spring-web</artifactId>
</dependency> -->
<!-- Pour interraction BD -->
<dependency>
<groupId>org.hsqldb</groupId>
<artifactId>hsqldb</artifactId>
<version>2.3.1</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-orm</artifactId>
<version>4.2.2.RELEASE</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-entitymanager</artifactId>
<version>4.3.4.Final</version>
</dependency>
</dependencies>
<build>
<finalName>TestAngularRestToken</finalName>
</build>
</project> |
Voici ma config xml:
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99
|
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:jpa="http://www.springframework.org/schema/data/jpa"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:security="http://www.springframework.org/schema/security"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security.xsd
http://www.springframework.org/schema/data/jpa
http://www.springframework.org/schema/data/jpa/spring-jpa.xsd">
<jpa:repositories base-package="com.testAngularRestToken.dao" />
<context:component-scan base-package="com.testAngularRestToken" />
<tx:annotation-driven transaction-manager="transactionManager" />
<mvc:annotation-driven>
<mvc:message-converters>
<bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
<property name="objectMapper">
<!-- Utilisation de notre HibernateAware mapper à la place de celui par défaut -->
<bean class="com.testAngularRestToken.objectMapper.HibernateAwareObjectMapper" />
</property>
</bean>
</mvc:message-converters>
<!-- Ajout pour utiliser le Pageable -->
<mvc:argument-resolvers>
<bean class="org.springframework.data.web.PageableHandlerMethodArgumentResolver" />
</mvc:argument-resolvers>
</mvc:annotation-driven>
<!-- Le bean "JndiObjectFactoryBean" permet de déclarer l'utilisation de la ressource JDBC. -->
<bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName" value="java:comp/env/jdbc/dsMonApplication" />
</bean>
<!-- Le bean "LocalContainerEntityManagerFactoryBean" utilise la ressource JDBC et le fichier
"persistence.xml" pour aboutir à la création du "EntityManager" qui est utilisé dans la DAO.
"persistenceUnit" correspond à ce qui est défini dans persistence.xml. -->
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="persistenceUnitName" value="myPersistenceUnit" />
<property name="dataSource" ref="dataSource" />
</bean>
<!-- Le bean "JpaTransactionManager" permet d'instancier le gestionnaire de transaction et lui associer la
fabrique de "EntityManager" -->
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>
<!-- Configuration de sping-security -->
<!-- Activation des annotations @PreFilter, @PreAuthorize, @PostFilter, @PostAuthorize sur chaque bean de
Spring -->
<security:global-method-security pre-post-annotations="enabled" />
<!-- On indique que pour "/rest/authentication", il n'y a pas de sécurité (tout le monde peut appeler pour
s'authentifier). -->
<security:http pattern="/rest/authentication" security="none"/>
<!-- On indique le point d'entrée lors d'un appel à tous les services REST (sauf celui déclaré juste
avant sur lequel on ne veut pas de sécurité). "stateless" indique qu'on ne veut pas de session
créée pour la sécurité vu que l'on utilise des token pour chaque requête. -->
<security:http pattern="/rest/**" entry-point-ref="restAuthenticationEntryPoint" create-session="stateless">
<!-- Nous n'avons pas besoin de protection csrf car le token est immunisé à ca. -->
<security:csrf disabled="true"/>
<!-- On indique que l'on utilise un filtre customisé référencé par "jwtAuthenticationFilter" (défini
plus bas). Il sera placé avant le filtre pour le formulaire de login dans la chaine des filtres
prédéfinis dans Spring. -->
<security:custom-filter before="FORM_LOGIN_FILTER" ref="jwtAuthenticationFilter"/>
</security:http>
<!-- On indique où se trouve notre filtre qui sera géré comme un bean par Spring. -->
<bean id="jwtAuthenticationFilter" class="com.testAngularRestToken.filter.JwtAuthenticationFilter">
<property name="authenticationManager" ref="authenticationManager" />
<property name="authenticationSuccessHandler" ref="jwtAuthenticationSuccessHandler" />
</bean>
<!-- On défini le "authenticationManager" qui va s'appuyer sur notre classe "JwtAuthenticationProvider". -->
<security:authentication-manager alias="authenticationManager">
<security:authentication-provider ref="jwtAuthenticationProvider" />
</security:authentication-manager>
<!-- Ajouts suivants pour le Pageable -->
<!-- On active le support Spring Data Web (utile pour Pageable notamment) -->
<bean class="org.springframework.data.web.config.SpringDataWebConfiguration" />
</beans> |
Voici le code:
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
|
@RequestMapping(method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
public PagedResources<ContractResource> listContracts(Pageable pageRequest, PagedResourcesAssembler<Contract> assembler) {
int pageNumber = pageRequest.getPageNumber();
int pageSize = pageRequest.getPageSize();
Sort sort = pageRequest.getSort();
// Appel le service.
Page<Contract> contractsList = contractsService.listContractsWithPagination(pageNumber, pageSize, sort);
// On demande la conversion en ressource grâce à l'assembleur de Spring demandé en paramètre
// du controlleur. On passe en paramètre la liste de Page recue par le service et notre assembleur
// entité/ressource.
return assembler.toResource(contractsList, contractResourceAssembler);
} |
Pouvez-vous m'aider svp?
Edit:
Problème résolut en changeant la config xml comme ca:
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130
|
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:jpa="http://www.springframework.org/schema/data/jpa"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:security="http://www.springframework.org/schema/security"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security.xsd
http://www.springframework.org/schema/data/jpa
http://www.springframework.org/schema/data/jpa/spring-jpa.xsd">
<!-- Active JpaRepository. On doit préciser le package où se trouve les repository. -->
<jpa:repositories base-package="com.testAngularRestToken.dao" />
<!-- Active la configuration par annotations (annotations utilisées dans les controlleurs par exemple).
Le package précisé sera scanné à la recherche des annotations Spring et les beans correspondants seront
chargés dans le contexte d'application avec un nom par défaut si aucun nom n'a été précisé (association
id avec classe).
INFO: La configuration par annotation évite de configurer les beans dans le XML comme ceci
<bean id="monId" class="package.MaClass">
<property name="attributeClass" value="valueAttribute" />
</bean>
"context" est référencée par "xmlns:context=...". -->
<context:component-scan base-package="com.testAngularRestToken" />
<!-- Permet de scanner tous les beans (exemple: Personne qui est déclaré comme entité) dans le contexte
d'application et de créer des intercepteurs AOP pour ceux qui sont annotés. "tx" est référencée par
"xmlns:tx=..." -->
<tx:annotation-driven transaction-manager="transactionManager" />
<!-- Permet d'enregistrer automatiquement un HTTPMessageConverter (pour conversion de et vers JSON) -->
<mvc:annotation-driven>
<!-- Ici on précise quel HTTPMessageConverter on veut -->
<mvc:message-converters>
<bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
<property name="objectMapper">
<!-- Utilisation de notre HibernateAware mapper à la place de celui par défaut -->
<bean class="com.testAngularRestToken.objectMapper.HibernateAwareObjectMapper" />
</property>
</bean>
</mvc:message-converters>
<!-- Ajout pour utiliser le Pageable -->
<mvc:argument-resolvers>
<ref bean="sortResolver"/>
<ref bean="pageableResolver" />
<ref bean="pagedResourcesAssemblerResolver" />
</mvc:argument-resolvers>
</mvc:annotation-driven>
<!-- Le bean "JndiObjectFactoryBean" permet de déclarer l'utilisation de la ressource JDBC. -->
<bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName" value="java:comp/env/jdbc/dsMonApplication" />
</bean>
<!-- Le bean "LocalContainerEntityManagerFactoryBean" utilise la ressource JDBC et le fichier
"persistence.xml" pour aboutir à la création du "EntityManager" qui est utilisé dans la DAO.
"persistenceUnit" correspond à ce qui est défini dans persistence.xml. -->
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="persistenceUnitName" value="myPersistenceUnit" />
<property name="dataSource" ref="dataSource" />
</bean>
<!-- Le bean "JpaTransactionManager" permet d'instancier le gestionnaire de transaction et lui associer la
fabrique de "EntityManager" -->
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>
<!-- Configuration de sping-security -->
<!-- Activation des annotations @PreFilter, @PreAuthorize, @PostFilter, @PostAuthorize sur chaque bean de
Spring -->
<security:global-method-security pre-post-annotations="enabled" />
<!-- On indique que pour "/rest/authentication", il n'y a pas de sécurité (tout le monde peut appeler pour
s'authentifier). -->
<security:http pattern="/rest/authentication" security="none"/>
<!-- On indique le point d'entrée lors d'un appel à tous les services REST (sauf celui déclaré juste
avant sur lequel on ne veut pas de sécurité). "stateless" indique qu'on ne veut pas de session
créée pour la sécurité vu que l'on utilise des token pour chaque requête. -->
<security:http pattern="/rest/**" entry-point-ref="restAuthenticationEntryPoint" create-session="stateless">
<!-- Nous n'avons pas besoin de protection csrf car le token est immunisé à ca. -->
<security:csrf disabled="true"/>
<!-- On indique que l'on utilise un filtre customisé référencé par "jwtAuthenticationFilter" (défini
plus bas). Il sera placé avant le filtre pour le formulaire de login dans la chaine des filtres
prédéfinis dans Spring. -->
<security:custom-filter before="FORM_LOGIN_FILTER" ref="jwtAuthenticationFilter"/>
</security:http>
<!-- On indique où se trouve notre filtre qui sera géré comme un bean par Spring. -->
<bean id="jwtAuthenticationFilter" class="com.testAngularRestToken.filter.JwtAuthenticationFilter">
<property name="authenticationManager" ref="authenticationManager" />
<property name="authenticationSuccessHandler" ref="jwtAuthenticationSuccessHandler" />
</bean>
<!-- On défini le "authenticationManager" qui va s'appuyer sur notre classe "JwtAuthenticationProvider". -->
<security:authentication-manager alias="authenticationManager">
<security:authentication-provider ref="jwtAuthenticationProvider" />
</security:authentication-manager>
<!-- Ajouts suivants pour le Pageable -->
<!-- On active le support Spring Data Web (utile pour Pageable notamment) -->
<bean class="org.springframework.data.web.config.SpringDataWebConfiguration" />
<!-- On créé les beans nécessaires pour la pagination en précisant parfois les arguments du constructeur si nécessaire.
Utilisation dans "mvc:argument-resolvers" qui sert à désigner des beans pour résoudre des arguments. -->
<bean id="sortResolver" class="org.springframework.data.web.HateoasSortHandlerMethodArgumentResolver" />
<bean id="pageableResolver" class="org.springframework.data.web.HateoasPageableHandlerMethodArgumentResolver">
<constructor-arg ref="sortResolver" />
</bean>
<bean id="pagedResourcesAssemblerResolver" class="org.springframework.data.web.PagedResourcesAssemblerArgumentResolver">
<constructor-arg ref="pageableResolver" />
<constructor-arg>
<!-- Deuxième argument null -->
<null />
</constructor-arg>
</bean>
</beans> |