Spring Boot接口报405错误:GET请求不支持问题排查求助
我需要根据ID为每个BaBs实体发送定制邮件,使用GET请求访问接口http://localhost:8081/api/v1/test/babss/sendmail/b1d0c331-35ac-430d-87ca-1718b06351c3时,出现405错误,提示“Request method 'GET' not supported”。以下是相关代码及配置,请排查问题原因。
相关代码与配置
BaBs实体类
import com.fasterxml.jackson.annotation.JsonBackReference; import com.fasterxml.jackson.annotation.JsonProperty; import lombok.*; import javax.persistence.*; import java.util.UUID; @Getter @Setter @NoArgsConstructor @AllArgsConstructor @Builder @Entity @Table(name = "babs") public class BaBs { @Id @Column(name = "id") private UUID id; @Column(name = "accountCode") private String accountCode; @Column(name = "accountName") private String accountName; @Column(name = "eMail") private String eMail; @ManyToOne @JsonBackReference @JoinColumn(name = "accountid") private Account account; }
邮件发送服务类
import gokhan.mutabakatcore.models.BaBs; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpStatus; import org.springframework.mail.MailException; import org.springframework.mail.SimpleMailMessage; import org.springframework.mail.javamail.JavaMailSender; import org.springframework.stereotype.Component; import javax.mail.MessagingException; import javax.mail.internet.MimeMessage; @Component public class SentBaBsEmail { @Autowired private JavaMailSender sender; public HttpStatus mailBaBs(BaBs baBs) throws MailException { SimpleMailMessage mail = new SimpleMailMessage(); mail.setTo(baBs.getEMail()); mail.setSubject("Trial Mail for Sending BaBs"); mail.setText("Normally Details from Object "); sender.send(mail); System.out.println("eMail sent"); return HttpStatus.GONE; } }
BaBs控制器相关代码
import gokhan.mutabakatcore.models.BaBs; import gokhan.mutabakatcore.services.BaBsService; import gokhan.mutabakatcore.utils.SentBaBsEmail; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.*; import javax.servlet.http.HttpServletRequest; import javax.validation.Valid; import java.util.Collections; import java.util.List; import java.util.Optional; import java.util.UUID; import java.util.function.Function; @RestController @RequestMapping("/api/v1/test/babss") public class BaBsController { private final BaBsService baBsService; public BaBsController(BaBsService baBsService) { this.baBsService = baBsService; } @Autowired SentBaBsEmail baBsEmail; @RequestMapping(value = "/sendmail/{Id}", method = { RequestMethod.GET, RequestMethod.POST }) public ResponseEntity<?> eMailBaBsByCustomerId(@PathVariable("Id") UUID uuid){ try{ if (!baBsService.findById(uuid).equals(Optional.empty())){ // Converts Optional Object to Normal Object BaBs baBs = (BaBs) toList(baBsService.findById(uuid)); baBsEmail.mailBaBs(baBs); return new ResponseEntity(baBs ,HttpStatus.CREATED); } return new ResponseEntity<>("Unrecorded BaBS!", HttpStatus.BAD_REQUEST); } catch (Exception e) { return new ResponseEntity<>(HttpStatus.NOT_FOUND); } } }
邮件配置(application.properties)
#SMTP Email Properties spring.mail.host=mail.xyz.com spring.mail.port=587 spring.mail.username=info@xyz.com spring.mail.password=password spring.mail.properties.mail.smtp.auth=true spring.mail.properties.mail.starttls.enable=true spring.mail.properties.mail.starttls.required=true
相关依赖(POM.xml)
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-mail</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-security</artifactId> </dependency>
错误信息
This application has no explicit mapping for /error, so you are seeing this as a fallback. Sat Aug 06 08:39:31 EET 2022 There was an unexpected error (type=Method Not Allowed, status=405). Request method 'GET' not supported org.springframework.web.HttpRequestMethodNotSupportedException: Request method 'GET' not supported
问题排查与解决
1. 路径大小写不匹配(核心原因)
控制器中定义的路径变量是{Id}(首字母大写),但请求URL中的路径是sendmail/b1d0c331-35ac-430d-87ca-1718b06351c3,Spring MVC默认区分大小写。这会导致Spring无法匹配到对应的请求映射,进而返回405错误(系统误以为该路径不支持GET方法)。
修复方案:
将控制器中的路径变量改为小写{id},保持与请求URL一致:
@RequestMapping(value = "/sendmail/{id}", method = { RequestMethod.GET, RequestMethod.POST }) public ResponseEntity<?> eMailBaBsByCustomerId(@PathVariable("id") UUID uuid){ // 方法逻辑不变 }
2. 可选类型转换的潜在问题
代码中BaBs baBs = (BaBs) toList(baBsService.findById(uuid));存在错误:toList方法未定义,强制转换会触发ClassCastException,导致方法进入catch块返回404。虽然这不是当前405错误的直接原因,但也需要修复:
正确的Optional转换方式:
Optional<BaBs> baBsOptional = baBsService.findById(uuid); if (baBsOptional.isPresent()) { BaBs baBs = baBsOptional.get(); baBsEmail.mailBaBs(baBs); return new ResponseEntity<>(baBs, HttpStatus.OK); // 发送邮件用OK更符合语义,CREATED用于资源创建场景 }
3. HTTP方法语义优化
发送邮件属于有副作用的操作,按照REST规范,应使用POST方法而非GET。建议移除GET支持,只保留POST:
// 替换原@RequestMapping注解 @PostMapping("/sendmail/{id}")
4. 安全配置排查(可选)
如果Spring Security配置中限制了该路径的GET请求访问权限,也可能导致405。可检查Security配置类,确保该路径允许对应HTTP方法通过。
内容的提问来源于stack exchange,提问作者Gökhan Karahan

