Using OpenAI API in Spring Boot
Want to build a Java backend that can hold a real conversation with OpenAI’s GPT model? Let’s go beyond single-turn prompts and add support for multi-turn chat using Spring Boot and the OpenAI API. We’ll also include a test that covers a 3–4 step conversation!
๐ฆ Step 1: Maven Dependencies
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
๐ง Step 2: ChatController.java
package com.example.openai;
import org.springframework.web.bind.annotation.*;
import java.net.http.*;
import java.net.URI;
import java.util.*;
import java.util.stream.Collectors;
@RestController
@RequestMapping("/api/chat")
public class ChatController {
private static final String OPENAI_API_KEY = "your-openai-api-key";
@PostMapping
public String chat(@RequestBody List<Map<String, String>> messages) throws Exception {
String formattedMessages = messages.stream()
.map(msg -> String.format("{\\"role\\": \\"%s\\", \\"content\\": \\"%s\\"}",
msg.get("role"), msg.get("content")))
.collect(Collectors.joining(","));
String requestBody = """
{
"model": "gpt-3.5-turbo",
"messages": [%s]
}
""".formatted(formattedMessages);
HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://api.openai.com/v1/chat/completions"))
.header("Authorization", "Bearer " + OPENAI_API_KEY)
.header("Content-Type", "application/json")
.POST(HttpRequest.BodyPublishers.ofString(requestBody))
.build();
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
return response.body();
}
}
๐งช Step 3: JUnit Test – Multi-Turn Chat
package com.example.openai;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.http.*;
import org.springframework.web.client.RestTemplate;
import java.util.*;
import static org.junit.jupiter.api.Assertions.*;
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT)
public class ChatControllerTest {
@Test
void testMultiStepChat() {
RestTemplate restTemplate = new RestTemplate();
String url = "http://localhost:8080/api/chat";
List<Map<String, String>> conversation = new ArrayList<>();
conversation.add(Map.of("role", "user", "content", "Hi, who are you?"));
conversation.add(Map.of("role", "assistant", "content", "I'm an AI trained by OpenAI. How can I help?"));
conversation.add(Map.of("role", "user", "content", "What's the capital of Germany?"));
conversation.add(Map.of("role", "assistant", "content", "The capital of Germany is Berlin."));
conversation.add(Map.of("role", "user", "content", "Is it a good place to visit?"));
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
HttpEntity<List<Map<String, String>>> request = new HttpEntity<>(conversation, headers);
ResponseEntity<String> response = restTemplate.postForEntity(url, request, String.class);
assertEquals(HttpStatus.OK, response.getStatusCode());
assertTrue(response.getBody().contains("Berlin") || response.getBody().toLowerCase().contains("yes"));
}
}
✅ Expected Result
You should get a response that continues the conversation naturally, like:
{
"choices": [
{
"message": {
"role": "assistant",
"content": "Yes, Berlin is a vibrant city with rich history and culture!"
}
}
]
}
๐ก Tips
- Use a logging library to persist message history.
- Store your API key in
application.ymlsecurely. - Add streaming response support with WebClient for real-time output.
๐ Conclusion
You now have a Spring Boot app that can maintain chat history and simulate real conversations with OpenAI’s Chat API. Expand this to a full chatbot, integrate into Slack, or embed in web apps!
Comments
Post a Comment