使用Open Feign调用微服务API时遭遇302错误求助
OpenFeign调用返回302错误排查与解决
我在学习微服务技术栈时,以Eureka作为服务注册中心,通过Open Feign从employee service调用address service的API时遇到302错误,但直接调用该API完全正常。
错误日志
Request processing failed: feign.FeignException: [302] during [GET] to [http://address-service/address-app/api/address/1] [AddressClient#getAddressByEmployeeId(Integer)]: [[{"addressId":1,"addressLine1":"addressline 1","addressLine2":"addressLine2","cityName":"city","employeeId":1,"stateName":"state","zipCode":"021547"},{"addressId":3,"addressLine1":"addressline1","addressLine2":"addressLine2","cityName":"city","employeeId":1,"stateName":"state","zipCode":"236525"}]] with root cause feign.FeignException: [302] during [GET] to [http://address-service/address-app/api/address/1] [AddressClient#getAddressByEmployeeId(Integer)]: [[{"addressId":1,"addressLine1":"addressline1","addressLine2":"addressline2","cityName":"city","employeeId":1,"stateName":"state","zipCode":"021547"},{"addressId":3,"addressLine1":"addreessLine1","addressLine2":"addressLine2","cityName":"city","employeeId":1,"stateName":"state","zipCode":"236525"}]]
相关代码片段
Address Service 启动类与配置
package com.spring.cloud.asign; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.client.discovery.EnableDiscoveryClient; @SpringBootApplication @EnableDiscoveryClient public class AddressServiceApplication { public static void main(String[] args) { SpringApplication.run(AddressServiceApplication.class, args); } }
application.properties:
spring.application.name=address-service server.servlet.context-path=/address-app/api server.port=8080 spring.datasource.url=jdbc:postgresql://localhost:5432/postgres?currentSchema=asignaddrservice spring.datasource.username=postgres spring.jpa.hibernate.ddl-auto=update
Employee Service 启动类、配置、Feign客户端与业务代码
package com.spring.cloud.asign; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.client.discovery.EnableDiscoveryClient; import org.springframework.cloud.openfeign.EnableFeignClients; @SpringBootApplication @EnableDiscoveryClient @EnableFeignClients public class EmployeeServiceApplication { public static void main(String[] args) { SpringApplication.run(EmployeeServiceApplication.class, args); } }
application.properties:
spring.application.name=employee-service server.servlet.context-path=/employee-app/api server.port=8085 # --- Datasource Connection --- spring.datasource.url=jdbc:mysql://localhost:3306/employee-management spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver spring.datasource.username=root # --- JPA & Hibernate Settings --- spring.jpa.database-platform=org.hibernate.dialect.MySQLDialect spring.jpa.hibernate.ddl-auto=update #spring.jpa.show-sql=true
Feign客户端:
package com.spring.cloud.asign.client; import java.util.List; import org.springframework.cloud.openfeign.FeignClient; 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 com.spring.cloud.asign.model.AddressResponse; @FeignClient(value = "address-service", path = "/address-app/api") public interface AddressClient { @PostMapping("/address") public AddressResponse addAddress(@RequestBody AddressResponse addRes); @GetMapping("/address/{empId}") public List<AddressResponse> getAddressByEmployeeId(@PathVariable Integer empId); @GetMapping("/address") public List<AddressResponse> getAllAddress(); }
业务服务类:
package com.spring.cloud.asign.services; import java.util.List; import java.util.stream.Collectors; import org.modelmapper.ModelMapper; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import com.spring.cloud.asign.client.AddressClient; import com.spring.cloud.asign.entity.Employees; import com.spring.cloud.asign.model.AddressResponse; import com.spring.cloud.asign.model.EmployeeResponse; import com.spring.cloud.asign.repo.EmployeeRepository; @Service public class EmployeeServices { @Autowired private EmployeeRepository employeeRepository; @Autowired private ModelMapper modelMapper; @Autowired private AddressClient addClient; public EmployeeResponse fetchEmployee(Integer empId) { Employees emp = employeeRepository.findById(empId).orElseThrow(); List<AddressResponse> addrRes = addClient.getAddressByEmployeeId(empId); EmployeeResponse empResponse = modelMapper.map(emp, EmployeeResponse.class); empResponse.setAddResList(addrRes); return empResponse; } }
排查与解决步骤
1. 定位302错误根源
302代表临时重定向,虽然错误日志中已返回正确响应数据,但Feign默认不会自动处理重定向,直接抛出异常。通常是目标服务API因路径匹配规则触发了Spring MVC的自动重定向。
2. 统一路径末尾的斜杠匹配
检查Address Service的Controller路径与Feign客户端的路径是否一致:
- 如果Address Service的Controller路径为
@GetMapping("/address/{empId}/")(末尾带/),而Feign客户端路径是@GetMapping("/address/{empId}")(末尾无/),Spring MVC会自动重定向到带/的路径,导致302。 - 解决办法:修改Feign客户端的API路径,统一末尾的/:
@GetMapping("/address/{empId}/") public List<AddressResponse> getAddressByEmployeeId(@PathVariable Integer empId);
3. 配置Feign自动跟随重定向
若不想修改路径,可通过配置让Feign自动处理重定向。在Employee Service的application.properties中添加:
# 全局配置所有Feign客户端允许跟随重定向 feign.client.config.default.follow-redirects=true feign.client.config.default.max-redirects=5 # 或仅针对address-service配置 feign.client.config.address-service.follow-redirects=true feign.client.config.address-service.max-redirects=5
4. 验证Eureka服务注册地址
确认address-service在Eureka控制台中注册的地址正确,无多余路径或端口错误,避免Feign调用时解析到错误地址触发重定向。
总结
最常见的原因是路径末尾斜杠不匹配导致的Spring MVC自动重定向,优先统一路径格式,或配置Feign允许跟随重定向即可解决问题。
内容的提问来源于stack exchange,提问作者Vijayarajakumar
相关产品推荐
相关产品推荐

