【问题标题】:modelAttribute in jsp page returning null on non input fieldsjsp页面中的modelAttribute在非输入字段上返回null
【发布时间】:2020-10-23 11:57:12
【问题描述】:

我正在使用 modelAttribute 将对象与我的表单中的模型类绑定,正如您必须在我之前在表单的 get 请求中提到的变量那样,并且所有值都被公平地打印在页面上,

现在在页面上,我输入了一个属性,该属性通过 OnetoOne 映射进一步映射到另一个实体。但是在发布时,只有 OneToOne 实体返回值,所有其余属性都返回 null。

控制器

@GetMapping("/users/{username}/complaint")
    public String userRegisterComplaintRoute(Model model, @PathVariable String username) {
        model.addAttribute("user", userService.findSingleUserDetails(username));
        return "complaint-index";
    }

    @PostMapping("/users/complaint")
    public String userRegisterComplaintPostRoute(Model model, User user) {
        System.out.println(user);
        // userService.addUserDetails(user);

        return "redirect:/users/" + user.getName() + "/complaint/status";
    }

表格

<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <title>Kolkata | CRS</title>
    </head>
    <body>
        <h1>Username ${user.username}</h1>
        <h1>Username ${user.name}</h1>
        <h1>Username ${user.password}</h1>
        <h1>Username ${user.roles}</h1>

        <form:form
            action="/users/complaint"
            method="post"
            modelAttribute="user"
        >
            <form:label path="complaint.text" for="complaint"
                >Complaint</form:label
            >
            <form:input
                type="text"
                name="complaint"
                id="complaint"
                path="complaint.text"
            ></form:input>

            <button type="submit">Submit</button>
        </form:form>
    </body>
</html>

用户类

package com.naha.crimereportingsystem.user;

import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.OneToMany;
import javax.persistence.OneToOne;

import com.naha.crimereportingsystem.complaint.Complaint;

@Entity
public class User {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private int id;
    private String name;
    private String username;
    private String password;
    private boolean active = true;
    private String roles = "ROLE_USER";

    @OneToOne(targetEntity = Complaint.class, cascade = CascadeType.ALL)
    private Complaint complaint;

    public String getUsername() {
        return username;
    }

    public Complaint getComplaint() {
        return complaint;
    }

    public void setComplaint(Complaint complaint) {
        this.complaint = complaint;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getRoles() {
        return roles;
    }

    public void setRoles(String roles) {
        this.roles = roles;
    }

    public boolean isActive() {
        return active;
    }

    public void setActive(boolean active) {
        this.active = active;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public User() {
    }

    public User(int id, String name, String username, String password, boolean active, String roles) {
        this.id = id;
        this.name = name;
        this.username = username;
        this.password = password;
        this.active = active;
        this.roles = roles;
        this.complaint = new Complaint();
    }

    @Override
    public String toString() {
        return "id: " + this.id + "\nname: " + this.name + "\nusername: " + this.username + "\ncomplaint:"
                + this.complaint.getText();
    }

}

Compaint 类

package com.naha.crimereportingsystem.complaint;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;

@Entity
public class Complaint {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private long id;
    private String text;
    private String status = "Investigation Pending";

    public long getId() {
        return id;
    }

    public String getStatus() {
        return status;
    }

    public void setStatus(String status) {
        this.status = status;
    }

    public String getText() {
        return text;
    }

    public void setText(String text) {
        this.text = text;
    }

    public void setId(long id) {
        this.id = id;
    }

    public Complaint() {
    }

    public Complaint(long id, String text, String status) {
        this.id = id;
        this.text = text;
        this.status = status;
    }

}

toString 输出

【问题讨论】:

    标签: java spring spring-boot spring-mvc modelattribute


    【解决方案1】:

    当您发布表单时,只有用户输入数据随请求一起发送。只有那些数据被绑定到命令对象。

    一个天真的解决方案是在表单中放置隐藏字段。但是 Spring 对此有一个很好的解决方案。

    在您的控制器上使用@SessionAttributes

    @SessionAttributes("commandNameHere")
    public class FooController {
       // code
    
        @RequestMapping("/foo", method = POST)
        public String foo(SessionStatus status) {
        // code
        
        status.setComplete(); // marks for cleanup of session attributes
    }
    

    Spring 会将命令对象放入透明会话中。表单数据中未找到的字段将从该会话中绑定。

    另外,在您的后期映射中,在命令对象上使用@ModelAttribute 以从模型中解析命令对象。


    进一步阅读

    【讨论】:

    • 所以我可以使用 SessionAttribute 或 ModelAttribute 来解决这个问题?并且将整个 User 模型类存储在您的会话中不是一种不好的做法,因为它可以将用户名和密码暴露给网络?
    • 并非如此。这两个注释不做同样的事情。 @ModelAttribute 从模型中解析了对象。 @SessionAttributes 存储在透明会话中并在绑定时检索必要的字段。在这种情况下,您需要同时使用两者。我不认为这是一个不好的做法,因为它在服务器端。此外,如果您想为具有敏感字段的对象创建自定义命令。
    • 谢谢,它成功了。虽然 ModelAttribute 的概念还不清楚。
    • 很高兴它有帮助。我在答案中添加了指向资源的链接。这可能会消除您的困惑。
    • 此解决方案似乎不起作用。据我所知,模型属性的值在页面加载之间不会持续存在。
    猜你喜欢
    • 2012-12-18
    • 1970-01-01
    • 2013-08-02
    • 1970-01-01
    • 2021-11-15
    • 2012-12-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多