Spring微服务中/products/all接口触发NumberFormatException求助
Alright, let's break down why this is happening and how to fix it.
Root Cause
You're hitting a route conflict between your custom @GetMapping("/products/all") endpoint and the auto-generated REST endpoints created by Spring Data REST.
When you use Spring Data REST with a repository like ProductRepository (which extends JpaRepository or similar), it automatically creates endpoints like /products/{id} to fetch a single product by its Long ID. Spring's request mapping matcher prioritizes variable paths (like {id}) over literal paths when checking incoming requests. So when you hit /products/all, Spring Data REST's RepositoryEntityController picks it up first, treating "all" as a product ID and trying to convert it to a Long—hence the ConversionFailedException.
Solutions
1. Adjust Your Custom Endpoint Path
The simplest fix is to change your custom endpoint to a path that won't clash with the auto-generated /{id} pattern. For example:
@RestController @RequestMapping("/products") public class ProductController { @GetMapping("/list") // Changed from "/all" to "/list" public ResponseEntity<List<Product>> getAllProducts() { // Your service logic here } }
Now hitting /products/list will correctly route to your custom controller instead of being intercepted by Spring Data REST.
2. Use a Request Parameter Instead of a Path Segment
If you prefer to keep the "all" concept but avoid path conflicts, swap the path segment for a request parameter:
@RestController @RequestMapping("/products") public class ProductController { @GetMapping public ResponseEntity<List<Product>> getProducts(@RequestParam(required = false) Boolean all) { if (Boolean.TRUE.equals(all)) { return ResponseEntity.ok(productService.getAllProducts()); } // Handle other cases (like filtered searches) if needed } }
Call this endpoint with /products?all=true—no path conflict, and the intent of the request is still clear.
3. Shift Spring Data REST to a Different Base Path
Configure Spring Data REST to serve its endpoints under a unique base path, so they don't overlap with your custom controllers. Add this to your application.properties:
spring.data.rest.base-path=/api
Or in application.yml:
spring: data: rest: base-path: /api
Now Spring Data REST's endpoints will live at /api/products/{id}, and your custom /products/all endpoint will work as expected without interference.
4. Give Your Custom Controller Higher Priority
Force Spring to check your custom controller first by adding the @Order annotation with the highest precedence:
@RestController @RequestMapping("/products") @Order(Ordered.HIGHEST_PRECEDENCE) // Ensures your controller is matched first public class ProductController { @GetMapping("/all") public ResponseEntity<List<Product>> getAllProducts() { // Your service logic here } }
This tells Spring to prioritize your literal /all path over Spring Data REST's variable {id} path.
Verify the Fix
After applying any of these solutions, test your endpoint—you should no longer see the ConversionFailedException, and the request will be handled by your custom controller as intended.
内容的提问来源于stack exchange,提问作者Enrique GF

