
在使用spring boot构建restful api并结合postman进行测试时,常见的404 “not found” 错误往往源于对api路径的误解。本文将深入探讨spring boot中api路径的构成,特别是`@requestmapping`注解的使用,并指导如何正确配置postman请求url,以避免因包含不必要的应用上下文路径而导致的404错误,确保api请求能够准确路由到目标控制器方法。
1. 理解Spring Boot中的API路径映射
Spring Boot应用程序通过注解来定义API端点及其对应的处理方法。其中,@RestController 标识一个类为RESTful控制器,@RequestMapping、@GetMapping、@PostMapping 等注解则用于定义请求的URL路径和HTTP方法。
1.1 @RequestMapping 注解的作用
@RequestMapping 注解可以应用于类级别和方法级别:
类级别: 定义控制器中所有方法的共同基础路径。例如,@RequestMapping(“/api”) 意味着该控制器中的所有方法都将以 /api 开头。方法级别: 定义具体方法的路径,它会与类级别的路径拼接形成完整的API路径。
1.2 应用程序上下文路径
默认情况下,Spring Boot应用程序在嵌入式服务器(如Tomcat)上运行时,其上下文路径是根路径 /。这意味着,除非在 application.properties 或 application.yml 中明确配置了 server.servlet.context-path 属性,否则应用程序的根URL就是 http://localhost:8080/ (假设端口是8080)。
例如,如果 application.properties 中没有 server.servlet.context-path 配置,那么你的应用程序的根路径就是 /。如果配置了 server.servlet.context-path=/my-app,那么应用程序的根路径将是 /my-app。
2. 404 “Not Found” 错误分析
当Spring Boot应用程序返回404错误时,通常表示服务器未能找到与请求URL匹配的资源或处理程序。这可能是由以下原因造成的:
URL路径不匹配: 请求的URL与任何定义的API端点都不匹配。HTTP方法不匹配: 请求的HTTP方法(GET, POST, PUT, DELETE等)与API端点期望的方法不符。控制器未被扫描: Spring Boot未能发现并注册控制器。应用程序未启动或端口错误: 应用程序未成功启动,或者请求发送到了错误的端口。
在本文提供的场景中,Postman请求的URL是 http://localhost:8080/mdb-spring-boot-product-organizer/api/addProduct,而控制器代码如下:
package com.example.mdbspringbootproductorganizer.controller;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.RestController;// ... 其他导入@RestController@RequestMapping("/api") // 类级别路径public class ProductController { // ... 依赖注入 @PostMapping("/addProduct") // 方法级别路径 public String saveProduct(@RequestBody Product product) { // ... 保存逻辑 return "Added product with id : " + product.getId(); } // ... 其他方法}
从代码中可以看出,ProductController 的类级别路径是 /api,saveProduct 方法的路径是 /addProduct。因此,该方法的完整有效路径应该是 /api/addProduct。
问题在于请求URL中多了一个 /mdb-spring-boot-product-organizer。这个部分通常是项目名称,但在默认的Spring Boot配置下,它不应该作为API路径的一部分。Spring Boot应用程序通常直接运行在根上下文路径下,因此,控制器定义的 /api/addProduct 路径会直接映射到 http://localhost:8080/api/addProduct。
绘蛙AI修图
绘蛙平台AI修图工具,支持手脚修复、商品重绘、AI扩图、AI换色
285 查看详情
3. 解决方案:修正Postman请求URL
解决此404错误的关键是移除URL中不必要的应用程序上下文路径。
正确的Postman请求URL应该是:
http://localhost:8080/api/addProduct
操作步骤:
打开Postman。选择请求方法: 对于 saveProduct 方法,应选择 POST。输入正确的URL: 在URL输入框中填写 http://localhost:8080/api/addProduct。配置请求体 (Body):选择 Body 标签页。选择 raw 类型。选择 JSON 格式。输入符合 Product 模型结构的JSON数据。
示例JSON请求体:
{ "id": 1, "name": "Sample Product", "listedPrice": 19.99, "purchasePrice": 10.50, "condition": "New", "brand": "BrandX", "shelf": "A", "bin": 101}
4. 完整的Spring Boot应用示例代码
为了提供一个完整的上下文,以下是涉及到的关键代码片段:
4.1 Product 模型 (POJO)
package com.example.mdbspringbootproductorganizer.model;import org.springframework.data.annotation.Id;import org.springframework.data.mongodb.core.mapping.Document;@Document(collection = "ProductInventory") // 映射到MongoDB集合public class Product { @Id // 标识为主键 private int id; private String name; private double listedPrice; private double purchasePrice; private String condition; private String brand; private char shelf; private int bin; // 构造函数 public Product(int id, String name, double listedPrice, double purchasePrice, String condition, String brand, char shelf, int bin) { this.id = id; this.name = name; this.listedPrice = listedPrice; this.purchasePrice = purchasePrice; this.condition = condition; this.brand = brand; this.shelf = shelf; this.bin = bin; } // Getter和Setter方法 public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public double getListedPrice() { return listedPrice; } public void setListedPrice(double listedPrice) { this.listedPrice = listedPrice; } public double getPurchasePrice() { return purchasePrice; } public void setPurchasePrice(double purchasePrice) { this.purchasePrice = purchasePrice; } public String getCondition() { return condition; } public void setCondition(String condition) { this.condition = condition; } public String getBrand() { return brand; } public void setBrand(String brand) { this.brand = brand; } public char getShelf() { return shelf; } public void setShelf(char shelf) { this.shelf = shelf; } public int getBin() { return bin; } public void setBin(int bin) { this.bin = bin; } @Override public String toString() { return "Product [id=" + id + ", name=" + name + ", listedPrice=" + listedPrice + ", purchasePrice=" + purchasePrice + ", condition=" + condition + ", brand=" + brand + ", shelf=" + shelf + ", bin=" + bin + "]"; }}
4.2 ProductRepository 接口
package com.example.mdbspringbootproductorganizer.repository;import org.springframework.data.mongodb.repository.MongoRepository;import com.example.mdbspringbootproductorganizer.model.Product;public interface ProductRepository extends MongoRepository { // MongoRepository 提供了基本的CRUD操作,无需额外实现}
4.3 ProductController 控制器
package com.example.mdbspringbootproductorganizer.controller;import java.util.List;import java.util.Optional;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.web.bind.annotation.DeleteMapping;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.RestController;import com.example.mdbspringbootproductorganizer.model.Product;import com.example.mdbspringbootproductorganizer.repository.ProductRepository;@RestController@RequestMapping("/api") // 所有API的基础路径public class ProductController { @Autowired private ProductRepository repository; @PostMapping("/addProduct") // POST请求到 /api/addProduct public String saveProduct(@RequestBody Product product) { repository.save(product); return "Added product with id : " + product.getId(); } @GetMapping("/findAllProducts") // GET请求到 /api/findAllProducts public List getProducts() { return repository.findAll(); } @GetMapping("/findAllProducts/{id}") // GET请求到 /api/findAllProducts/{id} public Optional getProduct(@PathVariable int id) { return repository.findById(id); } @DeleteMapping("/delete/{id}") // DELETE请求到 /api/delete/{id} public String deleteBook(@PathVariable int id) { repository.deleteById(id); return "Product deleted with id: " + id; }}
4.4 MdbSpringBootApplication 主类
package com.example.mdbspringbootproductorganizer;import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;import org.springframework.data.mongodb.repository.config.EnableMongoRepositories;@SpringBootApplication // 启用Spring Boot自动配置@EnableMongoRepositories // 启用Spring Data MongoDB仓库public class MdbSpringBootApplication { public static void main(String[] args) { SpringApplication.run(MdbSpringBootApplication.class, args); }}
5. 注意事项与调试技巧
检查应用程序日志: Spring Boot启动时会在控制台输出日志,确认应用程序是否成功启动,是否有任何错误或警告信息。例如,Started MdbSpringBootApplication… 表示启动成功。确认端口: 确保Postman请求的端口(默认8080)与Spring Boot应用程序实际运行的端口一致。HTTP方法匹配: 再次检查Postman中选择的HTTP方法是否与控制器方法上的注解(如 @PostMapping)一致。请求头 (Headers): 对于POST请求发送JSON数据,通常需要设置 Content-Type: application/json 请求头。Postman在选择 Body 为 raw 和 JSON 时会自动添加此头部。MongoDB连接: 确保MongoDB服务正在运行,并且应用程序的 application.properties 或 application.yml 中配置的MongoDB连接信息正确无误。浏览器测试GET请求: 对于简单的GET请求,可以直接在浏览器中输入URL进行测试,例如 http://localhost:8080/api/findAllProducts,这有助于快速验证路径是否正确。
总结
Spring Boot应用程序的404 “Not Found” 错误,尤其在使用Postman进行API测试时,最常见的原因是请求URL与定义的API路径不匹配。核心在于理解 @RequestMapping 注解如何构建API路径,以及应用程序默认的上下文路径。通过移除URL中不必要的项目名称或应用程序上下文路径,并确保HTTP方法和请求体配置正确,即可有效解决此类问题。在开发过程中,仔细核对URL、查看应用程序日志以及利用调试工具是排查问题的关键。
以上就是Spring Boot应用Postman 404错误排查与API路径配置指南的详细内容,更多请关注创想鸟其它相关文章!
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 chuangxiangniao@163.com 举报,一经查实,本站将立刻删除。
发布者:程序猿,转转请注明出处:https://www.chuangxiangniao.com/p/1083665.html
微信扫一扫
支付宝扫一扫