Bonjour, je m'en remets à vous car après plusieurs tentatives et plusieurs heures de recherche je ne comprends pas pourquoi je n'arrive pas à faire un update dans MySQL avec Spring..
Le procédé est le suivant: (pour les .java je vous épargne les imports, pour plus de visibilité)
On part du principe que ce dernier est déjà dans la BDD, il se connecte avec ses identifiants ->
GlobalController.java
sur cette page de login ->
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 @Component @Scope(value = "session", proxyMode = ScopedProxyMode.TARGET_CLASS) public class GlobalController { @Autowired private UserService userService; private User loginUser; public User getLoginUser() { if (loginUser == null) { Authentication auth = SecurityContextHolder.getContext().getAuthentication(); loginUser = userService.findByUserName(auth.getName()); } return loginUser; } }
login.html
Code html : 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 <!DOCTYPE html> <html xmlns:th="http://www.thymeleaf.org"> <head> <title>Login</title> <meta name="description" content="spring-boot thymeleaf | Login "> <div th:replace="fragments/header :: header-login-css"></div> </head> <body> <br/> <hr/> <div class="container"> <div class="row"> <div class="login-register-form-section"> <h1 class="content-title" align="center">Login</h1><br/> <div class="tab-content"> <div role="tabpanel" class="tab-pane fade in active" id="login"> <div th:if="${param.error}" class="alert alert-danger alert-dismissable"> <button type="button" class="close" data-dismiss="alert" aria-hidden="true">× </button> Identifiant inconnu. </div> <form th:action="@{/login}" method="post" class="form-horizontal"> <div class="form-group "> <div class="input-group"> <div class="input-group-addon"><i class="fa fa-user"></i></div> <input type="text" name="username" class="form-control" placeholder="Login" required="required" value=""/> </div> </div> <div class="form-group "> <div class="input-group"> <div class="input-group-addon"><i class="fa fa-key"></i></div> <input type="password" name="password" class="form-control" placeholder="Mot de passe" required="required"/> </div> </div> <div class="form-group"> <input type="checkbox" id="rememberMe"/> <label for="rememberMe">Remember Me </label> <a href="#" class="pull-right">Mot de passe oublié ?</a> </div> <input type="submit" value="Login" class="btn btn-success btn-custom"/> </form> </div> </div> </div> </div> </div> </body> </html>
grâce a une classe, en cas de succès il est redirigé ->
les infos sont obtenus grâce à une classe UserDetails de Spring
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 @Component public class MyAuthenticationSuccessHandler extends SimpleUrlAuthenticationSuccessHandler { private static final Logger logger = LoggerFactory.getLogger(MyAuthenticationSuccessHandler.class); private RedirectStrategy redirectStrategy = new DefaultRedirectStrategy(); @Override protected void handle(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException { String targetUrl = determineTargetUrl(authentication); System.out.println("handle: " + targetUrl); if (response.isCommitted()) { logger.warn("Can't redirect"); return; } redirectStrategy.sendRedirect(request, response, targetUrl); } protected String determineTargetUrl(Authentication authentication) { logger.info("determineTargetUrl: " + authentication.getName()); Collection<? extends GrantedAuthority> authorities = authentication.getAuthorities(); List<String> roles = new ArrayList<>(); for (GrantedAuthority a : authorities) { System.out.println("Authority: " + a.getAuthority()); roles.add(a.getAuthority()); } if (isAdmin(roles)) { return "/admin" + authentication.getName(); } else if (isUser(roles)) { return "/home/" + authentication.getName(); } else { return "/login?error"; } } @Override public void setRedirectStrategy(RedirectStrategy redirectStrategy) { this.redirectStrategy = redirectStrategy; } @Override protected RedirectStrategy getRedirectStrategy() { return redirectStrategy; } private boolean isUser(List<String> roles) { return roles.contains("ROLE_USER"); } private boolean isAdmin(List<String> roles) { return roles.contains("ROLE_ADMIN"); } }
la on est sur le cas d'un ROLE_USER, jusque la tout va bien, donc il a été redirigé sur son "home" qui lui permet directement d'éditer son mot de passe uniquement, on est donc sur le UserController.java
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 @Service public class AuthUserDetailsService implements UserDetailsService { private static final Logger logger = LoggerFactory.getLogger(AuthUserDetailsService.class); @Autowired private UserService userService; private org.springframework.security.core.userdetails.User springUser; @Override public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { boolean enabled = true; boolean accountNonExpired = true; boolean credentialsNonExpired = true; boolean accountNonLocked = true; User user = getUserDetail(username); if (user != null) { springUser = new org.springframework.security.core.userdetails.User(user.getUsername(), user.getPassword(), enabled, accountNonExpired, credentialsNonExpired, accountNonLocked, getAuthorities(user.getRole()) ); return springUser; } else { springUser = new org.springframework.security.core.userdetails.User("empty", "empty", false, true, true, false, getAuthorities(1) ); return springUser; } } public List<GrantedAuthority> getAuthorities(Integer role) { List<GrantedAuthority> authList = new ArrayList<GrantedAuthority>(); if (role == 1) { authList.add(new SimpleGrantedAuthority("ROLE_ADMIN")); } else if (role == 2) { authList.add(new SimpleGrantedAuthority("ROLE_USER")); } return authList; } private User getUserDetail(String username) { User user = userService.findByUserName(username); if (user == null) { logger.warn("user '" + username + "' on null!"); } else { logger.info(user.toString()); } return user; } }
et c'est la ou ça bloque, une fois sur sa page, j'ai bien le "url/home/username" correct (il recupère bien l'username) :
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 @Controller public class UserController { private static final Logger logger = LoggerFactory.getLogger(UserController.class); @Autowired GlobalController globalController; @Autowired UserService userService; @RequestMapping("/") public String root(Model model) { model.addAttribute("reqUser", new User()); logger.info("root"); return "login"; } @RequestMapping("/login") public String login(Model model) { model.addAttribute("reqUser", new User()); logger.info("login"); return "login"; } @RequestMapping(value = {"/home/editUser"}, method = RequestMethod.POST) public String edit(@ModelAttribute("editUser") User editUser, Model model) { logger.info("/home/editUser"); try { User user = userService.findByUserName(editUser.getUsername()); if (!user.equals(editUser)) { userService.update(editUser); model.addAttribute("msg", "success"); } else { model.addAttribute("msg", "same"); } } catch (Exception e) { model.addAttribute("msg", "fail"); logger.error("editUser: " + e.getMessage()); } model.addAttribute("edit", editUser); return "home"; } @RequestMapping(value = "/home/{username}", method = RequestMethod.GET) public String home(@PathVariable("username") String username, final RedirectAttributes redirectAttributes, Model model) { logger.info("/home/{} ", username); User editUser = userService.findByUserName(username); if (editUser != null) { model.addAttribute("editUser", editUser); return "home"; } else { redirectAttributes.addFlashAttribute("msg", "notfound"); } return "redirect:/home"; } }
mais quand je veux faire l'édition (donc quand j'appuie sur le bouton) j'ai l'erreur du fail :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12 [INFO ] 2018-11-23 10:23:37.679 [http-nio-8080-exec-1] UserController - /home/test Hibernate: select user0_.id as id1_0_, user0_.email as email2_0_, user0_.password as password3_0_, user0_.role as role4_0_, user0_.username as username5_0_ from user user0_ where user0_.username=?
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13 [INFO ] 2018-11-23 10:24:08.224 [http-nio-8080-exec-9] UserController - /home/editUser Hibernate: select user0_.id as id1_0_, user0_.email as email2_0_, user0_.password as password3_0_, user0_.role as role4_0_, user0_.username as username5_0_ from user user0_ where user0_.username is null [ERROR] 2018-11-23 10:24:08.233 [http-nio-8080-exec-9] UserController - editUser: null
voici le formulaire d'edition:
Code html : 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 <html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org"> <head> <title>Edition</title> <meta name="description" content="spring-boot thymeleaf | Home "> <div th:replace="fragments/header :: header-login-css"></div> </head> <body> <div th:replace="fragments/header :: header"></div> <br/><br/><br/> <hr/> <div class="container"> <div class="row"> <div class="login-register-form-section"> <h1 class="content-title" align="center">Editer mot de passe</h1><br/> <div class="tab-content"> <div role="tabpanel" class="tab-pane fade in active" id="home"> <div th:if="${msg eq 'success'}" class="alert alert-success alert-dismissable"> <button type="button" class="close" data-dismiss="alert" aria-hidden="true">×</button> <strong>Changement réussi</strong> </div> <div th:if="${msg eq 'fail'}" class="alert alert-danger alert-dismissable"> <button type="button" class="close" data-dismiss="alert" aria-hidden="true">×</button> <strong>Erreur lors du changement</strong> </div> <form th:object="${editUser}" th:action="@{/home/editUser}" method="post" class="form-horizontal"> <div class="form-group "> <div class="input-group"> <div class="input-group-addon"><i class="fa fa-lock"></i></div> <input th:field="*{password}" type="password" name="password" class="form-control" id="password" placeholder="Mot de passe actuel" required="required"/> </div> </div> <div class="form-group "> <div class="input-group"> <div class="input-group-addon"><i class="fa fa-lock"></i></div> <input th:field="*{password_1}" type="password" name="password_1" pattern="(?=.*\d)(?=.*[a-z])(?=.*[A-Z])(?=.*[!@#$%^&*(),.?:{}|<>]).{8,10}" title="un chiffre, une lettre minuscule, une lettre majuscule, un caractère spécial et un minimum de 8 caractères" minlength="8" maxlength="10" class="form-control" id="password_1" placeholder="Nouveau mot de passe" required="required"/> </div> </div> <div class="form-group "> <div class="input-group"> <div class="input-group-addon"><i class="fa fa-lock"></i></div> <input th:field="*{password_2}" type="password" name="password_2" pattern="(?=.*\d)(?=.*[a-z])(?=.*[A-Z])(?=.*[!@#$%^&*(),.?:{}|<>]).{8,10}" title="un chiffre, une lettre minuscule, une lettre majuscule, un caractère spécial et un minimum de 8 caractères" minlength="8" maxlength="10" class="form-control" id="password_2" placeholder="Confirmation mot de passe" required="required"/> </div> </div> <input type="submit" value="Editer" class="btn btn-success btn-custom"/> </form> </div> </div> </div> </div> </div> </body> </html>
donc a priori je suis sur que c'est encore un truc à la con mais à passer trop de temps dessus je mouline.
Je pense que le problème se trouve dans un de ses fichiers, je ne sais pas pourquoi il n'arrive pas à recuperer l'username pour l'update alors que pour le login tout va bien...
Merci de votre aide
PS: si vous pensez que cela ne vient pas d'un de ses fichiers, je vous donnerais les autres, je ne les mets pas encore car ça fait déjà un paquet de code et je ne suis pas sur que ça vient des autres..
Merciiii
Partager