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

JavaFX : Retrieving Image from server, no suitable constructor found

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

错误日志:

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.call(AccountController.java:140)
    at Controller.AccountController.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;
}

这种方法的根本问题是框架似乎不知道如何通过网络传递图像。简而言之,您需要找到一些可以在中间容器中轻松传输的格式。通常对于图像传输,可以从图像中提取原始字节并发送 byte[],这很容易传输。一旦在另一端收到,byte[] 可以读回图像。将 JavaFX Image 转换为 byte[] 的一种方法是首先使用 SwingFXUtils 将其转换为 BufferedImage,然后使用 ImageIO.write() to write into a ByteArrayOutputStream and obtain byte[] via toByteArray(). Finally, you can use ImageIO.read() and ByteArrayInputStream to convert byte[] into a BufferredImage and then JavaFX Image. Also depending on how you do processing on the client side, you can read data into JavaFX Image directly, using this constructor.

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