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

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;
    }
}
sur cette page de login ->

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">&times;
                        </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é ->

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");
    }
}
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
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;
    }
}
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
@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";
    }
 
}
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
[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=?
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
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">&times;</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">&times;</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