2016-03-08 51 views
0

我正在研究一個JavaFX應用程序,我想從本地主機上運行的服務器檢索圖像。該圖像是一個javafx.scene.Image。但是當我試圖檢索沒有任何類的圖像時,我得到了no suitable message-convertor found,而當我將圖像放入另一個對象時,我得到了一個不同的錯誤。那麼,我如何從服務器檢索圖像?請讓我知道。JavaFX:從服務器檢索圖像,沒有找到合適的構造函數

錯誤日誌:

org.springframework.http.converter.HttpMessageNotReadableException: Could not read document: No suitable constructor found for type [simple type, class javafx.scene.image.Image]: can not instantiate from JSON object (missing default constructor or creator, or perhaps need to add/enable type information?) 
at [Source: [email protected]; line: 1, column: 17] (through reference chain: Model.RestImage["canvasImage"]); nested exception is com.fasterxml.jackson.databind.JsonMappingException: No suitable constructor found for type [simple type, class javafx.scene.image.Image]: can not instantiate from JSON object (missing default constructor or creator, or perhaps need to add/enable type information?) 
at [Source: [email protected]; line: 1, column: 17] (through reference chain: Model.RestImage["canvasImage"]) 
    at org.springframework.http.converter.json.AbstractJackson2HttpMessageConverter.readJavaType(AbstractJackson2HttpMessageConverter.java:225) 
    at org.springframework.http.converter.json.AbstractJackson2HttpMessageConverter.read(AbstractJackson2HttpMessageConverter.java:209) 
    at org.springframework.web.client.HttpMessageConverterExtractor.extractData(HttpMessageConverterExtractor.java:95) 
    at org.springframework.web.client.RestTemplate$ResponseEntityResponseExtractor.extractData(RestTemplate.java:835) 
    at org.springframework.web.client.RestTemplate$ResponseEntityResponseExtractor.extractData(RestTemplate.java:819) 
    at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:599) 
    at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:557) 
    at org.springframework.web.client.RestTemplate.exchange(RestTemplate.java:475) 
    at Controller.AccountController$4.call(AccountController.java:140) 
    at Controller.AccountController$4.call(AccountController.java:127) 
    at javafx.concurrent.Task$TaskCallable.call(Task.java:1423) 
    at java.util.concurrent.FutureTask.run(FutureTask.java:266) 
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511) 
    at java.util.concurrent.FutureTask.run(FutureTask.java:266) 
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) 
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) 
    at java.lang.Thread.run(Thread.java:745) 
Caused by: com.fasterxml.jackson.databind.JsonMappingException: No suitable constructor found for type [simple type, class javafx.scene.image.Image]: can not instantiate from JSON object (missing default constructor or creator, or perhaps need to add/enable type information?) 
at [Source: [email protected]; line: 1, column: 17] (through reference chain: Model.RestImage["canvasImage"]) 

代碼JavaFX的一面:

private Task<List<RestImage>> fetchCanvasImagesFromServer = new Task<List<RestImage>>() { 

     @Override 
     protected List<RestImage> call() throws Exception { 
      List<RestImage> imageList = new ArrayList<>(); 
      try { 
       for(RestCanvas restCanvas : restCanvases) { 
        RestTemplate rest = StaticRestTemplate.getRest(); 
        HttpHeaders requestHeaders = new HttpHeaders(); 
        requestHeaders.add("Cookie", "JSESSIONID=" + StaticRestTemplate.jsessionid); 
        HttpEntity<RestImage> requestEntity = new HttpEntity<>(requestHeaders); 
        rest.getMessageConverters().add(new MappingJackson2HttpMessageConverter()); 
        rest.getMessageConverters().add(new ByteArrayHttpMessageConverter()); 
        ResponseEntity<RestImage> responseEntity = rest.exchange(getCanvasImage+restCanvas.getMcanvasid(), HttpMethod.GET, requestEntity, RestImage.class); 
        imageList.add(responseEntity.getBody()); 
       } 
       return imageList; 
      } catch (Exception e) { 
       e.printStackTrace(); 
      } 
      return imageList; 
     } 
    }; 

RestImage型號:

import javafx.scene.image.Image; 

public class RestImage { 

    private Image canvasImage; 

    private int someId; 
// getters and setters 
} 

服務器端控制器鱈魚

從服務器檢索圖片e:

@RequestMapping(value = "/canvasimage/{canvasid}") 
    public @ResponseBody 
    RestImage getBoardImageAsImage(@PathVariable("canvasid") int canvasid) { 
     System.out.println("Board image was called."); 
     Person person = this.personService.getCurrentlyAuthenticatedUser(); 
     RestImage restImage = new RestImage(); 
     restImage.setSomeId(canvasid); 
BufferedImage bufferedImage = ImageIO.read(file); 

        restImage.setCanvasImage(SwingFXUtils.toFXImage(bufferedImage,null)); 

return restImage; 
} 

回答

1

這種方法的根本問題是,框架似乎不知道如何通過網絡傳遞圖像。總之,你需要找到一些可以容易地在中間容器中傳輸的格式。通常用於圖像傳輸的人可以從圖像中提取原始字節,併發送易於攜帶的byte[]。一旦收到另一端,byte[]可以被讀回到圖像。將JavaFX Image轉換爲byte[]的一種方法是首先使用SwingFXUtils將其轉換爲BufferedImage,隨後使用ImageIO.write()來寫入ByteArrayOutputStream並通過toByteArray()獲得byte[]。最後,您可以使用ImageIO.read()ByteArrayInputStreambyte[]轉換爲BufferredImage,然後JavaFX Image。另外,根據您在客戶端的處理方式,您可以直接使用this constructor將數據讀入JavaFX Image

或者,考慮到您正在從文件中讀取圖像,您可以直接使用Files.readAllBytes()將圖像讀入byte[]。跳過多個分析步驟時,這種方法將顯着加快。

+0

任何想法如何將字節數組轉換回JavaFx圖像? –

+0

它已經在答案中,使用ByteArrayInputStream並將其提供給新的圖像() – AlmasB

+0

是的..已經是DId了。我還添加了一個關於JavaFX的問題:http://stackoverflow.com/questions/35868721/javafx-how-to-call-the-fxml-files-and-load-data-into-it。你能檢查一下嗎? :-) –

相關問題