Fading Coder

One Final Commit for the Last Sprint

Home > Tech > Content

Integrating Baidu's ERNIE Bot API with Java and Spring Boot

Tech 2

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

  1. Credentials: Replace YOUR_API_KEY and YOUR_SECRET_KEY in the ErnieBotService with you're credentials from the Baidu AI Cloud Console.
  2. Dependencies: Ensure your pom.xml includes Spring Boot Web starter for RestTemplate and JSON processing.
  3. Usage: Start the application and send a POST request to /api/ernie/chat with 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.

Related Articles

Understanding Strong and Weak References in Java

Strong References Strong reference are the most prevalent type of object referencing in Java. When an object has a strong reference pointing to it, the garbage collector will not reclaim its memory. F...

Comprehensive Guide to SSTI Explained with Payload Bypass Techniques

Introduction Server-Side Template Injection (SSTI) is a vulnerability in web applications where user input is improper handled within the template engine and executed on the server. This exploit can r...

Implement Image Upload Functionality for Django Integrated TinyMCE Editor

Django’s Admin panel is highly user-friendly, and pairing it with TinyMCE, an effective rich text editor, simplifies content management significantly. Combining the two is particular useful for bloggi...

Leave a Comment

Anonymous

◎Feel free to join the discussion and share your thoughts.