405 postman ошибка

{
    "timestamp": "2024-07-22T19:12:51.531+00:00",
    "status": 405,
    "error": "Method Not Allowed",
    "path": "/api/v1/students"
}

У меня почему то не получается с помощy Postman сделать post запрос для добавления. Я запустил spring приложение, и хотел добавить пользователей. pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>3.4.0-SNAPSHOT</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>ru.kors</groupId>
    <artifactId>springstudents</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>springstudents</name>
    <description>Demo project for Spring Boot</description>
    <url/>
    <licenses>
        <license/>
    </licenses>
    <developers>
        <developer/>
    </developers>
    <scm>
        <connection/>
        <developerConnection/>
        <tag/>
        <url/>
    </scm>
    <properties>
        <java.version>17</java.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.34</version>
            <scope>provided</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
    <repositories>
        <repository>
            <id>spring-milestones</id>
            <name>Spring Milestones</name>
            <url>https://repo.spring.io/milestone</url>
            <snapshots>
                <enabled>false</enabled>
            </snapshots>
        </repository>
        <repository>
            <id>spring-snapshots</id>
            <name>Spring Snapshots</name>
            <url>https://repo.spring.io/snapshot</url>
            <releases>
                <enabled>false</enabled>
            </releases>
        </repository>
    </repositories>
    <pluginRepositories>
        <pluginRepository>
            <id>spring-milestones</id>
            <name>Spring Milestones</name>
            <url>https://repo.spring.io/milestone</url>
            <snapshots>
                <enabled>false</enabled>
            </snapshots>
        </pluginRepository>
        <pluginRepository>
            <id>spring-snapshots</id>
            <name>Spring Snapshots</name>
            <url>https://repo.spring.io/snapshot</url>
            <releases>
                <enabled>false</enabled>
            </releases>
        </pluginRepository>
    </pluginRepositories>

</project>

StudentController

package ru.kors.springstudents.controller;


import lombok.AllArgsConstructor;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import ru.kors.springstudents.model.Student;
import ru.kors.springstudents.service.StudentService;

import java.util.List;

@RestController
@RequestMapping("/api/v1/students")
@AllArgsConstructor
public class StudentController {

    private final StudentService service;

    @GetMapping("")
    public List<Student> findAllStudents() {
        return service.findAllStudents();
    }

    @PostMapping("save_student")
    public String saveStudent(@RequestBody Student student) {
        service.saveStudent(student);
        return "Student saved successfully";
    }

    @GetMapping("/{email}")
    public Student findStudentByEmail(@PathVariable String email) {
        return service.findStudentByEmail(email);
    }

    @PutMapping("update_")
    public Student updateStudent(Student student) {
        return service.updateStudent(student);
    }

    @DeleteMapping("delete_student/{email}")
    public void deleteStudent(@PathVariable String email) {
        service.deleteStudent(email);
    }
}

Student

package ru.kors.springstudents.model;

import lombok.*;

@Data
@Builder
public class Student {
    private String firstName;
    private String lastName;
    @NonNull
    private String email;
    private int age;
}

StudentService

package ru.kors.springstudents.service;


import ru.kors.springstudents.model.Student;

import java.util.List;


public interface StudentService {

    List<Student> findAllStudents();
    Student saveStudent(Student student);
    Student findStudentByEmail(String email);
    Student updateStudent(Student student);
    void deleteStudent(String email);
}

InMemoryStudentService

package ru.kors.springstudents.service.Impl;

import lombok.AllArgsConstructor;
import org.springframework.stereotype.Service;
import ru.kors.springstudents.model.Student;
import ru.kors.springstudents.repository.InMemoryStudentDAQ;
import ru.kors.springstudents.service.StudentService;

import java.util.ArrayList;
import java.util.List;

@Service
@AllArgsConstructor
public class InMemoryStudentService implements StudentService {
    private final InMemoryStudentDAQ repository;

    @Override
    public List<Student> findAllStudents() {
        return repository.findAllStudents();
    }

    @Override
    public void deleteStudent(String email) {
        repository.deleteStudent(email);
    }

    @Override
    public Student updateStudent(Student student) {
        return repository.updateStudent(student);
    }

    @Override
    public Student findStudentByEmail(String email) {
        return repository.findStudentByEmail(email);
    }

    @Override
    public Student saveStudent(Student student) {
        return repository.saveStudent(student);
    }
}

InMemoryStudentDAQ

package ru.kors.springstudents.repository;

import org.springframework.stereotype.Repository;
import ru.kors.springstudents.model.Student;

import java.util.List;
import java.util.ArrayList;
import java.util.stream.IntStream;

@Repository
public class InMemoryStudentDAQ {
    private List<Student> STUDENTS = new ArrayList<>();

    public List<Student> findAllStudents() {
        return STUDENTS;
    }

    public void deleteStudent(String email) {
        var student = findStudentByEmail(email);
        if(student != null) {
            STUDENTS.remove(student);
        }
    }

    public Student updateStudent(Student student) {
        var studentIndex = IntStream.range(0, STUDENTS.size()).filter(index -> STUDENTS.get(index).getEmail().equals(student.getEmail())).findFirst().orElse(-1);
        if(studentIndex > -1) {
            STUDENTS.set(studentIndex, student);
            return student;
        }
        return null;
    }

    public Student findStudentByEmail(String email) {
        return STUDENTS.stream().filter(x -> x.getEmail().equals(email)).findFirst().orElse(null);
    }

    public Student saveStudent(Student student) {
        STUDENTS.add(student);
        return student;
    }
}

Ответы (1 шт):

Автор решения: Nowhere Man

В представленном коде НЕТ POST маппинга "/api/v1/students", так как в маппинге над методом saveStudent был зачем-то добавлен суффикс "save_student", совершенно не нужный при разработке REST API.

Для устранения данной ошибки достаточно было бы исправить:

@RestController
@RequestMapping("/api/v1/students")
@AllArgsConstructor
public class StudentController {

    private final StudentService service;

    @GetMapping("/all")
    public List<Student> findAllStudents() {
        return service.findAllStudents();
    }

    @PostMapping
    @ResponseStatus(HttpStatus.CREATED)
    public String saveStudent(@RequestBody Student student) {
        service.saveStudent(student);
        return "Student saved successfully";
    }
// ...
}
→ Ссылка