jsp 页面中的 modelAttribute 在非输入字段上返回 null

modelAttribute in jsp page returning null on non input fields

我在我的表单中使用 modelAttribute 将对象与模型 class 绑定,因为您必须事先在表单的获取请求中提及变量,所以我这样做了并且所有值都相当打印在页面上,

现在在页面上,我输入了一个属性,该属性通过 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>

用户Class

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();
    }

}

投诉Class

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 输出

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

一个天真的解决方案是在表单中放置隐藏字段。但是 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 会将命令对象放入透明会话中。在表单数据中找不到的字段将从该会话绑定。

此外,在您的 post 映射中,对命令对象使用 @ModelAttribute 以从模型中解析命令对象。


进一步阅读