Integrating Baidu's ERNIE Bot API with Java and Spring Boot
This guide outlines the steps to integrate Baidu's ERNIE Bot (WenXin Yiyan) API into a Java Spring Boot application. The process involves defining request/response models, creating a utility class for API communication, and exposing a RESTful endpoint.
1. Define API Request and Response Models
First, create the necessary data transfer objects (DTOs) to structure the API calls.
1.1 Message Model
This class represents a single message in a conversation.
public class ChatMessage {
private String role = "user";
private String content;
public String getRole() {
return role;
}
public void setRole(String role) {
this.role = role;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
}
1.2 Chat Request Model
This class wraps a list of messages for the chat completion request.
import java.util.List;
public class ChatRequest {
private List<ChatMessage> messages;
public List<ChatMessage> getMessages() {
return messages;
}
public void setMessages(List<ChatMessage> messages) {
this.messages = messages;
}
}
1.3 Chat Response Model
This class models the standard resposne from the ERNIE Bot API.
public class ChatResponse {
private String result;
private Integer error_code;
private String error_msg;
public Integer getError_code() {
return error_code;
}
public void setError_code(Integer error_code) {
this.error_code = error_code;
}
public String getError_msg() {
return error_msg;
}
public void setError_msg(String error_msg) {
this.error_msg = error_msg;
}
public String getResult() {
return result;
}
public void setResult(String result) {
this.result = result;
}
}
1.4 Access Token Model
This class is used to deserialize the OAuth 2.0 access token response.
public class AccessToken {
private String access_token;
public String getAccess_token() {
return access_token;
}
public void setAccess_token(String access_token) {
this.access_token = access_token;
}
}
2. Create a REST Client Utility Class
A comprehensive RestClient utility class is created to handle HTTP requests. This class abstracts the complexity of using Spring's RestTemplate.
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.*;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestTemplate;
import java.util.Map;
@Component
public class RestClient {
@Autowired
private RestTemplate restTemplate;
// --- GET Methods ---
public <T> ResponseEntity<T> get(String url, Class<T> responseType) {
return restTemplate.getForEntity(url, responseType);
}
public <T> ResponseEntity<T> get(String url, Class<T> responseType, Object... uriVariables) {
return restTemplate.getForEntity(url, responseType, uriVariables);
}
public <T> ResponseEntity<T> get(String url, Class<T> responseType, Map<String, ?> uriVariables) {
return restTemplate.getForEntity(url, responseType, uriVariables);
}
public <T> ResponseEntity<T> get(String url, Map<String, String> headers, Class<T> responseType, Object... uriVariables) {
HttpHeaders httpHeaders = new HttpHeaders();
httpHeaders.setAll(headers);
return get(url, httpHeaders, responseType, uriVariables);
}
public <T> ResponseEntity<T> get(String url, HttpHeaders headers, Class<T> responseType, Object... uriVariables) {
HttpEntity<?> requestEntity = new HttpEntity<>(headers);
return exchange(url, HttpMethod.GET, requestEntity, responseType, uriVariables);
}
// --- POST Methods ---
public <T> ResponseEntity<T> post(String url, Class<T> responseType) {
return restTemplate.postForEntity(url, HttpEntity.EMPTY, responseType);
}
public <T> ResponseEntity<T> post(String url, Object requestBody, Class<T> responseType) {
return restTemplate.postForEntity(url, requestBody, responseType);
}
public <T> ResponseEntity<T> post(String url, Object requestBody, Class<T> responseType, Object... uriVariables) {
return restTemplate.postForEntity(url, requestBody, responseType, uriVariables);
}
public <T> ResponseEntity<T> post(String url, Map<String, String> headers, Object requestBody, Class<T> responseType, Object... uriVariables) {
HttpHeaders httpHeaders = new HttpHeaders();
httpHeaders.setAll(headers);
return post(url, httpHeaders, requestBody, responseType, uriVariables);
}
public <T> ResponseEntity<T> post(String url, HttpHeaders headers, Object requestBody, Class<T> responseType, Object... uriVariables) {
HttpEntity<Object> requestEntity = new HttpEntity<>(requestBody, headers);
return post(url, requestEntity, responseType, uriVariables);
}
private <T> ResponseEntity<T> post(String url, HttpEntity<?> requestEntity, Class<T> responseType, Object... uriVariables) {
return restTemplate.exchange(url, HttpMethod.POST, requestEntity, responseType, uriVariables);
}
// --- Generic Exchange Method ---
public <T> ResponseEntity<T> exchange(String url, HttpMethod method, HttpEntity<?> requestEntity, Class<T> responseType, Object... uriVariables) {
return restTemplate.exchange(url, method, requestEntity, responseType, uriVariables);
}
}
3. Implement the ERNIE Bot Service
This service class encapsulates the logic for obtaining an access token and calling the ERNIE Bot chat completion endpoint.
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpEntity;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Component;
import java.util.*;
@Component
public class ErnieBotService {
// Replace with your actual credentials from Baidu AI Cloud
private final String apiKey = "YOUR_API_KEY";
private final String secretKey = "YOUR_SECRET_KEY";
@Autowired
RestClient restClient;
public String getChatResponse(String userInput) {
// 1. Obtain Access Token
String tokenUrl = String.format(
"https://aip.baidubce.com/oauth/2.0/token?grant_type=client_credentials&client_id=%s&client_secret=%s",
apiKey, secretKey
);
Map<String, String> headers = new HashMap<>();
headers.put("Content-Type", "application/json");
headers.put("Accept", "application/json");
ResponseEntity<AccessToken> tokenResponse = restClient.post(tokenUrl, headers, HttpEntity.EMPTY, AccessToken.class);
if (tokenResponse != null && tokenResponse.getBody() != null) {
String accessToken = tokenResponse.getBody().getAccess_token();
// 2. Call Chat Completion API
String chatUrl = String.format(
"https://aip.baidubce.com/rpc/2.0/ai_custom/v1/wenxinworkshop/chat/eb-instant?access_token=%s",
accessToken
);
// Prepare the request payload
ChatMessage message = new ChatMessage();
message.setContent(userInput);
ChatRequest chatRequest = new ChatRequest();
chatRequest.setMessages(Collections.singletonList(message));
// Make the API call. Using LinkedHashMap to handle the dynamic response.
ResponseEntity<LinkedHashMap> apiResponse = restClient.post(chatUrl, headers, chatRequest, LinkedHashMap.class);
if (apiResponse != null && apiResponse.getBody() != null) {
Map<String, Object> responseBody = apiResponse.getBody();
// Check for errors
if (responseBody.containsKey("error_code")) {
return responseBody.get("error_msg").toString();
}
// Return the successful result
return responseBody.get("result").toString();
} else {
return "Error: Received null response from API.";
}
}
return "Error: Failed to obtain access token.";
}
}
4. Create a REST Controller
Finally, expose a simple REST endpoint that accepts user input and returns the AI's response.
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
@RestController
@RequestMapping("/api/ernie")
public class ChatController {
@Autowired
private ErnieBotService ernieBotService;
@PostMapping("/chat")
public String chat(@RequestBody String userInput) {
String aiResponse = ernieBotService.getChatResponse(userInput);
return aiResponse;
}
}
Summary and Configuration
- Credentials: Replace
YOUR_API_KEYandYOUR_SECRET_KEYin theErnieBotServicewith you're credentials from the Baidu AI Cloud Console. - Dependencies: Ensure your
pom.xmlincludes Spring Boot Web starter forRestTemplateand JSON processing. - Usage: Start the application and send a POST request to
/api/ernie/chatwith a JSON body containing the user's message string. The endpoint will return the ERNIE Bot's response.
This implementation provides a clean separation of concerns, making it easy to maintain and test. The RestClient utility can also be reused for other HTTP-based API integrations within the project.