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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.08 08:22:33