如何从OMDb接口返回的HashMap中提取ArrayList类型的Search数据?
解决OMDb接口调用的Search字段类型转换异常
你的代码里有三个核心问题导致了ArrayList cannot be cast to String的异常:
- 错误声明了
Map<String, String>泛型 —— OMDb返回的Search是数组类型,不是字符串,强转必然报错。 - 直接把
ResponseSpec传给ObjectMapper——ResponseSpec是响应规范对象,不是JSON数据源,不能直接用来反序列化。 bodyToMono(String.class).map()代码不完整 ——map方法必须传入处理逻辑,而且这里完全没必要手动处理JSON。
下面是两种可行的解决方案:
方案一:用实体类直接反序列化(推荐)
这是Spring WebClient的最佳实践,避免手动解析JSON的繁琐和错误。
1. 创建匹配返回结构的实体类
// 对应OMDb的顶层响应 public class OmdbResponse { private List<Movie> Search; private String totalResults; private String Response; // 自动生成Getter、Setter方法 } // 电影实体类,对应Search里的每个元素 public class Movie { private String Title; private String Year; private String imdbID; private String Type; private String Poster; // 自动生成Getter、Setter方法 }
2. 优化WebClient调用代码
WebClient webClient = WebClient.create(); String searchKeyword = "batman"; String apiKey = "你的OMDb密钥"; // 替换成实际API Key // 用URI占位符构建请求,避免字符串拼接的编码问题 OmdbResponse omdbResponse = webClient.get() .uri("http://www.omdbapi.com/?apikey={apiKey}&s={search}&type=movie&page=1", apiKey, searchKeyword) .retrieve() .bodyToMono(OmdbResponse.class) // 直接反序列化为实体类 .block(); // 同步场景用block,异步场景改用subscribe // 处理返回的电影列表 if (omdbResponse != null && "True".equals(omdbResponse.getResponse())) { List<Movie> movieList = omdbResponse.getSearch(); for (Movie movie : movieList) { // 逐个处理电影数据,比如打印标题 System.out.println("电影:" + movie.getTitle() + ",年份:" + movie.getYear()); } }
方案二:手动解析JSON(不推荐,仅作参考)
如果一定要用ObjectMapper手动处理,需要修正泛型和数据源:
WebClient webClient = WebClient.create(); String searchKeyword = "batman"; String apiKey = "你的OMDb密钥"; // 先获取完整的响应体字符串 String responseBody = webClient.get() .uri("http://www.omdbapi.com/?apikey={apiKey}&s={search}&type=movie&page=1", apiKey, searchKeyword) .retrieve() .bodyToMono(String.class) .block(); ObjectMapper objectMapper = new ObjectMapper(); // 用Map<String, Object>接收,因为值可能是字符串或数组 Map<String, Object> responseMap = objectMapper.readValue(responseBody, Map.class); // 提取Search字段并强制转换为List List<Map<String, String>> searchRawList = (List<Map<String, String>>) responseMap.get("Search"); // 转换为Movie对象列表 List<Movie> movieList = new ArrayList<>(); for (Map<String, String> movieMap : searchRawList) { Movie movie = objectMapper.convertValue(movieMap, Movie.class); movieList.add(movie); } // 后续处理电影数据 for (Movie movie : movieList) { System.out.println(movie.getTitle()); }
关键提醒
- 永远不要用
Map<String, String>接收包含数组的JSON,泛型必须和实际JSON结构匹配。 - WebClient的
bodyToMono可以直接处理JSON反序列化,尽量避免手动解析,减少出错概率。 - 构建URI时用占位符,避免直接拼接字符串导致的编码错误(比如搜索关键词含特殊字符时)。
内容的提问来源于stack exchange,提问作者An Nguyen Thanh
相关产品推荐
相关产品推荐

