Bonjour.
Pour un projet personnel, j'ai besoin de comprendre comment envoyer des requêtes d'un service Angular à un controller Spring MVC.
J'ai pour cela utiliser un projet qui récupère et affiche une liste de livres dans une table HTML depuis ma base de données.

La configuration est faite en Java à l'aide des trois classes suivantes :

Code : Sélectionner tout - Visualiser dans une fenêtre à part
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
package com.cesarharada.spring.config;
 
import java.util.Properties;
 
import javax.sql.DataSource;
 
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.ComponentScans;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.core.env.Environment;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import org.springframework.orm.hibernate5.LocalSessionFactoryBean;
import static org.hibernate.cfg.Environment.*;
import org.springframework.orm.hibernate5.HibernateTransactionManager;
 
@Configuration
@PropertySource("classpath:db.properties")
@EnableTransactionManagement
@ComponentScans(value = { @ComponentScan("com.cesarharada.spring.dao"), @ComponentScan("com.cesarharada.spring.service") })
public class AppConfig {
 
	@Autowired
	private Environment env;
 
	@Bean
	public LocalSessionFactoryBean getSessionFactory() {
 
		LocalSessionFactoryBean factoryBean = new LocalSessionFactoryBean();
		Properties props = new Properties();
 
		props.put(DRIVER, env.getProperty("mysql.driver"));
		props.put(URL, env.getProperty("mysql.url"));
		props.put(USER, env.getProperty("mysql.user"));
		props.put(PASS, env.getProperty("mysql.password")); 
 
		props.put(SHOW_SQL, env.getProperty("hibernate.show_sql"));
		props.put(HBM2DDL_AUTO, env.getProperty("hibernate.hbm2ddl.auto"));
 
		props.put(DIALECT, env.getProperty("hibernate.dialect"));
		props.put(C3P0_MIN_SIZE, env.getProperty("hibernate.c3p0.min_size"));
		props.put(C3P0_MAX_SIZE, env.getProperty("hibernate.c3p0.max_size"));
		props.put(C3P0_ACQUIRE_INCREMENT, env.getProperty("hibernate.c3p0.acquire_increment"));
		props.put(C3P0_TIMEOUT, env.getProperty("hibernate.c3p0.timeout"));
		props.put(C3P0_MAX_STATEMENTS, env.getProperty("hibernate.c3p0.max_statements"));
 
		factoryBean.setHibernateProperties(props);
		factoryBean.setPackagesToScan("com.cesarharada.spring.model");
 
		return factoryBean;
 
	}
 
	@Bean
	public HibernateTransactionManager getTransactionManager() {
 
		HibernateTransactionManager transactionManager = new HibernateTransactionManager();
		transactionManager.setSessionFactory(getSessionFactory().getObject());
 
		return transactionManager;
 
	}
 
}
Code : Sélectionner tout - Visualiser dans une fenêtre à part
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
package com.cesarharada.spring.config;
 
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.DefaultServletHandlerConfigurer;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.ViewResolverRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
import org.springframework.web.servlet.view.InternalResourceViewResolver;
 
@Configuration
@EnableWebMvc
@ComponentScan(basePackages = { "com.cesarharada.spring.controller" })
public class WebConfig extends WebMvcConfigurerAdapter {
 
	@Override
	public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer){      
	    configurer.enable();
	}
 
	@Bean
	public InternalResourceViewResolver getInternalResourceViewResolver(){      
 
	    InternalResourceViewResolver resolver = new InternalResourceViewResolver();
 
	    resolver.setPrefix("/WEB-INF/views");
	    resolver.setSuffix(".jsp");
 
	    return resolver;
 
	}
 
}
Code : Sélectionner tout - Visualiser dans une fenêtre à part
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
package com.cesarharada.spring.config;
 
import javax.servlet.Filter;
 
import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;
 
import com.cesarharada.spring.filter.SameOriginPolicyFilter;
 
public class MyWebAppÎnitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
 
	@Override
	protected Class<?>[] getRootConfigClasses() {
 
		return new Class[] { AppConfig.class };
 
	}
 
	@Override
	protected Class<?>[] getServletConfigClasses() {
 
		return new Class[] { WebConfig.class };
 
	}
 
	@Override
	protected String[] getServletMappings() {
 
		return new String[] { "/" };
 
	}
 
	@Override
	protected Filter[] getServletFilters() {
 
		Filter[] singleton = { new SameOriginPolicyFilter() };
 
		return singleton;
 
	}
 
}
et le controller :

Code : Sélectionner tout - Visualiser dans une fenêtre à part
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
package com.cesarharada.spring.controller;
 
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import com.cesarharada.spring.model.Book;
import com.cesarharada.spring.service.BookService;
 
@RestController
@RequestMapping("/bookapi/")
public class BookController {
 
	@Autowired
	private BookService bookService;
 
	@CrossOrigin(origins = "http://localhost:4200", maxAge = 10800)
	@GetMapping(value= "/api/book")
	//@RequestMapping(value= "/api/book", method= RequestMethod.GET)
	public ResponseEntity<List<Book>> list() {
 
		List<Book> list = bookService.list();
 
		if (list.isEmpty()) {
 
			return new ResponseEntity<List<Book>>(HttpStatus.NO_CONTENT);
 
		}
		else {
 
			return new ResponseEntity<List<Book>>(list, HttpStatus.OK);
 
		}
 
		//return ResponseEntity.ok().body(list);
 
	}
 
	@PostMapping("/api/book")
	public ResponseEntity<?> save(@RequestBody Book book) {
 
		long id = bookService.save(book);
 
		return ResponseEntity.ok().body("Book created with id:" + id);
 
	}
 
	@GetMapping("/api/book/{id}")
	public ResponseEntity<Book> get(@PathVariable("id") long id) {
 
		Book book = bookService.get(id);
 
		return ResponseEntity.ok().body(book);
 
	}
 
	@PutMapping("/api/book/{id}")
	public ResponseEntity<?> update(@PathVariable("id") long id, @RequestBody Book book) {
 
		bookService.update(id, book);
 
		return ResponseEntity.ok().body("Book has been updated");
 
	}
 
	@DeleteMapping("/api/book/{id}")
	public ResponseEntity<?> delete(@PathVariable("id") long id) {
 
		bookService.delete(id);
 
		return ResponseEntity.ok().body("Book has been deleted");
 
	}
 
}
J'ai reçu plusieurs messages d'erreurs tels que celui-ci en retirant les annotations au-dessus de AppConfig :

déc. 21, 2019 2:27:18 PM org.apache.catalina.core.StandardContext loadOnStartup

SEVERE: Le Servlet [dispatcher] dans l'application web [/bookapi] a retourné une exception lors de son chargement
java.lang.NoSuchMethodError: 'void org.springframework.core.annotation.AnnotationUtils.clearCache()'
Voici également mon fichier properties :

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
mysql.driver=com.mysql.cj.jdbc.Driver
mysql.url=jdbc:mysql://localhost:3306/bookapi
mysql.user=root
mysql.password=
 
hibernate.show_sql=true
hibernate.hbm2ddl.auto=update
hibernate.dialect=org.hibernate.dialect.MySQLDialect
 
hibernate.c3p0.min_size=5
hibernate.c3p0.max_size=20
hibernate.c3p0.acquire_increment=1
hibernate.c3p0.timeout=1800
hibernate.c3p0.max_statements=150
Est-ce que quelque-chose me manque. Honnêtement, j'ai cherché un peu de tous les côtés. J'obtiens une erreur après l'autre.