[AIWriteSupporter] Java Spring Framework 서버 예제
플러그인의 AI 요청을 프록시하는 Spring 컨트롤러 예제입니다.
텍스트 AI
GPT
import org.springframework.http.*;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.reactive.function.BodyInserters;
import org.springframework.web.reactive.function.client.WebClient;
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;
import reactor.core.publisher.Mono;
import java.io.*;
@RestController
public class GPTController {
private static final String GPT_API_URL = "https://api.openai.com/v1/chat/completions";
private static final String GPT_API_KEY = "API key";
@PostMapping("/requestGPT")
public SseEmitter requestGPT(@RequestBody String json) throws IOException {
SseEmitter emitter = new SseEmitter((long)(5 * 60 * 1000));
WebClient client = WebClient.create(GPT_API_URL);
client.post()
.header("Content-Type", "application/json")
.header("Authorization", String.format("Bearer %s", GPT_API_KEY)) // OpenAI
// .header("Api-Key", GPT_API_KEY) // Azure OpenAI
.body(BodyInserters.fromValue(json))
.exchangeToFlux(response -> {
if (response.statusCode().equals(HttpStatus.OK)) {
return response.bodyToFlux(String.class);
} else {
return response.createException().flatMapMany(Mono::error);
}
})
.doOnNext(line -> {
try { emitter.send(SseEmitter.event().data(line)); }
catch (IOException e) { throw new RuntimeException(e); }
})
.doOnError(emitter::completeWithError)
.doOnComplete(emitter::complete)
.subscribe();
return emitter;
}
}
Gemini
import org.springframework.http.*;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.reactive.function.BodyInserters;
import org.springframework.web.reactive.function.client.WebClient;
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;
import reactor.core.publisher.Mono;
import java.io.*;
@RestController
public class GeminiController {
private static final String GEMINI_API_URL = ""; // e.g. 'https://generativelanguage.googleapis.com/v1beta/models/gemini-1.5-flash:streamGenerateContent'
private static final String GEMINI_API_PARAM = ""; // e.g. 'alt=sse&'
private static final String GEMINI_API_KEY = "";
private static final String urlWithParam =
GEMINI_API_URL + "?" + GEMINI_API_PARAM + "key=" + GEMINI_API_KEY;
@PostMapping("/requestGemini")
public SseEmitter requestGemini(@RequestBody String json) throws IOException {
SseEmitter emitter = new SseEmitter((long)(5 * 60 * 1000));
WebClient client = WebClient.create(urlWithParam);
client.post()
.header("Content-Type", "application/json")
.header("Authorization", "text/json")
.body(BodyInserters.fromValue(json))
.exchangeToFlux(response -> {
if (response.statusCode().equals(HttpStatus.OK)) {
return response.bodyToFlux(String.class);
} else {
return response.createException().flatMapMany(Mono::error);
}
})
.doOnNext(line -> {
try { emitter.send(SseEmitter.event().data(line)); }
catch (IOException e) { throw new RuntimeException(e); }
})
.doOnError(emitter::completeWithError)
.doOnComplete(emitter::complete)
.subscribe();
return emitter;
}
}
이미지 AI
gpt-image
3.4.0 버전부터 지원합니다.
컨트롤러는 OpenAI 응답을 그대로 전달하므로, data 배열의 모든 생성된 이미지가 반환됩니다(첫 번째 것만 반환되는 것이 아님).
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.core.type.TypeReference;
import org.springframework.http.*;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.client.RestTemplate;
import java.io.IOException;
import java.util.*;
@RestController
public class GPTImageController {
private static final String GPT_IMAGE_API_URL = "https://api.openai.com/v1/images/generations";
private static final String GPT_IMAGE_API_KEY = "API key";
private final RestTemplate restTemplate = new RestTemplate();
private final ObjectMapper objectMapper = new ObjectMapper();
@PostMapping("/requestGPTImage")
public ResponseEntity<Map<String, Object>> requestGPTImage(@RequestBody Map<String, Object> json) throws IOException {
String requestBody = objectMapper.writeValueAsString(json);
HttpHeaders headers = new HttpHeaders();
headers.set("Content-Type", "application/json");
headers.set("Authorization", String.format("Bearer %s", GPT_IMAGE_API_KEY));
HttpEntity<String> requestEntity = new HttpEntity<>(requestBody, headers);
String responseJson = restTemplate.exchange(GPT_IMAGE_API_URL, HttpMethod.POST, requestEntity, String.class).getBody();
// Pass the OpenAI response through as-is, keeping the data array (all n images)
Map<String, Object> resultMap = objectMapper.readValue(responseJson, new TypeReference<Map<String, Object>>() {});
return ResponseEntity.ok(resultMap);
}
}