Spring Boot微服务调用Rest接口遭遇NullPointerException问题求助
NullPointerException When Calling Rest Services in Spring Boot Microservice
先帮你定位下问题:从错误栈能看到空指针发生在WebseriesCatalogResource.java第28行,对应代码里的userRating.getUserRating().stream()这一行——这说明userRating本身是null,也就是调用Ratings-Data-Service的接口时没有拿到有效的返回值。下面是常见的原因和解决办法:
1. RestTemplate缺少负载均衡配置
你直接用@Autowired注入了RestTemplate,但如果没给RestTemplate添加@LoadBalanced注解,它是无法识别服务名(比如Ratings-Data-Service)并通过服务发现组件(比如Eureka)找到对应服务的。
解决办法:在配置类里创建RestTemplate时加上@LoadBalanced注解:
@Configuration public class AppConfig { @Bean @LoadBalanced public RestTemplate restTemplate() { return new RestTemplate(); } }
2. 服务发现配置问题
- 确保
Ratings-Data-Service和你的movie-catalog-service都正确注册到了Eureka Server - 检查服务名是否完全匹配:代码里用的是
Ratings-Data-Service,要确保实际注册的服务名大小写、连字符都完全一致(服务名是大小写敏感的)
3. 接口返回值为空或错误
即使服务能访问,Ratings-Data-Service的/rating/user/{userId}接口可能返回null,或者返回404等错误状态码,RestTemplate默认不会抛出异常,而是直接返回null。
解决办法:添加空值判断和响应状态检查,避免空指针:
@RequestMapping("/{userId}") public List<CatalogItem> getCatalog(@PathVariable("userId") String userId){ // 用ResponseEntity获取响应状态和内容 ResponseEntity<UserRating> ratingResponse = rt.getForEntity("http://Ratings-Data-Service/rating/user/"+userId, UserRating.class); if (!ratingResponse.getStatusCode().is2xxSuccessful() || ratingResponse.getBody() == null) { // 处理服务调用失败的情况,返回空列表或默认内容 return Collections.emptyList(); } UserRating userRating = ratingResponse.getBody(); // 先判断userRating.getUserRating()是否为null,避免后续stream()空指针 List<Rating> ratings = Optional.ofNullable(userRating.getUserRating()) .orElse(Collections.emptyList()); return ratings.stream() .map(rating -> { ResponseEntity<Movie> movieResponse = rt.getForEntity("http://Movie-Info-Service/movies/" + rating.getMovieId(), Movie.class); if (movieResponse.getStatusCode().is2xxSuccessful() && movieResponse.getBody() != null) { Movie movie = movieResponse.getBody(); return new CatalogItem(movie.getName(), movie.getDesc(), rating.getRating()); } // 电影服务调用失败时返回默认项 return new CatalogItem("Unknown Movie", "No description available", rating.getRating()); }) .collect(Collectors.toList()); }
额外建议:使用FeignClient简化调用
Spring Cloud的FeignClient可以更优雅地处理服务发现和Rest调用,自动处理负载均衡,还能更方便地配置错误处理,避免手动写大量RestTemplate的代码,你可以考虑替换RestTemplate为FeignClient。
内容的提问来源于stack exchange,提问作者sandeep seervi
相关产品推荐
相关产品推荐

