POSTMAN постоянно говорит мне Метод 405 не разрешен

Мой инструктор класса Udemy сделал это, и это сработало.

@PostMapping(consumes = "application/json")
@ResponseStatus(HttpStatus.CREATED)
public Employee create(@RequestBody Employee employee) {
   return employeeRepository.save(employee);
}

Весь класс ниже

package com.example.pma.projectmanagement.api.controllers;


import com.example.pma.projectmanagement.dao.EmployeeRepository;
import com.example.pma.projectmanagement.entities.Employee;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.*;

import java.util.List;

@RestController
@RequestMapping("/app-api/employees")
public class EmployeeApiController {
    @Autowired
    EmployeeRepository employeeRepository;

    @GetMapping
    public Iterable<Employee> getEmployees() {
        return employeeRepository.findAll();
    }

    @GetMapping("/{id}")
    public Employee getEmployeeById(@PathVariable("id") Long id) {
        return employeeRepository.findById(id).get();
    }

    @PostMapping(consumes = "application/json")
    @ResponseStatus(HttpStatus.CREATED)
    public Employee create(@RequestBody Employee employee) {
       return employeeRepository.save(employee);
    }

    @PutMapping(path = "/{id}", consumes = "application/json")
    @ResponseStatus(HttpStatus.OK)
    public Employee update(@RequestBody Employee employee) {
        return employeeRepository.save(employee);
    }

    @PatchMapping(path="/{id}", consumes = "application/json")
    @ResponseStatus(HttpStatus.OK)
    public Employee partialUpdate(@PathVariable("id") long id, @RequestBody Employee patchEmployee) {
        Employee e = employeeRepository.findById(id).get();

        if(patchEmployee.getEmail() != null) {
            e.setEmail(patchEmployee.getEmail());
        }
        if(patchEmployee.getFirstName() != null) {
            e.setFirstName(patchEmployee.getFirstName());
        }
        if(patchEmployee.getLastName() != null) {
            e.setLastName(patchEmployee.getLastName());
        }
        return employeeRepository.save(e);
    }
}

postman

Я могу ПОЛУЧИТЬ, но не могу ПОСТАВИТЬ, ПОСТАВИТЬ или ИСПРАВИТЬ

ОБНОВЛЕНИЕ: я использую Spring Security и в Thymeleaf мне пришлось добавить

<input type="hidden" th:value="${_csrf.token}" name="_csrf" />

Нужно ли мне что-то еще в моем теле JSON для выполнения csrf?

Я включил DEBUG и получил файл журнала

2022-02-04 00:09:43.972 DEBUG 29544 --- [http-nio-8080-exec-7] o.s.security.web.FilterChainProxy        : /app-api/employees/ at position 1 of 14 in additional filter chain; firing Filter: 'WebAsyncManagerIntegrationFilter'
2022-02-04 00:09:43.972 DEBUG 29544 --- [http-nio-8080-exec-7] o.s.security.web.FilterChainProxy        : /app-api/employees/ at position 2 of 14 in additional filter chain; firing Filter: 'SecurityContextPersistenceFilter'
2022-02-04 00:09:43.972 DEBUG 29544 --- [http-nio-8080-exec-7] w.c.HttpSessionSecurityContextRepository : HttpSession returned null object for SPRING_SECURITY_CONTEXT
2022-02-04 00:09:43.972 DEBUG 29544 --- [http-nio-8080-exec-7] w.c.HttpSessionSecurityContextRepository : No SecurityContext was available from the HttpSession: org.apache.catalina.session.StandardSessionFacade@6638e8dc. A new one will be created.
2022-02-04 00:09:43.972 DEBUG 29544 --- [http-nio-8080-exec-7] o.s.security.web.FilterChainProxy        : /app-api/employees/ at position 3 of 14 in additional filter chain; firing Filter: 'HeaderWriterFilter'
2022-02-04 00:09:43.972 DEBUG 29544 --- [http-nio-8080-exec-7] o.s.security.web.FilterChainProxy        : /app-api/employees/ at position 4 of 14 in additional filter chain; firing Filter: 'CsrfFilter'
2022-02-04 00:09:43.972 DEBUG 29544 --- [http-nio-8080-exec-7] o.s.security.web.csrf.CsrfFilter         : Invalid CSRF token found for http://localhost:8080/app-api/employees/
2022-02-04 00:09:43.973 DEBUG 29544 --- [http-nio-8080-exec-7] o.s.s.w.header.writers.HstsHeaderWriter  : Not injecting HSTS header since it did not match the requestMatcher org.springframework.security.web.header.writers.HstsHeaderWriter$SecureRequestMatcher@4bb07a96
2022-02-04 00:09:43.973 DEBUG 29544 --- [http-nio-8080-exec-7] w.c.HttpSessionSecurityContextRepository : SecurityContext is empty or contents are anonymous - context will not be stored in HttpSession.
2022-02-04 00:09:43.973 DEBUG 29544 --- [http-nio-8080-exec-7] s.s.w.c.SecurityContextPersistenceFilter : SecurityContextHolder now cleared, as request processing completed
2022-02-04 00:09:43.973 DEBUG 29544 --- [http-nio-8080-exec-7] o.s.security.web.FilterChainProxy        : /error at position 1 of 14 in additional filter chain; firing Filter: 'WebAsyncManagerIntegrationFilter'
2022-02-04 00:09:43.973 DEBUG 29544 --- [http-nio-8080-exec-7] o.s.security.web.FilterChainProxy        : /error at position 2 of 14 in additional filter chain; firing Filter: 'SecurityContextPersistenceFilter'
2022-02-04 00:09:43.973 DEBUG 29544 --- [http-nio-8080-exec-7] w.c.HttpSessionSecurityContextRepository : HttpSession returned null object for SPRING_SECURITY_CONTEXT
2022-02-04 00:09:43.973 DEBUG 29544 --- [http-nio-8080-exec-7] w.c.HttpSessionSecurityContextRepository : No SecurityContext was available from the HttpSession: org.apache.catalina.session.StandardSessionFacade@6638e8dc. A new one will be created.
2022-02-04 00:09:43.973 DEBUG 29544 --- [http-nio-8080-exec-7] o.s.security.web.FilterChainProxy        : /error at position 3 of 14 in additional filter chain; firing Filter: 'HeaderWriterFilter'
2022-02-04 00:09:43.973 DEBUG 29544 --- [http-nio-8080-exec-7] o.s.security.web.FilterChainProxy        : /error at position 4 of 14 in additional filter chain; firing Filter: 'CsrfFilter'
2022-02-04 00:09:43.973 DEBUG 29544 --- [http-nio-8080-exec-7] o.s.security.web.FilterChainProxy        : /error at position 5 of 14 in additional filter chain; firing Filter: 'LogoutFilter'
2022-02-04 00:09:43.973 DEBUG 29544 --- [http-nio-8080-exec-7] o.s.s.w.u.matcher.AntPathRequestMatcher  : Checking match of request : '/error'; against '/logout'
2022-02-04 00:09:43.973 DEBUG 29544 --- [http-nio-8080-exec-7] o.s.security.web.FilterChainProxy        : /error at position 6 of 14 in additional filter chain; firing Filter: 'UsernamePasswordAuthenticationFilter'
2022-02-04 00:09:43.973 DEBUG 29544 --- [http-nio-8080-exec-7] o.s.s.w.u.matcher.AntPathRequestMatcher  : Checking match of request : '/error'; against '/login'
2022-02-04 00:09:43.973 DEBUG 29544 --- [http-nio-8080-exec-7] o.s.security.web.FilterChainProxy        : /error at position 7 of 14 in additional filter chain; firing Filter: 'DefaultLoginPageGeneratingFilter'
2022-02-04 00:09:43.973 DEBUG 29544 --- [http-nio-8080-exec-7] o.s.security.web.FilterChainProxy        : /error at position 8 of 14 in additional filter chain; firing Filter: 'DefaultLogoutPageGeneratingFilter'
2022-02-04 00:09:43.973 DEBUG 29544 --- [http-nio-8080-exec-7] o.s.security.web.FilterChainProxy        : /error at position 9 of 14 in additional filter chain; firing Filter: 'RequestCacheAwareFilter'
2022-02-04 00:09:43.973 DEBUG 29544 --- [http-nio-8080-exec-7] o.s.s.w.s.HttpSessionRequestCache        : saved request doesn't match
2022-02-04 00:09:43.973 DEBUG 29544 --- [http-nio-8080-exec-7] o.s.security.web.FilterChainProxy        : /error at position 10 of 14 in additional filter chain; firing Filter: 'SecurityContextHolderAwareRequestFilter'
2022-02-04 00:09:43.973 DEBUG 29544 --- [http-nio-8080-exec-7] o.s.security.web.FilterChainProxy        : /error at position 11 of 14 in additional filter chain; firing Filter: 'AnonymousAuthenticationFilter'
2022-02-04 00:09:43.973 DEBUG 29544 --- [http-nio-8080-exec-7] o.s.s.w.a.AnonymousAuthenticationFilter  : Populated SecurityContextHolder with anonymous token: 'org.springframework.security.authentication.AnonymousAuthenticationToken@ae239419: Principal: anonymousUser; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails@fffe9938: RemoteIpAddress: 0:0:0:0:0:0:0:1; SessionId: CAC31DD8567E461C97442AC1C889DAD0; Granted Authorities: ROLE_ANONYMOUS'
2022-02-04 00:09:43.973 DEBUG 29544 --- [http-nio-8080-exec-7] o.s.security.web.FilterChainProxy        : /error at position 12 of 14 in additional filter chain; firing Filter: 'SessionManagementFilter'
2022-02-04 00:09:43.973 DEBUG 29544 --- [http-nio-8080-exec-7] o.s.security.web.FilterChainProxy        : /error at position 13 of 14 in additional filter chain; firing Filter: 'ExceptionTranslationFilter'
2022-02-04 00:09:43.973 DEBUG 29544 --- [http-nio-8080-exec-7] o.s.security.web.FilterChainProxy        : /error at position 14 of 14 in additional filter chain; firing Filter: 'FilterSecurityInterceptor'
2022-02-04 00:09:43.973 DEBUG 29544 --- [http-nio-8080-exec-7] o.s.s.w.u.matcher.AntPathRequestMatcher  : Checking match of request : '/error'; against '/projects/new'
2022-02-04 00:09:43.973 DEBUG 29544 --- [http-nio-8080-exec-7] o.s.s.w.u.matcher.AntPathRequestMatcher  : Checking match of request : '/error'; against '/projects/save'
2022-02-04 00:09:43.973 DEBUG 29544 --- [http-nio-8080-exec-7] o.s.s.w.u.matcher.AntPathRequestMatcher  : Checking match of request : '/error'; against '/employees/new'
2022-02-04 00:09:43.973 DEBUG 29544 --- [http-nio-8080-exec-7] o.s.s.w.u.matcher.AntPathRequestMatcher  : Checking match of request : '/error'; against '/employees/save'
2022-02-04 00:09:43.973 DEBUG 29544 --- [http-nio-8080-exec-7] o.s.s.w.u.matcher.AntPathRequestMatcher  : Checking match of request : '/error'; against '/'
2022-02-04 00:09:43.973 DEBUG 29544 --- [http-nio-8080-exec-7] o.s.s.w.u.matcher.AntPathRequestMatcher  : Request '/error' matched by universal pattern '/**'
2022-02-04 00:09:43.973 DEBUG 29544 --- [http-nio-8080-exec-7] o.s.s.w.a.i.FilterSecurityInterceptor    : Secure object: FilterInvocation: URL: /error; Attributes: [permitAll]
2022-02-04 00:09:43.973 DEBUG 29544 --- [http-nio-8080-exec-7] o.s.s.w.a.i.FilterSecurityInterceptor    : Previously Authenticated: org.springframework.security.authentication.AnonymousAuthenticationToken@ae239419: Principal: anonymousUser; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails@fffe9938: RemoteIpAddress: 0:0:0:0:0:0:0:1; SessionId: CAC31DD8567E461C97442AC1C889DAD0; Granted Authorities: ROLE_ANONYMOUS
2022-02-04 00:09:43.973 DEBUG 29544 --- [http-nio-8080-exec-7] o.s.s.access.vote.AffirmativeBased       : Voter: org.springframework.security.web.access.expression.WebExpressionVoter@7031aa78, returned: 1
2022-02-04 00:09:43.973 DEBUG 29544 --- [http-nio-8080-exec-7] o.s.s.w.a.i.FilterSecurityInterceptor    : Authorization successful
2022-02-04 00:09:43.973 DEBUG 29544 --- [http-nio-8080-exec-7] o.s.s.w.a.i.FilterSecurityInterceptor    : RunAsManager did not change Authentication object
2022-02-04 00:09:43.973 DEBUG 29544 --- [http-nio-8080-exec-7] o.s.security.web.FilterChainProxy        : /error reached end of additional filter chain; proceeding with original chain
2022-02-04 00:09:43.973 DEBUG 29544 --- [http-nio-8080-exec-7] o.s.s.w.u.matcher.AntPathRequestMatcher  : Checking match of request : '/error'; against '/projects/new'
2022-02-04 00:09:43.973 DEBUG 29544 --- [http-nio-8080-exec-7] o.s.s.w.u.matcher.AntPathRequestMatcher  : Checking match of request : '/error'; against '/projects/save'
2022-02-04 00:09:43.973 DEBUG 29544 --- [http-nio-8080-exec-7] o.s.s.w.u.matcher.AntPathRequestMatcher  : Checking match of request : '/error'; against '/employees/new'
2022-02-04 00:09:43.973 DEBUG 29544 --- [http-nio-8080-exec-7] o.s.s.w.u.matcher.AntPathRequestMatcher  : Checking match of request : '/error'; against '/employees/save'
2022-02-04 00:09:43.973 DEBUG 29544 --- [http-nio-8080-exec-7] o.s.s.w.u.matcher.AntPathRequestMatcher  : Checking match of request : '/error'; against '/'
2022-02-04 00:09:43.973 DEBUG 29544 --- [http-nio-8080-exec-7] o.s.s.w.u.matcher.AntPathRequestMatcher  : Request '/error' matched by universal pattern '/**'
2022-02-04 00:09:43.974 DEBUG 29544 --- [http-nio-8080-exec-7] o.s.s.access.vote.AffirmativeBased       : Voter: org.springframework.security.web.access.expression.WebExpressionVoter@7031aa78, returned: 1
2022-02-04 00:09:43.974 DEBUG 29544 --- [http-nio-8080-exec-7] o.s.web.servlet.DispatcherServlet        : "ERROR" dispatch for POST "/error", parameters={}
2022-02-04 00:09:43.974 DEBUG 29544 --- [http-nio-8080-exec-7] w.c.HttpSessionSecurityContextRepository : SecurityContext is empty or contents are anonymous - context will not be stored in HttpSession.
2022-02-04 00:09:43.974  WARN 29544 --- [http-nio-8080-exec-7] .w.s.m.s.DefaultHandlerExceptionResolver : Resolved [org.springframework.web.HttpRequestMethodNotSupportedException: Request method 'POST' not supported]
2022-02-04 00:09:43.974 DEBUG 29544 --- [http-nio-8080-exec-7] o.s.web.servlet.DispatcherServlet        : Exiting from "ERROR" dispatch, status 405
2022-02-04 00:09:43.974 DEBUG 29544 --- [http-nio-8080-exec-7] o.s.s.w.a.ExceptionTranslationFilter     : Chain processed normally
2022-02-04 00:09:43.974 DEBUG 29544 --- [http-nio-8080-exec-7] s.s.w.c.SecurityContextPersistenceFilter : SecurityContextHolder now cleared, as request processing completed

В моем файле SecurityConfiguration, если я добавлю это, POSTMAN будет работать.

 http.csrf().disable();

Но я чувствую, что мне не нужно отключать безопасность для проверки. После развертывания я бы удалил эту строку

Вот весь мой файл

package com.example.pma.projectmanagement.security;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.NoOpPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;

import javax.sql.DataSource;

@Configuration
@EnableWebSecurity
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {

    @Autowired
    DataSource dataSource;

    @Autowired
    BCryptPasswordEncoder bCryptPasswordEncoder;

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.jdbcAuthentication().dataSource(dataSource)
                .usersByUsernameQuery("SELECT USERNAME, PASSWORD, ENABLED FROM USER_ACCOUNTS WHERE USERNAME = ?")
                .authoritiesByUsernameQuery("SELECT USERNAME, ROLE FROM USER_ACCOUNTS WHERE USERNAME = ?")
                .dataSource(dataSource)
                .passwordEncoder(bCryptPasswordEncoder);
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
                .antMatchers("/projects/new").hasRole("ADMIN")
                .antMatchers("/projects/save").hasRole("ADMIN")
                .antMatchers("/employees/new").hasAuthority("ADMIN")
                .antMatchers("/employees/save").hasAuthority("ADMIN")
                .antMatchers("/", "/**").permitAll()
                .and()
                .formLogin();


        http.csrf().disable(); // added this line to get POSTMAN to work
        http.headers().frameOptions().disable();
    }
}
1
software is fun 4 Фев 2022 в 06:15
Можете ли вы добавить изображение того, что вы сделали на Postman?
 – 
Dinkkk
4 Фев 2022 в 06:38
Добавлено фото
 – 
software is fun
4 Фев 2022 в 06:42
Я думаю, что значение path должно быть массивом. Можете ли вы попробовать обновить его до чего-то вроде этого path = {"/{id}"}?
 – 
Dinkkk
4 Фев 2022 в 06:53
Я сделал это для своих PUT и PATCH и получил те же результаты. Для создания, как я узнаю идентификатор? Его присваивает база данных.
 – 
software is fun
4 Фев 2022 в 06:59

2 ответа

В вашем почтальоне... Вы сделали метод "Отправить"... слева от поля URL?

Это должно исправить это.

enter image description here

0
Xavi Font 4 Фев 2022 в 06:29
Да, конечно, я должен был отправить. Я также создал новые методы для PUT и PATCH, и весь мой код возвращает 405.
 – 
software is fun
4 Фев 2022 в 06:40

Удалите /12 из вашего URL. Поскольку в аннотации PostMapping нет значения, будет использоваться значение RequestMapping контроллера. Причина, по которой вы получаете 405, заключается в том, что этот URI имеет только GetMapping.

0
Josh Van de Walle 4 Фев 2022 в 06:44
Пожалуйста, проверьте мое обновленное фото. Я удалил /12. Я тестировал PUT и PATCH для сотрудника с идентификатором = 12. Это тоже не сработало. Я думаю, что если я смогу решить проблему с созданием, решение также будет применимо к PUT и PATCH.
 – 
software is fun
4 Фев 2022 в 07:01