将数据保存到服务器时适用于@GetMapping而不是@PostMapping

时间:2020-05-11 14:08:41

标签: css spring http view model

一般来说,我是Spring Boot和Web应用程序的新手。我的saveStudent()方法遇到了问题

@PostMapping("/students")
public ModelAndView saveStudent(Student student) {
    repo.save(student);
    ModelAndView mv = new ModelAndView();
    mv.addObject("obj",student);
    mv.setViewName("addStudent");
    return mv;
}

我知道,如果要将数据保存到服务器HTTP时,将使用POST方法,但是在检索数据时,它将使用GET方法。在这种情况下,由于我将一个Student实例保存到数据库中,因此我应该使用PostMapping对吗?但是令我惊讶的是,如果我将注释更改为@GetMapping,则此方法有效,您能解释一下原因吗?

@GetMapping("/students")
public ModelAndView saveStudent(Student student) {
    repo.save(student);
    ModelAndView mv = new ModelAndView();
    mv.addObject("obj",student);
    mv.setViewName("addStudent");
    return mv;
}

此方法工作正常,PostMapping不起作用。但是为什么呢?

MainController

package com.firstdbproj.demo.controller;


import java.util.List;
import java.util.Optional;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.ModelAndView;

import com.firstdbproj.demo.Student;
import com.firstdbproj.demo.dao.StudentRepo;


@RestController
public class MainController {

    @Autowired
    StudentRepo repo;

    @RequestMapping("/")
    public ModelAndView showIndexPage() {
        ModelAndView mv = new ModelAndView();
        mv.setViewName("index");
        return mv;
    }

    @PostMapping("/students")
    public ModelAndView fetchStudent(Student student) {
        repo.save(student);
        ModelAndView mv = new ModelAndView();
        mv.addObject("obj",student);
        mv.setViewName("addStudent");
        return mv;
    }


    @GetMapping(path="/students/{id}")
    @ResponseBody
    public Optional<Student> showStudentinJSON(@PathVariable("id")int ids) {
        Optional<Student> obj = repo.findById(ids);
        return obj;
    }


    @RequestMapping("/showStudentUsingId")
    public ModelAndView showStudent(@RequestParam("id")int ids) {
        Student obj = repo.findById(ids).orElse(new Student(0,"null"));
        ModelAndView mv = new ModelAndView();
        mv.addObject("student",obj);
        mv.setViewName("showStudent");
        return mv;
    }

    @RequestMapping("/showStudentUsingName")
    public ModelAndView showStudent(@RequestParam("id")String name) {
        Student obj = repo.findByName(name);
        ModelAndView mv = new ModelAndView();
        mv.addObject("student",obj);
        mv.setViewName("showStudent");
        return mv;
    }

    @RequestMapping("/showAllStudent")
    public String showAllStudent() {
        List<Student> obj = (List<Student>) repo.findAllSorted();
        return obj.toString();
    }

    @RequestMapping("/showAllStudentWhereName")
    public String showAllStudentWhereName(@RequestParam("id")String name) {
        List<Student> obj = (List<Student>) repo.findAllWhereName(name);
        return obj.toString();
    }

    @RequestMapping("/getStudent")
    public ModelAndView getStudent() {
        ModelAndView mv = new ModelAndView();
        mv.setViewName("getStudent");
        return mv;
    }

}

学生回购

package com.firstdbproj.demo;

import javax.persistence.Entity;
import javax.persistence.Id;

import org.springframework.stereotype.Component;

@Entity
public class Student {

    @Id
    private int id;
    private String name;

    public Student(){

    }
    public Student(int id,String name){
        this.id = id;
        this.name = name;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    @Override
    public String toString() {
        return "Student [id=" + id + ", name=" + name + "]";
    }
}

addStudent.jsp

<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
    pageEncoding="ISO-8859-1" isELIgnored="false"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="ISO-8859-1">
<title>Insert title here</title>
</head>
<body>
    Hello ${obj.id}, ${obj.name}!
    <form action="/">
    <input type="submit" value="Add another Record!">
    <input type="submit" formaction="getStudent" value="Fetch Records!">
    </form>
</body>
</html>

2 个答案:

答案 0 :(得分:0)

您可能已经这样做了。请重建并重新启动服务器。这可以帮助!

答案 1 :(得分:0)

您误解了REST的整体概念和目的。 HTTP方法是建议,而不是限制。

建议使用GET来检索数据,但这不是强制性的。通过使用GET,您可以获得浏览器缓存的其他好处,但是可以像使用POST / PUT一样使用。由于HTTP方法是API功能的建议/提示,所以这就是控制器正常工作的原因。

示例:

GET /students <--- implies that this API will return a list of student
POST /students <--- implies that this API will create a student

HTTP方法可以提示您API的功能,但是您可以使用GET来代替POST来创建学生。从技术上讲可行,但您会违反惯例

一些阅读材料:https://martinfowler.com/articles/richardsonMaturityModel.html

编辑以回答评论中的问题

如果获得405,则意味着特定资源路径不支持方法。例如,假设您有这个

@PostMapping("/students")
public String createStudent() {
   // logic
}

@GetMapping("/students") 
public List<String> getListOfStudents() {
  //logic
}

然后向POST发出的GET/students请求都可以,并且不会收到405。但是,如果您决定发送DELETE,则{{1} }到PUT,您将得到405。因此,在您的情况下,您可能缺少对正确资源的正确注释