Skip to content

Instantly share code, notes, and snippets.

@slmanju
Created January 25, 2018 05:46
Show Gist options
  • Save slmanju/a85a6854cb7d37d069351edae06a4eb7 to your computer and use it in GitHub Desktop.
Save slmanju/a85a6854cb7d37d069351edae06a4eb7 to your computer and use it in GitHub Desktop.
Generic RestTemplate wrapper
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.type.CollectionType;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.web.client.RestTemplateBuilder;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpMethod;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Component;
import org.springframework.web.client.HttpClientErrorException;
import org.springframework.web.client.RestClientException;
import org.springframework.web.client.RestTemplate;
import java.io.IOException;
import java.util.List;
@Component
public class RestTemplateHelper {
private static final Logger LOGGER = LoggerFactory.getLogger(RestTemplateHelper.class);
private RestTemplate restTemplate;
private ObjectMapper objectMapper;
@Autowired
public RestTemplateHelper(RestTemplateBuilder restTemplateBuilder, ObjectMapper objectMapper) {
this.restTemplate = restTemplateBuilder.build();
this.objectMapper = objectMapper;
}
public <T> T getForEntity(Class<T> clazz, String url, Object... uriVariables) {
try {
ResponseEntity<String> response = restTemplate.getForEntity(url, String.class, uriVariables);
JavaType javaType = objectMapper.getTypeFactory().constructType(clazz);
return readValue(response, javaType);
} catch (HttpClientErrorException exception) {
if (exception.getStatusCode() == HttpStatus.NOT_FOUND) {
LOGGER.info("No data found {}", url);
} else {
LOGGER.info("rest client exception", exception.getMessage());
}
}
return null;
}
public <T> List<T> getForList(Class<T> clazz, String url, Object... uriVariables) {
try {
ResponseEntity<String> response = restTemplate.getForEntity(url, String.class, uriVariables);
CollectionType collectionType = objectMapper.getTypeFactory().constructCollectionType(List.class, clazz);
return readValue(response, collectionType);
} catch (HttpClientErrorException exception) {
if (exception.getStatusCode() == HttpStatus.NOT_FOUND) {
LOGGER.info("No data found {}", url);
} else {
LOGGER.info("rest client exception", exception.getMessage());
}
}
return null;
}
public <T, R> T postForEntity(Class<T> clazz, String url, R body, Object... uriVariables) {
HttpEntity<R> request = new HttpEntity<>(body);
ResponseEntity<String> response = restTemplate.postForEntity(url, request, String.class, uriVariables);
JavaType javaType = objectMapper.getTypeFactory().constructType(clazz);
return readValue(response, javaType);
}
public <T, R> T putForEntity(Class<T> clazz, String url, R body, Object... uriVariables) {
HttpEntity<R> request = new HttpEntity<>(body);
ResponseEntity<String> response = restTemplate.exchange(url, HttpMethod.PUT, request, String.class, uriVariables);
JavaType javaType = objectMapper.getTypeFactory().constructType(clazz);
return readValue(response, javaType);
}
public void delete(String url, Object... uriVariables) {
try {
restTemplate.delete(url, uriVariables);
} catch (RestClientException exception) {
LOGGER.info(exception.getMessage());
}
}
private <T> T readValue(ResponseEntity<String> response, JavaType javaType) {
T result = null;
if (response.getStatusCode() == HttpStatus.OK ||
response.getStatusCode() == HttpStatus.CREATED) {
try {
result = objectMapper.readValue(response.getBody(), javaType);
} catch (IOException e) {
LOGGER.info(e.getMessage());
}
} else {
LOGGER.info("No data found {}", response.getStatusCode());
}
return result;
}
}
private RestTemplateHelper restTemplateHelper;
// other codes...
// find by id
UserDto userDto = restTemplateHelper.getForEntity(UserDto.class, "http://localhost:8080/users/{id}", id);
// find all
UserDto userDto = restTemplateHelper.getForList(UserDto.class, "http://localhost:8080/users");
// save
UserDto userDto = restTemplateHelper.postForEntity(UserDto.class, "http://localhost:8080/users", userDto);
// update
UserDto userDto = restTemplateHelper.putForEntity(UserDto.class, "http://localhost:8080/users/{id}", userDto, id);
// delete
restTemplateHelper.delete("http://localhost:8080/users/{id}", id);
Copy link

ghost commented Dec 25, 2020

Great! I found this very useful

@Artanniel
Copy link

Great!
Thanks!

@AlexKukhtinDev
Copy link

Maybe someone have exchange implementation?

@thiagocavalcanti
Copy link

Maybe someone have exchange implementation?

restTemplate.exchange(url, HttpMethod.GET, new HttpEntity<>(headers), String.class);

@thiagocavalcanti
Copy link

thiagocavalcanti commented Aug 28, 2022

If you want to return something like ResponseWrapper<T> you can use this:

 public <T> ListWrapperDTO<T> getForWrapper(String url, HttpHeaders headers,  Class<T> clazz) {
        return restTemplate.exchange(url, HttpMethod.GET, new HttpEntity<>(headers),
                new ParameterizedTypeReference<ListWrapperDTO<T>>() {
                    public Type getType() {
                        return new CustomParameterizedType((ParameterizedType) super.getType(), new Type[]{clazz});
                    }
                }
        ).getBody();
    }

where

class CustomParameterizedType implements ParameterizedType {
    private final ParameterizedType delegate;
    private final Type[] actualTypeArguments;
    
    CustomParameterizedType(ParameterizedType delegate, Type[] actualTypeArguments) {
        this.delegate = delegate;
        this.actualTypeArguments = actualTypeArguments;
    }
    
    @Override
    public Type[] getActualTypeArguments() {
        return actualTypeArguments;
    }
    
    @Override
    public Type getRawType() {
        return delegate.getRawType();
    }
    
    @Override
    public Type getOwnerType() {
        return delegate.getOwnerType();
    }
    
}

@mariocodev
Copy link

Maybe someone have exchange implementation?

    public <T> T getForExchange(Class<T> clazz, String url, HttpHeaders headers) {
        return exchange(clazz, url, HttpMethod.GET, new HttpEntity<>(headers));
    }

    public <T> T postForExchange(Class<T> clazz, String url, Object body, HttpHeaders headers) {
        return exchange(clazz, url, HttpMethod.POST, new HttpEntity<>(body, headers));
    }

    private <T> T exchange(Class<T> clazz, String url, HttpMethod method, HttpEntity<Object> entity) {
        try {
            ResponseEntity<String> response = restTemplate.exchange(url, method, entity, String.class);
            JavaType javaType = objectMapper.getTypeFactory().constructType(clazz);
            return readValue(response, javaType);
        } catch (HttpClientErrorException exception) {
            if (exception.getStatusCode().is4xxClientError()) {
                LOGGER.info("Error en la solicitud HTTP: {}", exception.getMessage());
            } else {
                LOGGER.error("Error en la solicitud HTTP: {}", exception.getMessage(), exception);
            }
        }
        return null;
    }

Examples

HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
headers.setBearerAuth("your_access_token");

// GET
UserDto userDto = restTemplateHelper.getForExchange(UserDto.class, "https://api.example.com/data/" + id, headers);

// POST
UserDto userDto = restTemplateHelper.postForExchange(UserDto.class, "https://api.example.com/data", userDto, headers);


Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment