JavaFX:从服务器检索图像,找不到合适的构造函数

时间:2016-03-08 09:07:29

标签: java javafx resttemplate

我正在开发一个JavaFX应用程序,我想在其中从Localhost中运行的服务器检索Image。该图像是javafx.scene.Image。但是当我尝试检索图像而没有任何包含它的类时,我得到no suitable message-convertor found,而当我将Image放在另一个对象中时,我得到了一个不同的错误。那么,我如何从服务器检索图像?请告诉我。

错误日志:

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: java.io.PushbackInputStream@1eebd84c; 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: java.io.PushbackInputStream@1eebd84c; 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: java.io.PushbackInputStream@1eebd84c; 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
}

服务器端控制器代码:

@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 个答案:

答案 0 :(得分:1)

这种方法的根本问题是框架似乎不知道如何通过网络传递图像。简而言之,您需要找到一些可以在中间容器中轻松传输的格式。通常,对于图像传输,可以从图像中提取原始字节并发送byte[],这可以轻松传输。一旦收到另一端,byte[]就可以读回图像。将JavaFX Image转换为byte[]的一种方法是首先使用BufferedImage将其转换为SwingFXUtils,然后使用ImageIO.write()写入ByteArrayOutputStream和通过byte[]获取toByteArray()。最后,您可以使用ImageIO.read()ByteArrayInputStreambyte[]转换为BufferredImage,然后转换为JavaFX Image。另外,根据您在客户端进行处理的方式,您可以使用this constructor直接将数据读入JavaFX Image

或者,考虑到您正在从文件中读取图像,您可以直接使用Files.readAllBytes()将图像读入byte[]。当你跳过多个解析步骤时,这种方法会明显加快。