es.prodevelop.pui9.utils.PuiExternalRequest Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of es.prodevelop.pui9.services Show documentation
Show all versions of es.prodevelop.pui9.services Show documentation
Support for business layer (BO)
package es.prodevelop.pui9.utils;
import java.net.SocketTimeoutException;
import java.net.URI;
import java.util.Collections;
import org.springframework.core.ParameterizedTypeReference;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.http.client.SimpleClientHttpRequestFactory;
import org.springframework.util.CollectionUtils;
import org.springframework.web.client.HttpClientErrorException;
import org.springframework.web.client.HttpServerErrorException;
import org.springframework.web.client.ResourceAccessException;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.util.DefaultUriBuilderFactory;
import org.springframework.web.util.DefaultUriBuilderFactory.EncodingMode;
import org.springframework.web.util.UriComponentsBuilder;
import es.prodevelop.pui9.data.converters.PuiGsonHttpMessageConverter;
import es.prodevelop.pui9.exceptions.PuiException;
import es.prodevelop.pui9.exceptions.PuiExceptionDto;
import es.prodevelop.pui9.json.GsonSingleton;
import es.prodevelop.pui9.login.PuiUserSession;
import es.prodevelop.pui9.services.exceptions.PuiServiceTimeoutException;
/**
* Utility class to make external request from PUI server to anywhere. POST and
* GET methods are accepted. It uses the {@link RestTemplate} object of Spring
* to make the requests. User {@link PuiExternalRequestConfig} to configure an
* external call
*
* @author Marc Gil - [email protected]
*/
public class PuiExternalRequest {
private static PuiExternalRequest singleton;
public static PuiExternalRequest getSingleton() {
if (singleton == null) {
singleton = new PuiExternalRequest();
}
return singleton;
}
/**
* Configure the {@link RestTemplate} object with the valid converters for PUI
*/
private PuiExternalRequest() {
}
private RestTemplate createRestTemplate(PuiExternalRequestConfig config) {
RestTemplate restTemplate = new RestTemplate();
if (restTemplate.getRequestFactory() instanceof SimpleClientHttpRequestFactory) {
configureTemplateSetTimeouts(restTemplate, config.getTimeout());
}
configureTemplateSetConverters(restTemplate);
configureTemplateEncoding(restTemplate);
return restTemplate;
}
private HttpHeaders createHttpHeaders(PuiExternalRequestConfig config) {
HttpHeaders baseHeaders = new HttpHeaders();
baseHeaders.setAccept(Collections.singletonList(config.getContentType()));
baseHeaders.setContentType(config.getContentType());
HttpHeaders newHeaders = config.getHeaders() != null ? config.getHeaders() : new HttpHeaders();
baseHeaders.forEach(newHeaders::putIfAbsent);
newHeaders.putIfAbsent(HttpHeaders.ACCEPT_LANGUAGE,
Collections.singletonList(PuiUserSession.getSessionLanguage().getIsocode()));
return newHeaders;
}
/**
* Change the timeout of the request. By default, 10000 milliseconds are set if
* the milliseconds parameter is null
*
* @param milliseconds
*/
private void configureTemplateSetTimeouts(RestTemplate restTemplate, Integer milliseconds) {
if (milliseconds == null) {
milliseconds = PuiExternalRequestConfig.DEFAULT_TIMEOUT;
}
SimpleClientHttpRequestFactory factory = (SimpleClientHttpRequestFactory) restTemplate.getRequestFactory();
factory.setReadTimeout(milliseconds);
factory.setConnectTimeout(milliseconds);
}
private void configureTemplateSetConverters(RestTemplate restTemplate) {
restTemplate.getMessageConverters().add(0, new PuiGsonHttpMessageConverter());
}
private void configureTemplateEncoding(RestTemplate restTemplate) {
DefaultUriBuilderFactory uriFactory = new DefaultUriBuilderFactory();
uriFactory.setEncodingMode(EncodingMode.VALUES_ONLY);
restTemplate.setUriTemplateHandler(uriFactory);
}
/**
* Execute a GET request. This call is synchonous
*
* @param The type of the response object
* @param config The configuration object
* @return The response
* @throws PuiException If any exception occurs
*/
@SuppressWarnings("unchecked")
public RETURN executeGet(PuiExternalRequestConfig config) throws PuiException {
String url = config.getUrl();
if (!CollectionUtils.isEmpty(config.getParams())) {
url = UriComponentsBuilder.fromHttpUrl(url).queryParams(config.getParams()).toUriString();
}
RestTemplate restTemplate = createRestTemplate(config);
HttpHeaders httpHeaders = createHttpHeaders(config);
HttpEntity entity = new HttpEntity<>(httpHeaders);
try {
ResponseEntity response;
if (config.getReturnClass() != null) {
response = restTemplate.exchange(url, HttpMethod.GET, entity, (Class) config.getReturnClass());
} else if (config.getReturnParameterizedType() != null) {
response = restTemplate.exchange(url, HttpMethod.GET, entity,
(ParameterizedTypeReference) config.getReturnParameterizedType());
} else {
response = restTemplate.exchange(url, HttpMethod.GET, entity, (Class) Void.class);
}
if (response.getStatusCode().equals(HttpStatus.MOVED_PERMANENTLY)) {
changeLocation(config, response);
return executeGet(config);
}
return response.getBody();
} catch (Exception e) {
throw new PuiException(e);
}
}
/**
* Execute a POST request. This call is synchonous.
*
* @param The type of the body object
* @param The type of the response object
* @param config The configuration object
* @return The response
* @throws PuiException If any exception occurs
*/
@SuppressWarnings("unchecked")
public RETURN executePost(PuiExternalRequestConfig config) throws PuiException {
String url = config.getUrl();
if (!CollectionUtils.isEmpty(config.getParams())) {
url = UriComponentsBuilder.fromHttpUrl(url).queryParams(config.getParams()).toUriString();
}
RestTemplate restTemplate = createRestTemplate(config);
HttpHeaders httpHeaders = createHttpHeaders(config);
HttpEntity entity = new HttpEntity<>((BODY) config.getBody(), httpHeaders);
try {
ResponseEntity response;
if (config.getReturnClass() != null) {
response = restTemplate.postForEntity(url, entity, (Class) config.getReturnClass());
} else if (config.getReturnParameterizedType() != null) {
response = restTemplate.exchange(url, HttpMethod.POST, entity,
(ParameterizedTypeReference) config.getReturnParameterizedType());
} else {
response = restTemplate.postForEntity(url, entity, (Class) Void.class);
}
if (response.getStatusCode().equals(HttpStatus.MOVED_PERMANENTLY)) {
changeLocation(config, response);
return executePost(config);
}
return response.getBody();
} catch (HttpServerErrorException e1) {
String errorJson = e1.getResponseBodyAsString();
PuiException e;
try {
PuiExceptionDto error = GsonSingleton.getSingleton().getGson().fromJson(errorJson,
PuiExceptionDto.class);
error.setStatusCode(e1.getStatusCode().value());
e = PuiException.fromTransferObject(error);
} catch (Exception e2) {
e = new PuiException(e1, e1.getStatusText());
e.setStatusResponse(e1.getStatusCode().value());
}
throw e;
} catch (HttpClientErrorException e1) {
PuiException e = new PuiException(e1, e1.getStatusText());
e.setStatusResponse(e1.getStatusCode().value());
throw e;
} catch (ResourceAccessException e) {
if (e.getCause() instanceof SocketTimeoutException) {
throw new PuiServiceTimeoutException(config.getTimeout());
} else {
throw new PuiException(e);
}
} catch (Exception e) {
throw new PuiException(e);
}
}
/**
* Execute a PUT request. This call is synchonous.
*
* @param The type of the body object
* @param The type of the response object
* @param config The configuration object
* @return The response
* @throws PuiException If any exception occurs
*/
@SuppressWarnings("unchecked")
public RETURN executePut(PuiExternalRequestConfig config) throws PuiException {
String url = config.getUrl();
if (!CollectionUtils.isEmpty(config.getParams())) {
url = UriComponentsBuilder.fromHttpUrl(url).queryParams(config.getParams()).toUriString();
}
RestTemplate restTemplate = createRestTemplate(config);
HttpHeaders httpHeaders = createHttpHeaders(config);
HttpEntity entity = new HttpEntity<>((BODY) config.getBody(), httpHeaders);
try {
ResponseEntity response;
if (config.getReturnClass() != null) {
response = restTemplate.exchange(url, HttpMethod.PUT, entity, (Class) config.getReturnClass());
} else if (config.getReturnParameterizedType() != null) {
response = restTemplate.exchange(url, HttpMethod.PUT, entity,
(ParameterizedTypeReference) config.getReturnParameterizedType());
} else {
response = restTemplate.exchange(url, HttpMethod.PUT, entity, (Class) Void.class);
}
if (response.getStatusCode().equals(HttpStatus.MOVED_PERMANENTLY)) {
changeLocation(config, response);
return executePut(config);
}
return response.getBody();
} catch (HttpServerErrorException e1) {
String errorJson = e1.getResponseBodyAsString();
PuiException e;
try {
PuiExceptionDto error = GsonSingleton.getSingleton().getGson().fromJson(errorJson,
PuiExceptionDto.class);
error.setStatusCode(e1.getStatusCode().value());
e = PuiException.fromTransferObject(error);
} catch (Exception e2) {
e = new PuiException(e1, e1.getStatusText());
e.setStatusResponse(e1.getStatusCode().value());
}
throw e;
} catch (HttpClientErrorException e1) {
PuiException e = new PuiException(e1, e1.getStatusText());
e.setStatusResponse(e1.getStatusCode().value());
throw e;
} catch (ResourceAccessException e) {
if (e.getCause() instanceof SocketTimeoutException) {
throw new PuiServiceTimeoutException(config.getTimeout());
} else {
throw new PuiException(e);
}
} catch (Exception e) {
throw new PuiException(e);
}
}
/**
* Execute a PATCH request. This call is synchonous. This call should include
* the PK as URL parameter, and an object set with the keys-values to be patched
* as body of the request
*
* @param The type of the body object
* @param The type of the response object
* @param config The configuration object
* @return The response
* @throws PuiException If any exception occurs
*/
@SuppressWarnings("unchecked")
public RETURN executePatch(PuiExternalRequestConfig config) throws PuiException {
String url = config.getUrl();
if (!CollectionUtils.isEmpty(config.getParams())) {
url = UriComponentsBuilder.fromHttpUrl(url).queryParams(config.getParams()).toUriString();
}
RestTemplate restTemplate = createRestTemplate(config);
HttpHeaders httpHeaders = createHttpHeaders(config);
HttpEntity entity = new HttpEntity<>((BODY) config.getBody(), httpHeaders);
try {
ResponseEntity response;
if (config.getReturnClass() != null) {
response = restTemplate.exchange(url, HttpMethod.PATCH, entity,
(Class) config.getReturnClass());
} else if (config.getReturnParameterizedType() != null) {
response = restTemplate.exchange(url, HttpMethod.PATCH, entity,
(ParameterizedTypeReference) config.getReturnParameterizedType());
} else {
response = restTemplate.exchange(url, HttpMethod.PATCH, entity, (Class) Void.class);
}
if (response.getStatusCode().equals(HttpStatus.MOVED_PERMANENTLY)) {
changeLocation(config, response);
return executePatch(config);
}
return response.getBody();
} catch (HttpServerErrorException e1) {
String errorJson = e1.getResponseBodyAsString();
PuiException e;
try {
PuiExceptionDto error = GsonSingleton.getSingleton().getGson().fromJson(errorJson,
PuiExceptionDto.class);
error.setStatusCode(e1.getStatusCode().value());
e = PuiException.fromTransferObject(error);
} catch (Exception e2) {
e = new PuiException(e1, e1.getStatusText());
e.setStatusResponse(e1.getStatusCode().value());
}
throw e;
} catch (HttpClientErrorException e1) {
PuiException e = new PuiException(e1, e1.getStatusText());
e.setStatusResponse(e1.getStatusCode().value());
throw e;
} catch (ResourceAccessException e) {
if (e.getCause() instanceof SocketTimeoutException) {
throw new PuiServiceTimeoutException(config.getTimeout());
} else {
throw new PuiException(e);
}
} catch (Exception e) {
throw new PuiException(e);
}
}
/**
* Execute a DELETE request. This call is synchonous.
*
* @param config The configuration object
* @return The response
* @throws PuiException If any exception occurs
*/
public void executeDelete(PuiExternalRequestConfig config) throws PuiException {
String url = config.getUrl();
if (!CollectionUtils.isEmpty(config.getParams())) {
url = UriComponentsBuilder.fromHttpUrl(url).queryParams(config.getParams()).toUriString();
}
RestTemplate restTemplate = createRestTemplate(config);
HttpHeaders httpHeaders = createHttpHeaders(config);
HttpEntity entity = new HttpEntity<>((Void) config.getBody(), httpHeaders);
try {
ResponseEntity response = restTemplate.exchange(url, HttpMethod.DELETE, entity, Void.class);
if (response.getStatusCode().equals(HttpStatus.MOVED_PERMANENTLY)) {
changeLocation(config, response);
executeDelete(config);
}
} catch (HttpServerErrorException e) {
throw new PuiException(e);
}
}
private void changeLocation(PuiExternalRequestConfig config, ResponseEntity> response) throws PuiException {
URI location = response.getHeaders().getLocation();
if (location == null) {
throw new PuiException("Moved permanently, but no location specified");
}
config.withUrl(location.toString().replace(location.getQuery(), ""));
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy