Implementaicón de llamadas a servicios remotos mediante HttpClient en Java
Dependencias requeridas
<dependency>
<groupId>org.apache.httpcomponents.client5</groupId>
<artifactId>httpclient5</artifactId>
<version>5.3</version>
</dependency>
A continuación se presenta una clase de utilidad con métodos para realizar solicitudes GET, POST y PUT:
package com.ejemplo.tecnologia.controlador;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.apache.hc.client5.http.classic.methods.HttpGet;
import org.apache.hc.client5.http.classic.methods.HttpPost;
import org.apache.hc.client5.http.classic.methods.HttpPut;
import org.apache.hc.client5.http.impl.classic.CloseableHttpClient;
import org.apache.hc.client5.http.impl.classic.CloseableHttpResponse;
import org.apache.hc.client5.http.impl.classic.HttpClients;
import org.apache.hc.client5.http.impl.io.PoolingHttpClientConnectionManager;
import org.apache.hc.client5.http.impl.io.PoolingHttpClientConnectionManagerBuilder;
import org.apache.hc.core5.http.ContentType;
import org.apache.hc.core5.http.io.entity.EntityUtils;
import org.apache.hc.core5.http.io.entity.StringEntity;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@Slf4j
public class ClienteHttpUtil {
/**
* Ejecuta una solicitud GET
*
* @param endpoint URL del servicio
* @param cabeceras Encabezados de la solicitud
* @param parametrosConsulta Parámetros de consulta
* @return Respuesta del servicio
*/
public static Map<String, Object> ejecutarGet(String endpoint, Map<String, String> cabeceras, Map<String, Object> parametrosConsulta) {
try (CloseableHttpClient cliente = HttpClients.createDefault()) {
// Construir URL con parámetros de consulta
String urlCompleta = endpoint;
if (parametrosConsulta != null && !parametrosConsulta.isEmpty()) {
StringBuilder constructorUrl = new StringBuilder(endpoint);
boolean tieneConsulta = endpoint.contains("?");
for (Map.Entry<String, Object> entrada : parametrosConsulta.entrySet()) {
constructorUrl.append(tieneConsulta ? "&" : "?")
.append(entrada.getKey())
.append("=")
.append(entrada.getValue());
tieneConsulta = true;
}
urlCompleta = constructorUrl.toString();
}
HttpGet solicitudGet = new HttpGet(urlCompleta);
// Establecer cabeceras
if (cabeceras != null) {
cabeceras.forEach(solicitudGet::setHeader);
}
try (CloseableHttpResponse respuesta = cliente.execute(solicitudGet)) {
org.apache.hc.core5.http.HttpEntity entidad = respuesta.getEntity();
String cuerpoRespuesta = EntityUtils.toString(entidad);
// Parsear respuesta JSON
ObjectMapper mapeador = new ObjectMapper();
return mapeador.readValue(cuerpoRespuesta, Map.class);
}
} catch (Exception e) {
log.error("Error al ejecutar solicitud GET, URL: {}", endpoint, e);
throw new RuntimeException("Fallo en la solicitud GET", e);
}
}
/**
* Ejecuta una solicitud POST
*
* @param endpoint URL del servicio
* @param cabeceras Encabezados de la solicitud
* @param cuerpoSolicitud Cuerpo de la solicitud
* @return Respuesta del servicio
*/
public static Map<String, Object> ejecutarPost(String endpoint, Map<String, String> cabeceras, Map<String, Object> cuerpoSolicitud) {
try (CloseableHttpClient cliente = HttpClients.createDefault()) {
HttpPost solicitudPost = new HttpPost(endpoint);
// Establecer cabeceras
if (cabeceras != null) {
cabeceras.forEach(solicitudPost::setHeader);
}
// Establecer cuerpo de la solicitud
if (cuerpoSolicitud != null) {
String jsonCuerpo;
jsonCuerpo = new ObjectMapper().writeValueAsString(cuerpoSolicitud);
StringEntity entidad = new StringEntity(jsonCuerpo, ContentType.APPLICATION_JSON);
solicitudPost.setEntity(entidad);
}
try (CloseableHttpResponse respuesta = cliente.execute(solicitudPost)) {
org.apache.hc.core5.http.HttpEntity entidad = respuesta.getEntity();
if (entidad != null) {
String cuerpoRespuesta = EntityUtils.toString(entidad);
// Parsear respuesta JSON
ObjectMapper mapeador = new ObjectMapper();
return mapeador.readValue(cuerpoRespuesta, Map.class);
} else {
return new HashMap<>(); // Devolver Map vacío en lugar de null
}
}
} catch (Exception e) {
log.error("Error al ejecutar solicitud POST, URL: {}", endpoint, e);
throw new RuntimeException("Fallo en la solicitud POST", e);
}
}
/**
* Ejecuta una solicitud PUT
*
* @param endpoint URL del servicio
* @param cabeceras Encabezados de la solicitud
* @param cuerpoSolicitud Cuerpo de la solicitud
* @return Respuesta del servicio
*/
public static Map<String, Object> ejecutarPut(String endpoint, Map<String, String> cabeceras, Map<String, Object> cuerpoSolicitud) {
try (CloseableHttpClient cliente = HttpClients.createDefault()) {
HttpPut solicitudPut = new HttpPut(endpoint);
// Establecer cabeceras
if (cabeceras != null) {
cabeceras.forEach(solicitudPut::setHeader);
}
// Establecer cuerpo de la solicitud
if (cuerpoSolicitud != null) {
String jsonCuerpo;
jsonCuerpo = new ObjectMapper().writeValueAsString(cuerpoSolicitud);
StringEntity entidad = new StringEntity(jsonCuerpo, ContentType.APPLICATION_JSON);
solicitudPut.setEntity(entidad);
}
try (CloseableHttpResponse respuesta = cliente.execute(solicitudPut)) {
org.apache.hc.core5.http.HttpEntity entidad = respuesta.getEntity();
String cuerpoRespuesta = EntityUtils.toString(entidad);
// Parsear respuesta JSON
ObjectMapper mapeador = new ObjectMapper();
return mapeador.readValue(cuerpoRespuesta, Map.class);
}
} catch (Exception e) {
log.error("Error al ejecutar solicitud PUT, URL: {}", endpoint, e);
throw new RuntimeException("Fallo en la solicitud PUT", e);
}
}
}
Para utilizar esta clase, simplemente especifique la URL, el cuerpo de la solicitud y las cabeceras, luego invoque el método correspondiente según el tipo de operación:
@Override
public String prueba(Map<String, Object> parametros) {
String url = urlBase + "/objeto/" + "DFCV_PC_DISPOSITIVO" + "/instancia/_buscar";
Map<String, String> cabecerasHttp = new HashMap<>();
cabecerasHttp.put("host", "cmdb_recurso.easyops-unico.com");
cabecerasHttp.put("usuario", "easyops");
cabecerasHttp.put("organizacion", "20240918");
cabecerasHttp.put("Tipo-Contenido", "application/json");
Map<String, Object> cuerpoSolicitud = new HashMap<>();
cuerpoSolicitud.put("pagina", 1);
cuerpoSolicitud.put("tamano_pagina", 20);
cuerpoSolicitud.put("ignorar_error_campo_faltante", "true");
return ClienteHttpUtil.ejecutarPost(url, cabecerasHttp, cuerpoSolicitud);
}