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[]
。当您跳过多个解析步骤时,这种方法会明显更快。
我正在开发一个 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[]
。当您跳过多个解析步骤时,这种方法会明显更快。