DEV Community

Cover image for Comunicando JAVA com o GeminiAI
Wander
Wander

Posted on

1

Comunicando JAVA com o GeminiAI

Se voce programa em Java e nunca 'brincou' com o GeminiAI, este artigo vai ser um ótimo guia introdutório, aqui vou apresentar de forma bem simples como enviar requisições ao Gemini e retornar um JSON, como uma API Rest. 🐱‍👤

O que estou usando? 👀


VAMOS COMECAR 🚀

Inicie um projeto simples pelo spring initializer, e inclua as seguintes dependências no seu POM

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>

<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <version>1.18.36</version>
    <scope>provided</scope>
</dependency>

<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>2.18.2</version>
</dependency>
Enter fullscreen mode Exit fullscreen mode

Essas dependencias vao possibilitar o uso do Lombok, RestTemplate e ObjectMapper.

Lombok: para evitarmos códigos repetitivos (famosos boilerplates) e para melhorar a legibilidade do nosso código

RestTemplate: para realizar a requisição http a API do GeminiAI

ObjectMapper: para convertermos o retorno da api do Gemini em JSON

 

CONFIGURANDO O RESTTEMPLATE

Vamos configurar o RestTemplate no nosso projeto Java, para isso criamos uma classe com a anotação @Configuration e com o Bean para defini-lo:

@Configuration
public class RestTemplateConfig {

    @Bean
    public RestTemplate restTemplate(RestTemplateBuilder builder) {
        return builder.build();
    }
}
Enter fullscreen mode Exit fullscreen mode

 

CRIANDO O SERVICE

Vamos criar uma classe service para realizar a comunicação com o GeminiAI, esta classe será responsável por toda comunicação e tratamento da resposta do Gemini, e deverá ficar da seguinte forma:

@Service
public class TalkService {
    private final RestTemplate restTemplate;
    private final ObjectMapper objectMapper;

    @Value("${gemini.ai.api.url}")
    private String geminiApiUrl;

    @Value("${gemini.ai.api.key}")
    private String geminiApiKey;

    public TalkService(RestTemplate restTemplate, ObjectMapper objectMapper) {
        this.restTemplate = restTemplate;
        this.objectMapper = objectMapper;
    }

    public String callGeminiAI(TalkRequest input) {
        String url = geminiApiUrl + geminiApiKey;

        GeminiRequest request = new GeminiRequest();
        GeminiRequest.Content content = new GeminiRequest.Content();
        GeminiRequest.Part part = new GeminiRequest.Part();

        part.setText(input.getChat());
        content.setParts(Collections.singletonList(part));
        request.setContents(Collections.singletonList(content));

        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON);
        HttpEntity<GeminiRequest> entity = new HttpEntity<>(request, headers);

        ResponseEntity<String> response = restTemplate.exchange(url, HttpMethod.POST, entity, String.class);

        try {
            GeminiResponse geminiAIResponse = objectMapper.readValue(response.getBody(), GeminiResponse.class);

            if (geminiAIResponse.getCandidates() != null && !geminiAIResponse.getCandidates().isEmpty()) {
                GeminiResponse.Candidate candidate = geminiAIResponse.getCandidates().get(0);
                if (candidate.getContent() != null && candidate.getContent().getParts() != null && !candidate.getContent().getParts().isEmpty()) {
                    return candidate.getContent().getParts().get(0).getText();
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return "Falha ao processar resposta da API";
    }
}
Enter fullscreen mode Exit fullscreen mode

Note que nesta classe estamos usando os POJO's GeminiRequest e GeminiResponse, segue abaixo o código para cria-los

GeminiRequest

@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
public class GeminiRequest {
    private List<Content> contents;

    @Getter
    @Setter
    @AllArgsConstructor
    @NoArgsConstructor
    public static class Content {
        private List<Part> parts;
    }

    @Getter
    @Setter
    @AllArgsConstructor
    @NoArgsConstructor
    public static class Part {
        private String text;
    }
}
Enter fullscreen mode Exit fullscreen mode

GeminiResponse

@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
@JsonIgnoreProperties(ignoreUnknown = true)
public class GeminiResponse {
    private List<Candidate> candidates;
    private UsageMetadata usageMetadata;
    private String modelVersion;

    @Getter
    @Setter
    @AllArgsConstructor
    @NoArgsConstructor
    @JsonIgnoreProperties(ignoreUnknown = true)
    public static class Candidate {
        private Content content;
        private String finishReason;
        private double avgLogprobs;
    }

    @Getter
    @Setter
    @AllArgsConstructor
    @NoArgsConstructor
    @JsonIgnoreProperties(ignoreUnknown = true)
    public static class Content {
        private List<Part> parts;
    }

    @Getter
    @Setter
    @AllArgsConstructor
    @NoArgsConstructor
    @JsonIgnoreProperties(ignoreUnknown = true)
    public static class Part {
        private String text;
    }

    @Getter
    @Setter
    @AllArgsConstructor
    @NoArgsConstructor
    @JsonIgnoreProperties(ignoreUnknown = true)
    public static class UsageMetadata {
        private int promptTokenCount;
        private int candidatesTokenCount;
        private int totalTokenCount;
    }
}
Enter fullscreen mode Exit fullscreen mode

 

CRIANDO UM CONTROLLER

Vamos agora criar um controller para escutar uma requisição Rest e fazer o processamento através do nosso Service

@RestController
@RequestMapping("v1")
public class TalkController {
    private final TalkService talkService;

    @Autowired
    public TalkController(final TalkService talkService) {
        this.talkService = talkService;
    }

    @PostMapping("/chat-gemini")
    public TalkResponse talk(@RequestBody TalkRequest talkRequest) {
        TalkResponse response = new TalkResponse();
        response.setResponse(talkService.callGeminiAI(talkRequest));
        return response;
    }
}
Enter fullscreen mode Exit fullscreen mode

Nosso controller também possui POJO's, confira o código deles abaixo

TalkRequest

@Getter
@Setter
@AllArgsConstructor
public class TalkRequest {
    private String chat;
}
Enter fullscreen mode Exit fullscreen mode

TalkResponse

@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
public class TalkResponse {
    private String response;
}

Enter fullscreen mode Exit fullscreen mode

 

CONFIGURANDO VARIAVEIS NOS PROPERTIES

Voce precisará informar o endpoint de acesso ao GeminiAI e também a sua chave de acesso. Essas informações armazenei no arquivo properties, dado que estamos falando de um simples teste. Confira o arquivo properties com as variáveis necessárias

spring.application.name=NOME_DA_SUA_APLICACAO

gemini.ai.api.url=https://generativelanguage.googleapis.com/v1beta/models/gemini-1.5-flash:generateContent?key=
gemini.ai.api.key=SUA_CHAVE_DE_ACESSO
Enter fullscreen mode Exit fullscreen mode

 

BORA TESTAR 🐱‍💻

Já temos uma comunicação com o GeminiAI, agora podemos testar nossa aplicação usando o postman, para isso inicie a sua aplicação no Intellij e execute a requisição no postman conforme a imagem abaixo:

Image description


CONCLUSÃO
O intuito deste artigo foi introduzir programadores Java a conexao do GeminiAI com uma aplicacao Java, criando infinitas novas possibilidades de uso. Espero que tenham gostado, até a próxima! 😊

Image of Timescale

Timescale – the developer's data platform for modern apps, built on PostgreSQL

Timescale Cloud is PostgreSQL optimized for speed, scale, and performance. Over 3 million IoT, AI, crypto, and dev tool apps are powered by Timescale. Try it free today! No credit card required.

Try free

Top comments (0)

The Most Contextual AI Development Assistant

Pieces.app image

Our centralized storage agent works on-device, unifying various developer tools to proactively capture and enrich useful materials, streamline collaboration, and solve complex problems through a contextual understanding of your unique workflow.

👥 Ideal for solo developers, teams, and cross-company projects

Learn more

👋 Kindness is contagious

Explore a sea of insights with this enlightening post, highly esteemed within the nurturing DEV Community. Coders of all stripes are invited to participate and contribute to our shared knowledge.

Expressing gratitude with a simple "thank you" can make a big impact. Leave your thanks in the comments!

On DEV, exchanging ideas smooths our way and strengthens our community bonds. Found this useful? A quick note of thanks to the author can mean a lot.

Okay