JavaでGUIとサーバー処理を分離した構成を実現したいと思ったことはありませんか?
この記事では、JavaFXによるデスクトップUIとSpring BootによるバックエンドAPIを組み合わせ、社内向けの画像管理ツールを作成する方法を紹介します。
対象読者
- JavaでGUIアプリとREST APIの連携を学びたい方
- 画像のアップロード・閲覧・削除などを行う簡易ツールを作りたい方
- JavaFXとSpring Bootの実務レベル統合例を探している方
構成概要
以下のような構成で進めます
- JavaFX: 画像選択、プレビュー、アップロード操作のUI
- Spring Boot: 画像保存API(ローカルディスク保存)
1. Spring Bootで画像アップロードAPIを作成
// ImageController.java
@RestController
@RequestMapping("/api/images")
public class ImageController {
private final Path storageDir = Paths.get("uploads");
@PostConstruct
public void init() throws IOException {
Files.createDirectories(storageDir);
}
@PostMapping("/upload")
public ResponseEntity<?> upload(@RequestParam("file") MultipartFile file) throws IOException {
Path destination = storageDir.resolve(file.getOriginalFilename());
Files.copy(file.getInputStream(), destination, StandardCopyOption.REPLACE_EXISTING);
return ResponseEntity.ok("アップロード成功");
}
@GetMapping("/{filename}")
public ResponseEntity<byte[]> download(@PathVariable String filename) throws IOException {
Path filePath = storageDir.resolve(filename);
byte[] content = Files.readAllBytes(filePath);
return ResponseEntity.ok().body(content);
}
@DeleteMapping("/{filename}")
public ResponseEntity<?> delete(@PathVariable String filename) throws IOException {
Path filePath = storageDir.resolve(filename);
Files.deleteIfExists(filePath);
return ResponseEntity.ok("削除成功");
}
}
依存ライブラリ(Maven)
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
2. JavaFXで画像アップロードUIを作成
JavaFXを使って、画像選択とプレビュー、API経由でのアップロードを行います。
public class ImageUploaderApp extends Application {
private ImageView imageView;
private File selectedFile;
public static void main(String[] args) {
launch(args);
}
@Override
public void start(Stage stage) {
Button selectButton = new Button("画像選択");
Button uploadButton = new Button("アップロード");
imageView = new ImageView();
imageView.setFitWidth(300);
imageView.setPreserveRatio(true);
selectButton.setOnAction(e -> selectImage(stage));
uploadButton.setOnAction(e -> uploadImage());
VBox root = new VBox(10, selectButton, imageView, uploadButton);
root.setPadding(new Insets(20));
stage.setScene(new Scene(root));
stage.setTitle("画像アップローダー");
stage.show();
}
private void selectImage(Stage stage) {
FileChooser chooser = new FileChooser();
chooser.getExtensionFilters().add(new FileChooser.ExtensionFilter("画像ファイル", "*.jpg", "*.png"));
selectedFile = chooser.showOpenDialog(stage);
if (selectedFile != null) {
imageView.setImage(new Image(selectedFile.toURI().toString()));
}
}
private void uploadImage() {
if (selectedFile == null) return;
HttpClient client = HttpClient.newHttpClient();
HttpRequest.BodyPublisher body = ofFileUpload("file", selectedFile);
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("http://localhost:8080/api/images/upload"))
.header("Content-Type", "multipart/form-data; boundary=MyBoundary")
.POST(body)
.build();
client.sendAsync(request, HttpResponse.BodyHandlers.ofString())
.thenAccept(response -> {
System.out.println("アップロード結果: " + response.body());
});
}
// シンプルなmultipart/form-data作成
private HttpRequest.BodyPublisher ofFileUpload(String name, File file) {
String boundary = "MyBoundary";
var byteArrays = new ArrayList<byte[]>();
try {
byteArrays.add(("--" + boundary + "\r\n").getBytes());
byteArrays.add(("Content-Disposition: form-data; name=\"" + name + "\"; filename=\"" + file.getName() + "\"\r\n").getBytes());
byteArrays.add(("Content-Type: application/octet-stream\r\n\r\n").getBytes());
byteArrays.add(Files.readAllBytes(file.toPath()));
byteArrays.add(("\r\n--" + boundary + "--\r\n").getBytes());
} catch (IOException e) {
e.printStackTrace();
}
return HttpRequest.BodyPublishers.ofByteArrays(byteArrays);
}
}
3. 実行方法と構成
プロジェクト構成例:
📁 image-manager/ ├─ 📁 backend/ (Spring Boot) │ └─ ImageController.java ├─ 📁 frontend/ (JavaFX) │ └─ ImageUploaderApp.java
1. Spring Bootアプリを localhost:8080
で起動
2. JavaFXアプリから画像を選択してアップロードボタンをクリック
まとめ
JavaFXとSpring Bootを組み合わせることで、「社内で使いやすいGUI+REST連携の業務ツール」が簡単に構築できます。
今回紹介した画像アップローダーのように、UIはデスクトップに残しつつ、データ処理をAPIに分離することで、保守性・拡張性の高いアーキテクチャを実現できます。
用途例:
- 社内文書や証跡の画像管理
- OCR前の画像収集
- 社外提出資料のレビュー管理