使用Postman时POST请求正常工作,但使用React axios和Spring Boot后端时不起作用
P粉208469050
P粉208469050 2024-04-05 13:07:01
0
1
568

从反应控制台我收到错误消息“无法加载资源:服务器响应状态为 500 ()”,指向 url“:8080/api/review-add”

从 Spring Boot 后端,我收到错误消息“not-null 属性引用 null 或瞬态值:com.reactspringboot.bookclubbackend.entity.Review.account”

问题是在邮递员中执行 POST 请求时,我没有收到错误,并且对象已发布到数据库中。

这是来自 Spring Boot 后端的文件:

论坛.java

@Entity
@Table(name="Forum")
public class Forum {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name="id")
    private long id;

    @Column(name="book_name")
    private String bookName;

    @Column(name="book_image")
    private String bookImage;

    @Lob
    @Column(name="description")
    private String description;


    @OneToMany(mappedBy = "forum", cascade = CascadeType.ALL)
    private List<Review> reviews;

    public Forum() {
    }

    public Forum(String bookName, String bookImage, String description, List<Review> reviews) {
        this.bookName = bookName;
        this.bookImage = bookImage;
        this.description = description;
        this.reviews = reviews;
    }

    public long getId() {
        return id;
    }

    public String getBookName() {
        return bookName;
    }

    public void setBookName(String bookName) {
        this.bookName = bookName;
    }

    public String getBookImage() {
        return bookImage;
    }

    public void setBookImage(String bookImage) {
        this.bookImage = bookImage;
    }

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }

    // using 'JsonProperty' to prevent infinite recursion
    @JsonProperty(access = JsonProperty.Access.WRITE_ONLY)
    public List<Review> getReviews() {
        return reviews;
    }

    public void setReviews(List<Review> reviews) {
        this.reviews = reviews;
    }
}

帐户.java

@Entity
@Table(name="account")
public class Account {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name="id")
    private long id;

    @Column(name="account_name")
    private String accountName;

    @Column(name="password")
    private String password;

    @Column(name="email")
    private String email;

    @Column(name="profile_image")
    private String profileImage;

    @Column(name="role")
    private String role;

    @Column(name="date_joined")
    @CreationTimestamp
    private Date dateJoined;


    @OneToMany(mappedBy = "account", cascade = CascadeType.ALL)
    private List<Review> reviews;

    public Account() {
    }

    public Account(String accountName, String password, String email, String profileImage, String role, Date dateJoined, List<Review> reviews) {
        this.accountName = accountName;
        this.password = password;
        this.email = email;
        this.profileImage = profileImage;
        this.role = role;
        this.dateJoined = dateJoined;
        this.reviews = reviews;
    }

    public long getId() {
        return id;
    }

    public String getAccountName() {
        return accountName;
    }

    public void setAccountName(String accountName) {
        this.accountName = accountName;
    }

    public String getPassword() {
        return password;
    }

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

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    public String getProfileImage() {
        return profileImage;
    }

    public void setProfileImage(String profileImage) {
        this.profileImage = profileImage;
    }

    public String getRole() {
        return role;
    }

    public void setRole(String role) {
        this.role = role;
    }

    public Date getDateJoined() {
        return dateJoined;
    }

    public void setDateJoined(Date dateJoined) {
        this.dateJoined = dateJoined;
    }

    // using 'JsonProperty' to prevent infinite recursion
    @JsonProperty(access = JsonProperty.Access.WRITE_ONLY)
    public List<Review> getReviews() {
        return reviews;
    }

    public void setReviews(List<Review> reviews) {
        this.reviews = reviews;
    }
}

Review.java

@Entity
@Table(name="review")
public class Review {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name="id")
    private long id;

    @Column(name="date_posted")
    @CreationTimestamp
    private Date datePosted;

    @Lob
    @Column(name="comment")
    private String comment;

    @Column(name="star_rating")
    private double starRating;


    //@JsonIgnore
    @ManyToOne
    @JoinColumn(name = "account_id",nullable = false, insertable = true, updatable = true)
    private Account account;


    //@JsonIgnore
    @ManyToOne
    @JoinColumn(name = "forum_id",nullable = false, insertable = true, updatable = true)
    private Forum forum;


    public Review() {
    }

    public Review(Date datePosted, String comment, double starRating, Account account, Forum forum) {
        this.datePosted = datePosted;
        this.comment = comment;
        this.starRating = starRating;
        this.account = account;
        this.forum = forum;
    }

    public long getId() {
        return id;
    }

    public Date getDatePosted() {
        return datePosted;
    }

    public void setDatePosted(Date datePosted) {
        this.datePosted = datePosted;
    }

    public String getComment() {
        return comment;
    }

    public void setComment(String comment) {
        this.comment = comment;
    }

    public double getStarRating() {
        return starRating;
    }

    public void setStarRating(double starRating) {
        this.starRating = starRating;
    }

    public Account getAccount() {
        return account;
    }

    public void setAccount(Account account) {
        this.account = account;
    }

    public Forum getForum() {
        return forum;
    }

    public void setForum(Forum forum) {
        this.forum = forum;
    }
}

ReviewRepository.java

@CrossOrigin(origins = "http://localhost:3000")
public interface ReviewRepository extends JpaRepository<Review, Long> {


    @Query(value = "SELECT * FROM Review r where r.forum_id = :forum_id", nativeQuery = true)
    public List<Review> getReviewsUsingForumId(@Param("forum_id") Long forum_id);
}

ReviewController.java

@CrossOrigin(origins = "http://localhost:3000")
@RestController
@RequestMapping("/api/")
public class ReviewController {

    @Autowired
    private ReviewRepository reviewRepository;


    // create review rest api
    //@CrossOrigin(origins = "http://localhost:3000")
    @PostMapping("/review-add")
    public Review createReview(@RequestBody Review review) {
        return reviewRepository.save(review);
    }

    @GetMapping("/forum-reviews/{forumId}")
    public List<Review> getReviewsByForumId(@RequestBody @PathVariable Long forumId) {
        return reviewRepository.getReviewsUsingForumId(forumId);
    }
}

来自 React 前端

PostComponent.js

function PostComponent() {

    // right now only using static data for testing
    const [review, setReview] = useState({datePosted: "2023-07-26", comment: "", 
                                          starRating: 5.0,
                                          account: {
                                            id: 1
                                          },
                                          forum: {
                                            id: 1
                                          }});
    
    const postURL = "http://localhost:8080/api/review-add";

    function changeHandler (event) {    
        setReview({comment: event.target.value});
    }

    function submit(event) {
        event.preventDefault();
        axios.post(postURL, review)
          
    }

    useEffect(() => {
        console.log(review.comment)
    }, [review]);

    return ( 
        <div>
            <div className="container">
                <h2>Post Review</h2>
                <form onSubmit={(event) => submit(event)}>
                    <div className="form-group">
                        <label>Comment</label>
                        <input placeholder="Commet here" name="comment" className="form=control"
                            value={review.comment} onChange={changeHandler}/>
                    </div>
                    <button>Submit</button>
                </form>
            </div>
        </div>
    ) 
}

export default PostComponent;

在邮递员正文中,我选择 raw 并设置为 JSON,当我对“审阅”实体使用此 POST 请求时,它会起作用:

{
    "datePosted": "2023-07-26",
    "comment": "From postman.",
    "starRating": 5.0,
    "account": {
        "id": 1
    },
    "forum": {
        "id": 1
    }
}

数据库中存在id为1的论坛和id为1的帐户。

如果有人可以帮助我或指出我解决这个问题,我将不胜感激。我已经被这个问题困扰好几天了,而且我已经没有想法了。

P粉208469050
P粉208469050

全部回复(1)
P粉254077747

如果服务器期望接收整个负载:

{
    "datePosted": "2023-07-26",
    "comment": "From postman.",
    "starRating": 5.0,
    "account": {
        "id": 1
    },
    "forum": {
        "id": 1
    }
}

在你执行以下操作后,服务器将不会收到:

setReview({comment: event.target.value});

服务器只会收到:

{
    "comment": "From postman."
}

当你只想更新状态中的一个属性时,更新仍然需要包含对象的其余部分以保留整个对象:

setReview({...review, comment: event.target.value});

或者:

setReview(r => ({...r, comment: event.target.value}));

顺便说一下...你的浏览器调试工具可以帮助你缩小到这个确切的问题。你可以观察发送的AJAX请求中的负载,看到它不是你期望的内容,并立即排除所有服务器端代码作为问题的原因,开始专注于客户端调试。

热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板