如何使用 ResponseEntity 返回 JSONObject 而不是 HashMap? (未找到类型返回值的转换器:类 org.json.JSONObject)

Posted

技术标签:

【中文标题】如何使用 ResponseEntity 返回 JSONObject 而不是 HashMap? (未找到类型返回值的转换器:类 org.json.JSONObject)【英文标题】:How to return a JSONObject instead HashMap with ResponseEntity? (No converter found for return value of type: class org.json.JSONObject) 【发布时间】:2019-02-23 15:23:41 【问题描述】:

我能够从基于 Spring Boot 构建的 REST API 以 JSON 形式返回 HashMap。这是我的方法:

@ResponseBody
@Transactional
@GetMapping("create_coinmarketcap_snapshot")
public ResponseEntity<HashMap> create_coinmarketcap_snapshot() 

    String jsonString = callURL("https://api.coinmarketcap.com/v2/ticker/?limit=5");

    JSONArray coinmarketcapsnapshotsArray = new JSONArray();
    JSONObject coinmarketcapsnapshotsJSONObject = new JSONObject();
    HashMap<Integer, CoinmarketcapSnapshot> coinmarketcapsnapshotsHashMap = new HashMap<>();

    try 

        JSONObject jsonObject = new JSONObject(jsonString);
        JSONObject jsonObjectData = jsonObject.getJSONObject("data");
        Iterator<?> keys = jsonObjectData.keys();

        int count = 0;

        while (keys.hasNext()) 

            count++;

            String key = (String) keys.next();

            if (jsonObjectData.get(key) instanceof JSONObject) 

                JSONObject jsonObjectDataCrypto = jsonObjectData.getJSONObject(key);
                JSONObject jsonObjectDataCryptoQuotes = jsonObjectDataCrypto.getJSONObject("quotes").getJSONObject("USD");

                CoinmarketcapSnapshot coinmarketcapsnapshotObject = new CoinmarketcapSnapshot();
                String dateFormatted = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss").format(Calendar.getInstance().getTime());
                coinmarketcapsnapshotObject.setTitle(jsonObjectDataCrypto.get("name") + " - " + dateFormatted);
                coinmarketcapsnapshotObject.setCryptocurrencyId((int) jsonObjectDataCrypto.get("id"));
                if(jsonObjectDataCrypto.get("rank")!=null)
                    coinmarketcapsnapshotObject.setRank((int) jsonObjectDataCrypto.get("rank"));
                
                if(jsonObjectDataCrypto.get("circulating_supply")!=null)
                    coinmarketcapsnapshotObject.setCirculatingSupply((Double) jsonObjectDataCrypto.get("circulating_supply"));
                
                if(jsonObjectDataCrypto.get("total_supply")!=null)
                    coinmarketcapsnapshotObject.setTotalSupply((Double) jsonObjectDataCrypto.get("total_supply"));
                
                if(!jsonObjectDataCrypto.isNull("circulating_supply")) 
                    coinmarketcapsnapshotObject.setMaxSupply((Double) jsonObjectDataCrypto.get("circulating_supply"));
                
                if(!jsonObjectDataCrypto.isNull("total_supply")) 
                    coinmarketcapsnapshotObject.setMaxSupply((Double) jsonObjectDataCrypto.get("total_supply"));
                
                if(!jsonObjectDataCrypto.isNull("max_supply")) 
                    coinmarketcapsnapshotObject.setMaxSupply((Double) jsonObjectDataCrypto.get("max_supply"));
                
                if(!jsonObjectDataCryptoQuotes.isNull("price")) 
                    coinmarketcapsnapshotObject.setPrice((Double) jsonObjectDataCryptoQuotes.get("price"));
                
                if(!jsonObjectDataCryptoQuotes.isNull("volume_24h")) 
                    coinmarketcapsnapshotObject.setVolume24h((Double) jsonObjectDataCryptoQuotes.get("volume_24h"));
                
                if(!jsonObjectDataCryptoQuotes.isNull("market_cap")) 
                    coinmarketcapsnapshotObject.setMarketCap((Double) jsonObjectDataCryptoQuotes.get("market_cap"));
                
                if(!jsonObjectDataCryptoQuotes.isNull("percent_change_1h")) 
                    coinmarketcapsnapshotObject.setPercentChange1h((Double) jsonObjectDataCryptoQuotes.get("percent_change_1h"));
                
                if(!jsonObjectDataCryptoQuotes.isNull("percent_change_24h")) 
                    coinmarketcapsnapshotObject.setPercentChange24h((Double) jsonObjectDataCryptoQuotes.get("percent_change_24h"));
                
                if(!jsonObjectDataCryptoQuotes.isNull("percent_change_7d")) 
                    coinmarketcapsnapshotObject.setPercentChange7d((Double) jsonObjectDataCryptoQuotes.get("percent_change_7d"));
                

                entityManager.persist(coinmarketcapsnapshotObject);
                coinmarketcapsnapshotsArray.put(coinmarketcapsnapshotObject);
                coinmarketcapsnapshotsJSONObject.put(String.valueOf(count),coinmarketcapsnapshotObject);
                coinmarketcapsnapshotsHashMap.put(count, coinmarketcapsnapshotObject);
            
        

     catch (JSONException e) 
        e.printStackTrace();
    

    System.out.println("\n\ncoinmarketcapsnapshotsArray:\n"+coinmarketcapsnapshotsArray);
    System.out.println("\n\ncoinmarketcapsnapshotsJSONObject:\n"+coinmarketcapsnapshotsJSONObject);
    System.out.println("\n\ncoinmarketcapsnapshotsHashMap:\n"+coinmarketcapsnapshotsHashMap);

    return new ResponseEntity<>(coinmarketcapsnapshotsHashMap, HttpStatus.OK);

这是终端打印的内容:

coinmarketcapsnapshotsArray:
["com.krown.entity.CoinmarketcapSnapshot@4d60f69f","com.krown.entity.CoinmarketcapSnapshot@4739c2f2","com.krown.entity.CoinmarketcapSnapshot@7d5bd573","com.krown.entity.CoinmarketcapSnapshot@43b5eb6d","com.krown.entity.CoinmarketcapSnapshot@26e1a633"]


coinmarketcapsnapshotsJSONObject:
"1":"com.krown.entity.CoinmarketcapSnapshot@4d60f69f","2":"com.krown.entity.CoinmarketcapSnapshot@4739c2f2","3":"com.krown.entity.CoinmarketcapSnapshot@7d5bd573","4":"com.krown.entity.CoinmarketcapSnapshot@43b5eb6d","5":"com.krown.entity.CoinmarketcapSnapshot@26e1a633"


coinmarketcapsnapshotsHashMap:
1=com.krown.entity.CoinmarketcapSnapshot@4d60f69f, 2=com.krown.entity.CoinmarketcapSnapshot@4739c2f2, 3=com.krown.entity.CoinmarketcapSnapshot@7d5bd573, 4=com.krown.entity.CoinmarketcapSnapshot@43b5eb6d, 5=com.krown.entity.CoinmarketcapSnapshot@26e1a633

我想返回我的 JSONObject“coinmarketcapsnapshotsJSONObject”而不是“coinmarketcapsnapshotsHashMap”,但是当我这样做时,我一直遇到这个错误:

没有找到返回值类型的转换器:class org.json.JSONObject

正如在网上找到的一些帖子中所建议的,我在 pom.xml 文件中添加了 Jackson 作为新依赖项:

<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>2.5.0</version>
</dependency>

很遗憾,这并没有改变任何东西。

您有什么建议可以改进在 Spring Boot 上为 REST API 构建 JSON 的过程吗?

当我返回 HashMap 时,输出如下所示:

【问题讨论】:

为什么要转成JSONObject?默认情况下,Jackson 会为您执行此操作 您是否尝试调用您的休息服务?当您调用此休息服务时,您得到了什么?因为您没有在日志中覆盖“CoinmarketcapSnapshot”中的tostring() 方法,所以它只是打印toString() 表示 @MaruthiAdithya 我是 Java 新手,我不明白为什么我们需要这么多不同的库来遍历 JSON 对象并返回 JSON。由于我已经需要 JSON 对象,所以我想避免使用 HashMap。 @Deadpool,REST 服务在我返回 HashMap 时运行良好,但在返回 JSONObject 时不起作用。我将更新答案以显示输出。 那你为什么要返回JSONObject? 【参考方案1】:

HttpStatus.OK 是使用 Spring 的 Http 端点的默认返回值,因此不需要指定它,从而使整个 ResponseEntity 变得不必要:

@ResponseBody
@Transactional
@GetMapping("create_coinmarketcap_snapshot")
public HashMap create_coinmarketcap_snapshot() 

    String jsonString = callURL("https://api.coinmarketcap.com/v2/ticker/?limit=5");

    JSONArray coinmarketcapsnapshotsArray = new JSONArray();
    JSONObject coinmarketcapsnapshotsJSONObject = new JSONObject();
    HashMap<Integer, CoinmarketcapSnapshot> coinmarketcapsnapshotsHashMap = new HashMap<>();

    try 

        JSONObject jsonObject = new JSONObject(jsonString);
        JSONObject jsonObjectData = jsonObject.getJSONObject("data");
        Iterator<?> keys = jsonObjectData.keys();

        int count = 0;

        while (keys.hasNext()) 

            count++;

            String key = (String) keys.next();

            if (jsonObjectData.get(key) instanceof JSONObject) 

                JSONObject jsonObjectDataCrypto = jsonObjectData.getJSONObject(key);
                JSONObject jsonObjectDataCryptoQuotes = jsonObjectDataCrypto.getJSONObject("quotes").getJSONObject("USD");

                CoinmarketcapSnapshot coinmarketcapsnapshotObject = new CoinmarketcapSnapshot();
                String dateFormatted = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss").format(Calendar.getInstance().getTime());
                coinmarketcapsnapshotObject.setTitle(jsonObjectDataCrypto.get("name") + " - " + dateFormatted);
                coinmarketcapsnapshotObject.setCryptocurrencyId((int) jsonObjectDataCrypto.get("id"));
                if(jsonObjectDataCrypto.get("rank")!=null)
                    coinmarketcapsnapshotObject.setRank((int) jsonObjectDataCrypto.get("rank"));
                
                if(jsonObjectDataCrypto.get("circulating_supply")!=null)
                    coinmarketcapsnapshotObject.setCirculatingSupply((Double) jsonObjectDataCrypto.get("circulating_supply"));
                
                if(jsonObjectDataCrypto.get("total_supply")!=null)
                    coinmarketcapsnapshotObject.setTotalSupply((Double) jsonObjectDataCrypto.get("total_supply"));
                
                if(!jsonObjectDataCrypto.isNull("circulating_supply")) 
                    coinmarketcapsnapshotObject.setMaxSupply((Double) jsonObjectDataCrypto.get("circulating_supply"));
                
                if(!jsonObjectDataCrypto.isNull("total_supply")) 
                    coinmarketcapsnapshotObject.setMaxSupply((Double) jsonObjectDataCrypto.get("total_supply"));
                
                if(!jsonObjectDataCrypto.isNull("max_supply")) 
                    coinmarketcapsnapshotObject.setMaxSupply((Double) jsonObjectDataCrypto.get("max_supply"));
                
                if(!jsonObjectDataCryptoQuotes.isNull("price")) 
                    coinmarketcapsnapshotObject.setPrice((Double) jsonObjectDataCryptoQuotes.get("price"));
                
                if(!jsonObjectDataCryptoQuotes.isNull("volume_24h")) 
                    coinmarketcapsnapshotObject.setVolume24h((Double) jsonObjectDataCryptoQuotes.get("volume_24h"));
                
                if(!jsonObjectDataCryptoQuotes.isNull("market_cap")) 
                    coinmarketcapsnapshotObject.setMarketCap((Double) jsonObjectDataCryptoQuotes.get("market_cap"));
                
                if(!jsonObjectDataCryptoQuotes.isNull("percent_change_1h")) 
                    coinmarketcapsnapshotObject.setPercentChange1h((Double) jsonObjectDataCryptoQuotes.get("percent_change_1h"));
                
                if(!jsonObjectDataCryptoQuotes.isNull("percent_change_24h")) 
                    coinmarketcapsnapshotObject.setPercentChange24h((Double) jsonObjectDataCryptoQuotes.get("percent_change_24h"));
                
                if(!jsonObjectDataCryptoQuotes.isNull("percent_change_7d")) 
                    coinmarketcapsnapshotObject.setPercentChange7d((Double) jsonObjectDataCryptoQuotes.get("percent_change_7d"));
                

                entityManager.persist(coinmarketcapsnapshotObject);
                coinmarketcapsnapshotsArray.put(coinmarketcapsnapshotObject);
                coinmarketcapsnapshotsJSONObject.put(String.valueOf(count),coinmarketcapsnapshotObject);
                coinmarketcapsnapshotsHashMap.put(count, coinmarketcapsnapshotObject);
            
        

     catch (JSONException e) 
        e.printStackTrace();
    

    System.out.println("\n\ncoinmarketcapsnapshotsArray:\n"+coinmarketcapsnapshotsArray);
    System.out.println("\n\ncoinmarketcapsnapshotsJSONObject:\n"+coinmarketcapsnapshotsJSONObject);
    System.out.println("\n\ncoinmarketcapsnapshotsHashMap:\n"+coinmarketcapsnapshotsHashMap);

    return coinmarketcapsnapshotsHashMap;

【讨论】:

【参考方案2】:

@GetMapping(produces=MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<?> create_coinmarketcap_snapshot() throws IOException 
    UriComponentsBuilder builder = 
        UriComponentsBuilder.fromUriString("https://api.coinmarketcap.com/v2/ticker")
            .queryParam("limit", "5");

    ResponseEntity<String> response = 
        restTemplate.getForEntity(builder.toUriString(), String.class);

    ObjectMapper mapper = new ObjectMapper();
    JsonNode root = mapper.readTree(response.getBody());
    JsonNode data = root.path("data");

    data.forEach(jsonObject -> 
        jsonObject.get("rank"); //extracting values from each json object
        jsonObject.get("circulating_supply");
        jsonObject.get("total_supply");
        jsonObject.get("max_supply");
        jsonObject.get("price");
        jsonObject.get("volume_24h");
        jsonObject.get("market_cap");
        jsonObject.get("percent_change_1h");
        jsonObject.get("percent_change_24h");
        //... and so on         
    );     

    return ResponseEntity.ok(data); 
   

现在您返回一个 json 对象,其中包含“数据”键 @118218 的值

【讨论】:

以上是关于如何使用 ResponseEntity 返回 JSONObject 而不是 HashMap? (未找到类型返回值的转换器:类 org.json.JSONObject)的主要内容,如果未能解决你的问题,请参考以下文章

如何在 ResponseEntity 中返回已创建状态 (201 HTTP)

Spring Android POST在ResponseEntity中没有返回类型应用程序/八位字节流

ResponseEntity,如何获取html中的body

如何将 Spring WebClient 响应转换为 ResponseEntity?

使用ResponseEntity进行返回json数据

Spring Boot - 使用 ModelAndView 返回 ResponseEntity