You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Boot微服务访问localhost端点出现404错误求助

404错误排查:Spring Cloud Gateway访问产品微服务失败

我用Maven构建Spring Boot微服务项目,包含products(产品服务)和config-server(配置中心),本地PostgreSQL有一个product数据库,表结构和数据都已就绪。但通过网关地址http://localhost:8222/api/v1/products访问时,返回404错误,响应内容如下:

{
  "timestamp": 1436442596410,
  "status": 404,
  "error": "Not Found",
  "message": "No message available",
  "path": "/api/v1/products"
}

相关代码文件

产品服务核心代码

ProductController.java

@RestController
@RequestMapping("/api/v1/products")
@RequiredArgsConstructor
public class ProductController {

    private final ProductService service;

    @PostMapping
    public ResponseEntity<Integer> createProduct(
            @RequestBody @Valid ProductRequest request
    ) {
        return ResponseEntity.ok(service.createProduct(request));
    }

    @PostMapping("/purchase")
    public ResponseEntity<List<ProductPurchaseResponse>> purchaseProducts(
            @RequestBody List<ProductPurchaseRequest> request
    ) {
        return ResponseEntity.ok(service.purchaseProducts(request));
    }

    @GetMapping("/{product-id}")
    public ResponseEntity<ProductResponse> findById(
            @PathVariable("product-id") Integer productId
    ) {
        return ResponseEntity.ok(service.findById(productId));
    }

    @GetMapping
    public ResponseEntity<List<ProductResponse>> findAll() {
        return ResponseEntity.ok(service.findAll());
    }
}

ProductService.java

@Service
@RequiredArgsConstructor
public class ProductService {

    private final ProductRepository repository;
    private final ProductMapper mapper;

    public Integer createProduct(
            ProductRequest request
    ) {
        var product = mapper.toProduct(request);
        return repository.save(product).getId();
    }

    public ProductResponse findById(Integer id) {
        return repository.findById(id)
                .map(mapper::toProductResponse)
                .orElseThrow(() -> new EntityNotFoundException("Product not found with ID:: " + id));
    }

    public List<ProductResponse> findAll() {
        return repository.findAll()
                .stream()
                .map(mapper::toProductResponse)
                .collect(Collectors.toList());
    }

    @Transactional(rollbackFor = ProductPurchaseException.class)
    public List<ProductPurchaseResponse> purchaseProducts(
            List<ProductPurchaseRequest> request
    ) {
        var productIds = request
                .stream()
                .map(ProductPurchaseRequest::productId)
                .toList();
        var storedProducts = repository.findAllByIdInOrderById(productIds);
        if (productIds.size() != storedProducts.size()) {
            throw new ProductPurchaseException("One or more products does not exist");
        }
        var sortedRequest = request
                .stream()
                .sorted(Comparator.comparing(ProductPurchaseRequest::productId))
                .toList();
        var purchasedProducts = new ArrayList<ProductPurchaseResponse>();
        for (int i = 0; i < storedProducts.size(); i++) {
            var product = storedProducts.get(i);
            var productRequest = sortedRequest.get(i);
            if (product.getAvailableQuantity() < productRequest.quantity()) {
                throw new ProductPurchaseException("Insufficient stock quantity for product with ID:: " + productRequest.productId());
            }
            var newAvailableQuantity = product.getAvailableQuantity() - productRequest.quantity();
            product.setAvailableQuantity(newAvailableQuantity);
            repository.save(product);
            purchasedProducts.add(mapper.toproductPurchaseResponse(product, productRequest.quantity()));
        }
        return purchasedProducts;
    }

}

ProductApplication.java

@SpringBootApplication
public class ProductApplication {

    public static void main(String[] args) {
        SpringApplication.run(ProductApplication.class, args);
    }

}

配置中心的服务配置

gateway-service.yml

server:
  port: 8222
spring:
  cloud:
    gateway:
      discovery:
        locator:
          enabled: true
      routes: 
        - id: product-service
          uri: lb:http://PRODUCT-SERVICE
          predicates:
            - Path=/api/v1/products/**

product-service.yml

server:
  port: 8050
spring:
  datasource:
    driver-class-name: org.postgresql.Driver
    url: jdbc:postgresql://localhost:5432/product
    username: XXX
    password: XXX
  jpa:
    hibernate:
      ddl-auto: validate
    database: postgresql
    database-platform: org.hibernate.dialect.PostgreSQLDialect
  flyway:
    baseline-on-migrate: true
    enabled: true
    baseline-description: "init"
    baseline-version: 0
    user: ${spring.datasource.username}
    password: ${spring.datasource.password}

Eureka客户端配置(application.yml)

eureka:
  instance:
    hostname: localhost
  client:
    service-url:
      defaultZone: http://localhost:8761/eureka
name:
  value: XXX
spring:
  cloud:
    config:
      override-system-properties: false

management:
  tracing:
    sampling:
      probability: 1.0

已验证操作

  • 所有微服务已成功注册到Eureka(地址http://localhost:8761)
  • 项目文件结构及pom.xml配置无错误
  • Flyway已成功连接PostgreSQL并完成数据初始化

排查方向

  1. 验证产品服务自身可用性:直接访问http://localhost:8050/api/v1/products,确认是否能正常返回数据。若直接访问也404,检查:
    • 控制器类是否在ProductApplication所在包或子包下,确保被Spring扫描到
    • 产品服务是否配置了server.servlet.context-path,导致路径前缀变化
  2. 检查网关路由配置:
    • 确认Eureka中产品服务的注册名称是否为PRODUCT-SERVICE(Eureka服务名称大小写敏感)
    • 网关路由断言Path=/api/v1/products/**是否匹配请求路径,可调整为Path=/api/v1/products或Path=/api/v1/products/**测试
    • 开启网关日志,查看请求转发详情,确认请求是否正确路由到产品服务
  3. 检查负载依赖:确保网关项目依赖中包含spring-cloud-starter-loadbalancer,否则lb://协议无法生效
  4. 检查端口通信:确认本地防火墙或安全策略未阻止网关(8222)与产品服务(8050)之间的通信

内容的提问来源于stack exchange,提问作者dqdq dqsss

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.20 18:05:55