java.lang.ClassCastException:java.util.LinkedHashMap无法强制转换为com.testing.models.Account

java.lang.ClassCastException:java.util.LinkedHashMap无法强制转换为com.testing.models.Account,java,jackson,rest-assured,Java,Jackson,Rest Assured,我得到以下错误: java.lang.ClassCastException: java.util.LinkedHashMap cannot be cast to com.testing.models.Account 用下面的代码 final int expectedId = 1; Test newTest = create(); int expectedResponseCode = Response.SC_OK; ArrayList<Account> account = gi

我得到以下错误:

java.lang.ClassCastException: java.util.LinkedHashMap cannot be cast to com.testing.models.Account
用下面的代码

final int expectedId = 1;

Test newTest = create();

int expectedResponseCode = Response.SC_OK;

ArrayList<Account> account = given().when().expect().statusCode(expectedResponseCode)
    .get("accounts/" + newTest.id() + "/users")
    .as(ArrayList.class);
assertThat(account.get(0).getId()).isEqualTo(expectedId);
final int expectedId=1;
Test newTest=create();
int expectedResponseCode=Response.SC_OK;
ArrayList帐户=给定().when().expect().statusCode(expectedResponseCode)
.get(“accounts/”+newTest.id()+“/users”)
.as(ArrayList.class);
assertThat(account.get(0.getId()).isEqualTo(expectedId);

有什么原因使我不能做
get(0)

问题来自Jackson。当它没有足够的关于反序列化到哪个类的信息时,它使用
LinkedHashMap

因为您没有通知Jackson您的
ArrayList
的元素类型,所以它不知道您想要反序列化到
帐户的
ArrayList
。因此,它又回到了默认状态

相反,您可能可以使用
作为(JsonNode.class)
,然后以比rest-assured更丰富的方式处理
ObjectMapper
。大概是这样的:

ObjectMapper mapper = new ObjectMapper();

JsonNode accounts = given().when().expect().statusCode(expectedResponseCode)
    .get("accounts/" + newClub.getOwner().getCustId() + "/clubs")
    .as(JsonNode.class);


//Jackson's use of generics here are completely unsafe, but that's another issue
List<Account> accountList = mapper.convertValue(
    accounts, 
    new TypeReference<List<Account>>(){}
);

assertThat(accountList.get(0).getId()).isEqualTo(expectedId);
ObjectMapper mapper=new ObjectMapper();
JsonNode帐户=给定().when().expect().statusCode(expectedResponseCode)
.get(“accounts/”+newClub.getOwner().getCustId()+“/clubs”)
.as(JsonNode.class);
//杰克逊在这里使用仿制药是完全不安全的,但这是另一个问题
List accountList=mapper.convertValue(
账户,
新类型引用(){}
);
assertThat(accountList.get(0.getId()).isEqualTo(expectedId);
我遇到了一个类似的异常(但问题不同)
java.lang.ClassCastException:java.util.LinkedHashMap无法转换为org.bson.Document,幸运的是它更容易解决:

而不是

List<Document> docs = obj.get("documents");
Document doc = docs.get(0)
List docs=obj.get(“文档”);
Document doc=docs.get(0)
这在第二行给出了错误,可以使用

List<Document> docs = obj.get("documents");
Document doc = new Document(docs.get(0));
List docs=obj.get(“文档”);
单据单据=新单据(docs.get(0));
尝试以下操作:

POJO pojo = mapper.convertValue(singleObject, POJO.class);
或:

List pojos=mapper.convertValue(
对象列表,
新类型引用(){});

有关更多信息,请参阅。

我可以通过使用
CollectionType
而不是
TypeReference
来缓解JSON数组到LinkedHashMap对象集合的问题。 这就是我所做和工作的

public <T> List<T> jsonArrayToObjectList(String json, Class<T> tClass) throws IOException {
    ObjectMapper mapper = new ObjectMapper();
    CollectionType listType = mapper.getTypeFactory().constructCollectionType(ArrayList.class, tClass);
    List<T> ts = mapper.readValue(json, listType);
    LOGGER.debug("class name: {}", ts.get(0).getClass().getName());
    return ts;
}
public <T> List<T> jsonArrayToObjectList(String json, Class<T> tClass) throws IOException {
    ObjectMapper mapper = new ObjectMapper();
    List<T> ts = mapper.readValue(json, new TypeReference<List<T>>(){});
    LOGGER.debug("class name: {}", ts.get(0).getClass().getName());
    return ts;
}

我使用此方法反序列化XML并转换类型:

public <T> Object deserialize(String xml, Class objClass ,TypeReference<T> typeReference ) throws IOException {
    XmlMapper xmlMapper = new XmlMapper();
    Object obj = xmlMapper.readValue(xml,objClass);
    return  xmlMapper.convertValue(obj,typeReference );   
}
公共对象反序列化(字符串xml、类objClass、类型引用TypeReference)引发IOException{
XmlMapper XmlMapper=新的XmlMapper();
objectobj=xmlMapper.readValue(xml,objClass);
返回xmlMapper.convertValue(obj,typeReference);
}
这就是电话:

List<POJO> pojos = (List<POJO>) MyUtilClass.deserialize(xml, ArrayList.class,new TypeReference< List< POJO >>(){ });
listpojo=(List)MyUtilClass.deserialize(xml,ArrayList.class,newtypereference>(){});

当您使用jackson从字符串映射到具体类时,尤其是当您使用泛型类型时。那么这个问题可能会因为不同的类加载器而发生。我有一次遇到了下面的场景:

项目B依赖于库A

图书馆A:

public class DocSearchResponse<T> {
 private T data;
}
我使用库中的ServiceA进行查询和数据转换

public class ServiceAImpl extends ServiceA<Account> {
    
}

用两种方法解决问题

  • 什么类型是对象
  • publicTJSONTObject(字符串json,类类型){
    T目标=null;
    试一试{
    target=objectMapper.readValue(json,类型);
    }catch(在此输入代码处理异常e){
    e、 printStackTrace();
    }
    回报目标;
    }
    
  • 类型为集合包裹对象
  • publicTJSONTObject(字符串json,类型引用类型){
    T目标=null;
    试一试{
    target=objectMapper.readValue(json,类型);
    }捕获(JsonProcessingException e){
    e、 printStackTrace();
    }
    回报目标;
    }
    
    这是我在项目中使用的东西,返回了Json对象,我将其转换为POJO列表,然后访问元素。 我从另一个微服务获取Json对象的输入

    主要是:- JsonNode stocks=restemplate.getForObject(“http://localhost:2000/stocks/qty,JsonNode.class); List stockList=mapper.convertValue(stocks,new TypeReference(){})

    @GetMapping("/")
        public List<Stock_id_qty> checkQty() throws JsonProcessingException {
            ObjectMapper mapper = new ObjectMapper();
            JsonNode stocks = restTemplate.getForObject("http://localhost:2000/stocks/qty", JsonNode.class);
            List<Stock_id_qty> stockList = mapper.convertValue(stocks, new TypeReference<List<Stock_id_qty>>() {});
            List<Stock_id_qty> result = new ArrayList<>();
            for(Stock_id_qty s : stockList){
                if(s.getStockQty() < 10)
                {
                    result.add(s);
                }
            }
            return result;
        }
    
    @GetMapping(“/”)
    public List checkQty()引发JsonProcessingException{
    ObjectMapper mapper=新的ObjectMapper();
    JsonNode stocks=restTemplate.getForObject(“http://localhost:2000/stocks/qty,JsonNode.class);
    List stockList=mapper.convertValue(stocks,new TypeReference(){});
    列表结果=新建ArrayList();
    用于(库存编号数量:库存清单){
    如果(s.getStockQty()<10)
    {
    结果。添加(s);
    }
    }
    返回结果;
    }
    
    无法强制转换为什么?错误消息的其余部分是什么?@OliverCharlesworth还添加了整个StackTrace什么是
    帐户
    ?你为什么要从地图上转换到它?对于我们这些可能不熟悉这个库的人,你能说出这个
    给定的()是什么类吗
    方法是从?@DaveNewton
    帐户静态导入的
    是Dropwizard中的一个模型,它使用
    com.fasterxml.jackson.databind.annotations
    您还可以设置响应asString(),省去了额外的转换-readValue将接受一个字符串作为第一个参数。@bigdutsch:重新访问这个,当
    convertValue
    可以一步完成时,我不需要在那里转换回令牌。转到字符串也有效。+1表示“convertValue”。我有一个案例,我需要从json中读取一个特定属性作为列表,这正是我所需要的。我还保存了我的问题。谢谢大家!+1,您案例中的不同之处在于方法本身是泛型的,因此
    T
    无法通过TypeToken进行具体化,这通常更容易实现。就我个人而言,我更喜欢G
    public class Account{
     private String name;
     //come with other attributes
    }
    
    public class ServiceAImpl extends ServiceA<Account> {
        
    }
    
    public class MakingAccountService {
        @Autowired
        private ServiceA service;
        public void execute(Criteria criteria){
          
            DocSearchResponse<Account> result = service.query(criteria);
            Account acc = result.getData(); //  java.util.LinkedHashMap cannot be cast to com.testing.models.Account
        }
    }
    
    public class ServiceAImpl extends ServiceA<Account> {
            @Override
            public DocSearchResponse<T> convertJson(String result){
             return mapper.readValue(result, new TypeReference<DocSearchResponse<T>>() {});
          }
        }
     }
    
    public <T> T jsonToObject(String json, Class<T> type) {
            T target = null;
            try {
                target = objectMapper.readValue(json, type);
            } catch (Jsenter code hereonProcessingException e) {
                e.printStackTrace();
            }
        
            return target;
        }
    
    public <T> T jsonToObject(String json, TypeReference<T> type) {
        T target = null;
        try {
            target = objectMapper.readValue(json, type);
        } catch (JsonProcessingException e) {
            e.printStackTrace();
        }
        return target;
    }
    
    @GetMapping("/")
        public List<Stock_id_qty> checkQty() throws JsonProcessingException {
            ObjectMapper mapper = new ObjectMapper();
            JsonNode stocks = restTemplate.getForObject("http://localhost:2000/stocks/qty", JsonNode.class);
            List<Stock_id_qty> stockList = mapper.convertValue(stocks, new TypeReference<List<Stock_id_qty>>() {});
            List<Stock_id_qty> result = new ArrayList<>();
            for(Stock_id_qty s : stockList){
                if(s.getStockQty() < 10)
                {
                    result.add(s);
                }
            }
            return result;
        }