Spring Boot POST 请求返回 http 状态 405“方法不允许”而不是 HTTP 状态 404
Posted
技术标签:
【中文标题】Spring Boot POST 请求返回 http 状态 405“方法不允许”而不是 HTTP 状态 404【英文标题】:Spring Boot POST requests returning http status 405 "Method Not Allowed" instead of HTTP status 404 【发布时间】:2021-09-19 21:54:02 【问题描述】:当向应用程序中不存在的端点发送 POST 请求时,服务器返回 405 而不是 404。具有现有端点的请求也会出现类似的问题,只要一切正常,状态码就会返回 200,但是当发生内部服务器错误(例如找不到用户)时,http 响应变为 405(而不是 500)。使用 GET 请求一切正常。
奇怪的是,如果我装上调试器,并按照错误的过程进行抛出,它正在处理一个 500 错误。但显然最终某处出了点问题,我得到了 405 返回。
我的网络安全配置:
@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter
@Autowired
private JwtAuthenticationEntryPoint jwtAuthenticationEntryPoint;
@Autowired
private UserDetailsService jwtUserDetailsService;
@Autowired
private JwtRequestFilter jwtRequestFilter;
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception
// configure AuthenticationManager so that it knows from where to load
// user for matching credentials
// Use BCryptPasswordEncoder
auth.userDetailsService(jwtUserDetailsService).passwordEncoder(passwordEncoder());
@Bean
public PasswordEncoder passwordEncoder()
return new BCryptPasswordEncoder();
@Bean
@Override
public AuthenticationManager authenticationManagerBean() throws Exception
return super.authenticationManagerBean();
@Value("$allowedOrigin")
private String origin = "http://localhost:4200";
@Override
protected void configure(HttpSecurity httpSecurity) throws Exception
//You can enforce the use of HTTPS when your app is running on Heroku by adding
// the following configuration to your Spring Boot app.
httpSecurity.requiresChannel()
.requestMatchers(r - > r.getHeader("X-Forwarded-Proto") != null)
.requiresSecure();
httpSecurity
.cors()
.and().csrf()
.disable()
// dont authenticate this particular request
.authorizeRequests()
.antMatchers("/api/authenticate")
.permitAll()
// all other requests for /api need to be authenticated
.antMatchers("/api/**", "/admin/**")
.authenticated()
.and()
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
// Add a filter to validate the tokens with every request
httpSecurity.addFilterBefore(jwtRequestFilter, UsernamePasswordAuthenticationFilter.class);
@Bean
CorsConfigurationSource corsConfigurationSource()
CorsConfiguration configuration = new CorsConfiguration();
configuration.setAllowedOrigins(Arrays.asList("*"));
configuration.setAllowedMethods(Arrays.asList("GET", "POST", "PUT", "DELETE", "OPTIONS"));
configuration.setAllowedHeaders(Arrays.asList("*"));
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", configuration);
return source;
更新:
我没有任何 ControllerAdivce,也没有编写全局异常处理程序。
405 响应中的“Allow”标头读取“GET, HEAD”,即使 POST 请求实际进入 POST 端点也是如此。
【问题讨论】:
是否有任何ControllerAdivce或全局异常处理程序编写? 不,没有 ControllerAdvice 也没有编写全局异常,这是一个相当新的项目。这就是它如此令人沮丧的原因,我看不出它可能哪里出错了。奇怪的是,当我做一个 POST 时,它进入了端点,但标题说“允许”:“GET,HEAD” 【参考方案1】:根据您的 HttpSecurity 配置,您只允许 Post 请求,对于 GET、PUT 等其他 HTTP 方法,您将获得 405(不允许的方法)......
antMatchers(HttpMethod.POST).permitAll();
【讨论】:
我添加了该部分作为解决方法,同时我删除了它......它不需要在那里。 antMatchers(HttpMethod.POST).permitAll();这样做是允许所有 POST 请求,并且不需要角色或身份验证。它不会阻止其他 HTTP 方法请求,例如 GET、PUT、...【参考方案2】:原来是一个带有未实现的“/error”路径方法的 ErrorController 导致了问题。每当抛出异常或错误时,它都会被解析为“/error”并由 ErrorController 拾取,由于某种原因将其解析为 405。实现该方法后,HTTP 状态将正确返回。
@RestController
public class RoutingController implements ErrorController
private static final String PATH = "/error";
@RequestMapping(value = PATH)
public String handleError(HttpServletRequest request)
Integer statusCode = (Integer) request.getAttribute("javax.servlet.error.status_code");
Exception exception = (Exception) request.getAttribute("javax.servlet.error.exception");
return String.format("<html><body><h2>Error Page</h2><div>Status code: <b>%s</b></div>" +
"<div>Exception Message: <b>%s</b></div><body></html>",
statusCode, exception == null ? "N/A" : exception.getMessage());
public String getErrorPath()
return PATH;
【讨论】:
以上是关于Spring Boot POST 请求返回 http 状态 405“方法不允许”而不是 HTTP 状态 404的主要内容,如果未能解决你的问题,请参考以下文章
spring boot应用集成cas单点登录,post请求拿不到参数