Spring MVC奇怪的行为 - 当模型属性不应该被

时间:2015-07-22 21:08:22

标签: spring spring-mvc spring-boot thymeleaf

背景信息:我正在使用Spring Boot开发客户端MVC,后者与后端的REST API进行通信,后者从数据库(MongoDB)检索用户信息。我的观点技术是Thymeleaf。

一旦用户登录,他就会被重定向到他的主页,在那里显示他的个人信息。他还可以选择编辑他的个人资料,所以当他点击"编辑我的个人资料"链接他被发送到一个表格,可以填写他想要编辑的任何信息,然后点击"保存"保存更改。

以下是我的会话属性:

@SessionAttributes({"credentials", "user"})

"凭证"是一个名为Credentials的类实例化的会话对象,它有两个字段:String username和String password。

"用户"是一个名为User的类的实例化的会话对象,除了String username和String password之外,还有许多字段,如firstname,lastname等。

问题:

当他通过填写表格来编辑他的个人信息时,以及当他更改用户名和密码时,"凭证的用户名和密码"对象被覆盖!即使我没有指定应该覆盖对象字段,也会发生这种情况。从表面上看,这看起来像是Spring MVC令人困惑的凭据和用户的用户名和密码字段,并以某种方式覆盖它。

以下是设置用户和凭据的会话属性的位置:

@RequestMapping(value = "/getBasicUser", method = RequestMethod.GET)
    public <T> String getBasicUser(@ModelAttribute("credentials") Credentials credentials,
            Model model, RedirectAttributes redirect) {

        RestTemplate restTemplate = new RestTemplate();
        String url = "http://localhost:9090/users/getBasicUser?username="
                + credentials.getUsername();
        ResponseEntity<User> responseEntity = restTemplate.exchange(
                url,
                HttpMethod.GET,
                new HttpEntity<T>(createHeaders(credentials.getUsername(),
                        credentials.getPassword())), User.class);
        User user;
        user = responseEntity.getBody();

        if (user != null) {
            **redirect.addFlashAttribute("user", user);** //now session attribute "user" is set. 
            return "redirect:/basicHome";
        } else {
            return "register_fail";
        }
    }

@RequestMapping(value = "/login", method = RequestMethod.POST)
    public String login(**@ModelAttribute("credentials") Credentials credentials**, // session attribute "credentials" is set here
            RedirectAttributes redirect) {

        RestTemplate restTemplate = new RestTemplate();
        RoleInfo roleInfo = restTemplate.postForObject(
                "http://localhost:9090/users/login", credentials,
                RoleInfo.class);

        if (roleInfo != null) {
            if (roleInfo.isAdmin()) {
                return "redirect:/adminHome";
            } else {
                return "redirect:/getBasicUser";
            }
        } else {
            return "login_fail";
        }
    }

现在&#34;凭证&#34;在整个会话期间存储登录用户的用户名和密码,百老汇会在主页中识别出来:

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
    xmlns:th="http://www.thymeleaf.org"
    xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity3">
<head>
<title>Home</title>
</head>
<body>
    <h1>Welcome, <span th:text="${credentials.username}"></span> </h1>

    <h2>My profile:</h2>
    <a th:href="@{/edit}">Edit my profile</a>
    <br></br>
    <br></br>
        <table>
            <tr><td>Firstname:</td> <td th:text="${user.firstname}"></td></tr>
            <tr><td>Lastname:</td> <td th:text="${user.lastname}"></td></tr>
            <tr><td>Username:</td> <td th:text="${user.username}"></td></tr>
            <tr><td>Address:</td> <td th:text="${user.address}"></td></tr>
            <tr><td>City:</td> <td th:text="${user.city}"></td></tr>
            <tr><td>State:</td> <td th:text="${user.state}"></td></tr>
            <tr><td>Zip code:</td> <td th:text="${user.zipCode}"></td></tr>
            <tr><td>Email:</td> <td th:text="${user.email}"></td></tr>
            <tr><td>Phone number:</td> <td th:text="${user.phoneNumber}"></td></tr>
            <tr><td><hr></hr></td></tr>
        </table>
</body>
</html>

但是,在下面的方法中,字段被覆盖!

    @RequestMapping(value = "/edit", method = RequestMethod.PUT)
        public <T> String editProfile(@ModelAttribute("newUser") User user,
                @ModelAttribute("credentials") Credentials credentials, Model model,
                RedirectAttributes redirect) {

            RestTemplate restTemplate = new RestTemplate();
            String url = "http://localhost:9090/users/update?username=" + credentials.getUsername();

// username and password shows the new fields that are entered, as expected, but credentials username and password ALSO shows the new username and password, and NOT the session attribute's log in username and password.

        System.out.println("username: " + user.getUsername());
        System.out.println("password: " + user.getPassword());
        System.out.println("credentials username: " + credentials.getUsername());
        System.out.println("credentials password: " + credentials.getPassword());
        HttpHeaders headers = createHeaders(credentials.getUsername(),
                credentials.getPassword());

        @SuppressWarnings({ "unchecked", "rawtypes" })
        HttpEntity<T> entity = new HttpEntity(user, headers);

        ResponseEntity<User> responseEntity = restTemplate.exchange(url,
                HttpMethod.PUT, entity, User.class);

        User returnedUser = responseEntity.getBody();

        if (returnedUser != null) {
            //credentials.setUsername(returnedUser.getUsername());
            //credentials.setPassword(returnedUser.getPassword());
            redirect.addFlashAttribute("user", returnedUser);
            redirect.addFlashAttribute("credentials", credentials);
            return "redirect:/basicHome";
        } else {
            return "redirect:/editFail";
        }
    }

我甚至不确定春天如何将一个表格支持bean或一个对象混淆到另一个。

以下是编辑页面的百里香视图:

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
    xmlns:th="http://www.thymeleaf.org"
    xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity3">
<head>
<title>Edit</title>
</head>
<body>
    <form action="#" th:action="@{/edit}" th:object="${newUser}" th:method="put">
    <table>
        <tr><td>First Name:</td> <td><input type="text" th:value="${user.firstname}" id="firstname" name="firstname"/></td></tr>
        <tr><td>Last Name:</td> <td><input type="text" th:value="${user.lastname}" id="lastname" name="lastname"/></td></tr>
        <tr><td>User Name:</td> <td><input type="text" th:value="${user.username}" id="username" name="username"/></td></tr>
        <tr><td>Password:</td> <td><input type="password" th:value="${user.password}" id="password" name="password"/></td></tr>
        <tr><td>Address:</td> <td><input type="text" th:value="${user.address}" id="address" name="address"/></td></tr>
        <tr><td>City:</td> <td><input type="text" th:value="${user.city}" id="city" name="city"/></td></tr>
        <tr><td>State:</td> <td><input type="text" th:value="${user.state}" id="state" name="state"/></td></tr>
        <tr><td>Zip Code:</td> <td><input type="text" th:value="${user.zipCode}" id="zipCode" name="zipCode"/></td></tr>
        <tr><td>Email:</td> <td><input type="text" th:value="${user.email}" id="email" name="email"/></td></tr> 
        <tr><td>Phone Number:</td> <td><input type="text" th:value="${user.phoneNumber}" id="phoneNumber" name="phoneNumber"/></td></tr>
    </table>    
        <hr></hr>
        <input type="submit" value="Save" name="editButton" />
    </form>
</body>

0 个答案:

没有答案