'How to maintain utility class for rest calls using rest template?

I am using rest template for each method in my service implementation is there any way to create utility class for rest template to pass url and request parameters?

Thanks & Regards

Anita patil



Solution 1:[1]

please refer this code snippet were i have added almost all http method

package com.util;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.util.UriComponentsBuilder;

@Service
public class HttpService
{
	private static final Logger logger = LogManager.getLogger(HttpService.class);
	private final RestTemplate restTemplate;

	@Autowired
	public HttpService(RestTemplate restTemplate) {this.restTemplate = restTemplate;}

	/**
	 * The simple get request
	 * @param url - url need to call
	 * @return
	 */
	public ResponseEntity  get(String url)
	{
		return restTemplate.getForEntity(url, String.class);
	}


	/**
	 *
	 * @param builder - contain url and request parameter
	 * @return
	 */
	public ResponseEntity  get(UriComponentsBuilder builder)
	{
		return restTemplate.getForEntity(builder.build().toUri(), String.class);
	}

	/**
	 * The get request with request parameters
	 * @param builder - Uri builder contain url and request parameter
	 * @param httpHeaders - header need to send
	 * @return
	 */
	public ResponseEntity get(UriComponentsBuilder builder, HttpHeaders httpHeaders){

		HttpEntity<?> entity = new HttpEntity<>(httpHeaders);
		return restTemplate.exchange(builder.build().toUri(), HttpMethod.GET, entity, String.class);
	}

	public <T> ResponseEntity<T> get(UriComponentsBuilder builder, HttpHeaders httpHeaders, Class<T> responseType){

		HttpEntity<HttpHeaders> entity = new HttpEntity<>(httpHeaders);
		return restTemplate.exchange(builder.build().toUri(), HttpMethod.GET, entity, responseType);
	}
	/**
	 * The get method can be use for sending http get request with header parameter
	 * @param url - request url that need to call
	 * @param headers -  header that need to send.
	 * @return
	 */
	public ResponseEntity get(String url, HttpHeaders headers){
		HttpEntity<String> entity= new HttpEntity<>(headers);
		return restTemplate.exchange(url, HttpMethod.GET, entity, String.class);
	}

	/**
	 * The post method can use for post request with Request entity and Header
	 * The response will be return in response type class
	 * For passing header we need pass header in HttpEntity along with class that has to be send in request.
	 * example HttpEntity(object,header)
	 * For calling post with header only then we need to pass HttpEntity with header
	 * example HttpEntity(header);
	 * @param builder
	 * @param entity
	 * @param response
	 * @param <T>
	 * @param <P>
	 * @return
	 */
	public <T,P> T post(UriComponentsBuilder builder, HttpEntity<P> entity, Class<T> response){

		return restTemplate.postForObject(builder.build().toUri(), entity, response);
	}

	public void put() throws Exception
	{
		throw new Exception("not implemeted yet, implement when required");
	}

   }

Solution 2:[2]

This is what I wanted to look for over time. And that's why I'm sharing it in case it helps. Every time I want to use RestTemplate I use this utility class.

import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.logging.log4j.Logger;
import org.springframework.core.ParameterizedTypeReference;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.web.client.HttpStatusCodeException;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.util.UriComponentsBuilder;

import java.net.URI;
import java.nio.charset.StandardCharsets;
import java.util.function.Supplier;

import static com.montonio.util.StringUtil.beautify;
import static com.montonio.util.StringUtil.isBlank;


@Service
public class RestClient {

    private final Logger logger;
    private final RestTemplate restTemplate;

    public RestClient(Logger logger, RestTemplate restTemplate) {
        this.logger = logger;
        this.restTemplate = restTemplate;
    }

    private static <T> T parse(String str, Class<T> responseClass) {
        try {
            if (isBlank(str) || responseClass == null) return null;
            return new ObjectMapper().readValue(str, responseClass);
        } catch (Exception ex) {
            ex.printStackTrace();
            return null;
        }
    }

    public <T> ResponseEntity<T> getForEntity(String url, Class<T> responseClass) {
        logger.info("url: {}", url);
        URI uri = UriComponentsBuilder.fromHttpUrl(url).encode(StandardCharsets.US_ASCII).build(true).toUri();
        return exec(() -> restTemplate.getForEntity(uri, responseClass), responseClass);
    }

    public <T, R> ResponseEntity<T> postForEntityLogin(String url, R requestBody, Class<T> responseClass) {
        return exec(() -> restTemplate.postForEntity(url, requestBody, responseClass), responseClass);
    }

    public <T, R> ResponseEntity<T> postForEntity(String url, R requestBody, Class<T> responseClass) {
        logger.info("url: {}, request: {}", url, beautify(requestBody));
        return exec(() -> restTemplate.postForEntity(url, requestBody, responseClass), responseClass);
    }

    public <R, T> ResponseEntity<T> postForObject(String url, R requestBody, Class<T> responseClass) {
        logger.info("url: {}, request: {}", url, beautify(requestBody));
        return exec(() -> ResponseEntity.ok(restTemplate.postForObject(url, requestBody, responseClass)), responseClass);
    }

    public <R, T> ResponseEntity<T> putForEntity(String url, R requestBody, Class<T> responseClass) {
        logger.info("url: {}, request: {}", url, beautify(requestBody));
        return exec(() -> {
            restTemplate.put(url, requestBody);
            return ResponseEntity.ok().build();
        }, responseClass);
    }

    public <R> ResponseEntity putForEntityOrThrowEx(String url, R requestBody) {
        logger.info("url: {}, request: {}", url, beautify(requestBody));
        return execOrThrowEx(() -> {
            restTemplate.put(url, requestBody);
            return ResponseEntity.ok().build();
        });
    }

    public <T> ResponseEntity<T> getForEntityOrThrowEx(String url, Class<T> responseClass) {
        logger.info("url: {}", url);
        return execOrThrowEx(() -> restTemplate.getForEntity(url, responseClass));
    }

    public <T> ResponseEntity<T> getParametrizedWithExchangeOrThrowEx(String url, ParameterizedTypeReference<T> typeReference) {
        return getWithExchangeOrThrowEx(url, typeReference);
    }

    public <T> ResponseEntity<T> getWithExchangeOrThrowEx(String url, ParameterizedTypeReference<T> responseTypeReference) {
        logger.info("url: {}", url);
        return execOrThrowEx(() -> restTemplate.exchange(url, HttpMethod.GET, null, responseTypeReference));
    }

    public <T> ResponseEntity<T> getParametrizedWithExchange(String url, ParameterizedTypeReference<T> responseTypeReference) {
        logger.info("url: {}", url);
        return exec(() -> restTemplate.exchange(url, HttpMethod.GET, null, responseTypeReference), null);
    }

    public <T, R> ResponseEntity<T> postForEntityOrThrowEx(String url, R requestBody, Class<T> responseClass) {
        logger.info("url: {}, request: {}", url, beautify(requestBody));
        return execOrThrowEx(() -> restTemplate.postForEntity(url, requestBody, responseClass));
    }

    public <T, R> ResponseEntity<T> postForObjectOrThrowEx(String url, R requestBody, Class<T> responseClass) {
        logger.info("url: {}, request: {}", url, beautify(requestBody));
        return execOrThrowEx(() -> {
            restTemplate.postForObject(url, requestBody, responseClass);
            return ResponseEntity.ok().build();
        });
    }

    private <T> ResponseEntity<T> exec(Supplier<ResponseEntity> supplier, Class<T> response) {
        try {
            return supplier.get();
        } catch (HttpStatusCodeException httpException) {
            httpException.printStackTrace();
            logger.error("HttpClientException: {}", httpException.getLocalizedMessage());
            logger.error("HttpStatusCodeException: ", httpException);
            return ResponseEntity.status(httpException.getStatusCode()).body(parse(httpException.getResponseBodyAsString(), response));
        } catch (Exception exception) {
            logger.error("Exception: {}", exception.getLocalizedMessage());
            return ResponseEntity.status(500).build();
        }
    }

    private ResponseEntity execOrThrowEx(Supplier supplier) {
        try {
            return (ResponseEntity) supplier.get();
        } catch (Exception ex) {
            logger.error("HttpClientException: {}", ex.getLocalizedMessage());
            logger.error("HttpClientException: ", ex);
            throw new RuntimeException(ex);
        }
    }

    public <T> ResponseEntity<T> getParameterizedTypeWithExchange(String url, ParameterizedTypeReference<T> typeReference) {
        logger.info("url: {}", url);
        return exec1(() -> restTemplate.exchange(url, HttpMethod.GET, null, typeReference));
    }

    private ResponseEntity exec1(Supplier supplier) {
        return (ResponseEntity) supplier.get();
    }

    public <T> ResponseEntity<T> getForObject(String url, Class<T> responseClass) {
        logger.info("url: {}", url);
        return exec(() -> ResponseEntity.ok(restTemplate.getForObject(url, responseClass)), responseClass);
    }

    public <T> ResponseEntity<T> getForObject(String url, HttpEntity<T> requestEntity, Class<T> responseClass) {
        logger.info("url: {}", url);
        return exec(() -> restTemplate.exchange(url, HttpMethod.GET, requestEntity, responseClass), responseClass);
    }

    public <T> ResponseEntity<T> postForObjectWithExchange(String url, HttpEntity<T> requestEntity, Class<T> responseClass) {
        logger.info("url: {}", url);
        return exec(() -> restTemplate.exchange(url, HttpMethod.POST, requestEntity, responseClass), responseClass);
    }
}

and also there is I used StringUtil class which using in above utility class.

import com.fasterxml.jackson.databind.ObjectMapper;

public class StringUtil {

    private static final ObjectMapper objectMapper = new ObjectMapper();
    private String value;

    public StringUtil() {
    }

    public static String parseString(Object value) {
        if (value == null) return "";
        return defaultString(value);
    }


    public static boolean isBlank(Object str) {
        String str_ = defaultString(str);
        return StringUtil.isBlank(str_) || str_.trim().equalsIgnoreCase("null");
    }

    public static boolean isNotBlank(Object str) {
        return !isBlank(str);
    }

    public static String beautify(Object obj) {
        if (obj == null) return "";
        try {
            return objectMapper.writeValueAsString(obj);
        } catch (Exception ex) {
            return obj.toString();
        }
    }

    public static boolean equals(Object original, Object compare) {
        if (original == null && compare == null) return true;
        if (original == null || compare == null) return false;
        return original.toString().equals(compare.toString());
    }

    public static String valueOf(Object obj) {
        if (obj == null) return null;
        return obj + "";
    }

    public static String defaultString(Object str) {
        return defaultString(str, "");
    }

    public static String defaultString(Object str, String defaultStr) {
        if (str == null || str.toString().trim().length() == 0 || str.toString().trim().equalsIgnoreCase("null")) {
            return defaultStr;
        }
        return str.toString();
    }

    public static String substring(String str, int begin, int end) {
        if (isBlank(str)) return str;
        return str.substring(begin, end);
    }

    public String getValue() {
        return this.value;
    }

}

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Pratik Bhajankar
Solution 2 debugmode