遍历嵌套HashMap时遇Gson类型异常:Expected a string but was BEGIN_ARRAY
问题分析与解决方案
错误根源
你碰到的java.lang.IllegalStateException: Expected a string but was BEGIN_ARRAY异常,核心问题是Java实体类的字段类型和JSON响应结构不匹配——要么是JSON里某个字段是数组,但你在实体类里定义成了字符串;要么是你把JSON数组当成单个对象来解析了。结合你要遍历client下属性、断言message和code的需求,大概率是前一种情况:client下的first_name/last_name/city在JSON里是错误信息数组,但实体类里定义成了字符串类型。
修复步骤
1. 对齐实体类与JSON结构
先明确你的JSON响应结构,举个常见的校验错误JSON示例:
{ "message": "客户端参数校验失败", "code": 400, "client": { "first_name": ["不能为空", "长度不能少于2位"], "last_name": ["不能为空"], "city": ["必须是有效城市名"] } }
对应的实体类要改成如下结构,把client下的属性定义为List<String>来匹配数组:
public class ErrorWithClient { private String message; private int code; private ClientErrors client; // 内部类对应client的结构 public static class ClientErrors { private List<String> first_name; private List<String> last_name; private List<String> city; // 生成getter/setter方法 public List<String> getFirst_name() { return first_name; } public void setFirst_name(List<String> first_name) { this.first_name = first_name; } public List<String> getLast_name() { return last_name; } public void setLast_name(List<String> last_name) { this.last_name = last_name; } public List<String> getCity() { return city; } public void setCity(List<String> city) { this.city = city; } } // 生成message、code、client的getter/setter public String getMessage() { return message; } public void setMessage(String message) { this.message = message; } public int getCode() { return code; } public void setCode(int code) { this.code = code; } public ClientErrors getClient() { return client; } public void setClient(ClientErrors client) { this.client = client; } }
2. 正确解析JSON
如果JSON是单个对象,用常规Gson解析方式:
Gson gson = new Gson(); ErrorWithClient error = gson.fromJson(jsonResponse, ErrorWithClient.class);
如果JSON最外层是数组(比如[{"message": "...", "code": ..., "client": {...}}]),则要解析成列表:
List<ErrorWithClient> errorList = gson.fromJson(jsonResponse, new TypeToken<List<ErrorWithClient>>(){}.getType());
3. 遍历属性并断言
现在可以正常遍历client下的属性,同时断言message和code:
// 断言message和code的正确性 assertEquals("客户端参数校验失败", error.getMessage()); assertEquals(400, error.getCode()); // 遍历client下的各属性错误信息 ClientErrors clientErrors = error.getClient(); // 检查first_name的错误内容 assertTrue(clientErrors.getFirst_name().contains("不能为空")); assertTrue(clientErrors.getFirst_name().contains("长度不能少于2位")); // 检查last_name assertTrue(clientErrors.getLast_name().contains("不能为空")); // 检查city assertTrue(clientErrors.getCity().contains("必须是有效城市名"));
排查小技巧
如果还是找不到不匹配的地方,可以:
- 直接打印JSON字符串,和实体类字段逐一核对,重点看字段类型(是字符串还是数组/对象);
- 用Gson的
JsonParser先解析成JsonElement,手动查看结构:
JsonElement element = JsonParser.parseString(jsonResponse); System.out.println(element); // 打印完整JSON结构,快速定位异常字段
内容的提问来源于stack exchange,提问作者Markus
相关产品推荐
相关产品推荐

