org.springframework.web.client.HttpClientErrorException: 401 Unauthorized - spring

I have web service URL:
http://myservice.local/aprovalanduser/?format=json&Name=India
When I am calling this URL using
resttemplate httpsrestTemplate.getForObject(uri, userdetails[].class)
I am getting error:
org.springframework.web.client.HttpClientErrorException: 401 Unauthorized
in the web service method:
method: "GET",
data: xmlData,
contentType: "application/xml",
dataType: "xml",
async: true,
crossDomain: false,
I am setting the header only for XML like below:
headers.setContentType(MediaType.APPLICATION_XML);

Here is the code which does basic authentication as suggested by #ekem chitsiga
String plainCreds = "username:password";
byte[] plainCredsBytes = plainCreds.getBytes();
byte[] base64CredsBytes = Base64.encodeBase64(plainCredsBytes);
String base64Creds = new String(base64CredsBytes);
HttpHeaders headers = new HttpHeaders();
headers.add("Authorization", "Basic " + base64Creds);
HttpEntity<String> request = new HttpEntity<String>(headers);
RestTemplate restTemplate = new RestTemplate();
String url = "http://myservice.local/aprovalanduser/?format=json&Name=India";
ResponseEntity<Object> response = restTemplate.exchange(url, HttpMethod.GET, request, Object.class);
response.getBody();

Http status code 401 means that you need to supply credentials to access the service. The way you present the credentials dependends on the authentication mechanism used by the service
For example if it uses Basic Authentication then you need to add a Authorization request header with Basic prefix and a base64 encoded combination of username and password separated by :

String plainCreds_usuario = Constants.CREDENCIAL_REST_API_ODATA_USUARIO;
String plainCreds_password = Constants.CREDENCIAL_REST_API_ODATA_PASSWORD;
String plainCreds = plainCreds_usuario+":"+plainCreds_password;
byte[] plainCredsBytes = plainCreds.getBytes();
byte[] base64CredsBytes = Base64.encodeBase64(plainCredsBytes);
String base64Creds = new String(base64CredsBytes);
HttpHeaders headers = new HttpHeaders();
headers.add("Authorization", "Basic " + base64Creds);
HttpEntity<String> request = new HttpEntity<String>(headers);
RestTemplate restTemplate = new RestTemplate();
ResponseEntity<Object> response = restTemplate.exchange(Constants.getRutaApiOdataHttp() + Constants.WS_REST_API_ODATA_GET_EMPRESAS, HttpMethod.GET, request, Object.class);
response.getBody();
if(response != null && response.getBody() != null){
System.out.println("YES");
System.out.println(response.getBody().toString());
}
else
{
System.out.println("NONES");
}

Related

When trying to invoke rest API throws httpmediatypenotsupportedexception content type 'application/x-www-form-urlencoded' not supported

I am trying to invoke rest API below which consumes a multi-part file. First paramter is a MultipartFile and second is s String. and this functions processes some business logic
#PostMapping( value="/uploadFile", consumes = MediaType.MULTIPART_FORM_DATE_VALUE)
public ResponseEntity<String> upload(#RequestPart("file") MultipartFile file,
#RequestParam("path") String path){
//businness logic
}
Invoking above API from code below. But it throws
httpmediatypenotsupportedexception content type
'application/x-www-form-urlencoded' not supported. I have also tried
added header "Content-type", MediaType.MULTIPART_FORM_DATA_VALUE OR
"Content-Type", "multipart/form-data" OR "Accept",
"multipart/form-data" in the headers below, but that has not helped
either
public void uploadFile() {
Path path = Paths.get("C:/ABC.txt");
byte[] content = null;
try{
content = Files.readAllBytes(path); // All file is read in content variable
} catch(final IOException e){
}
MultipartFile file = new MockMultipartFile("ABC.txt",content);
UriComponentsBuilder urlBuilder = UriComponentsBuilder.fromHttpUrl(oauthURL);
urlBuilder.queryParam("file", file);
urlBuilder.queryParam("path", "/temp);
HttpHeaders headers = new HttpHeaders();
HttpEntity<String> response = null;
HttpEntity<?> entity = new HttpEntity<>(headers);
try{
response = restTemplate.exchange(urlBuilder.build().encode().toUri(), HttpMethod.POST, entity. String.class);
}
catch (Exception e){
}
}
}
Your server accepts (consumes) "multipart/form-data" however you are sending the file and path in the URL. This will always result in a "application/x-www-form-urlencoded".
So you need to change the server to accept it as you send them or send the file and path as the body (within the entity)
EDIT (some code to show how):
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.MULTIPART_FORM_DATA);
MultiValueMap<String, Object> body = new LinkedMultiValueMap<>();
body.add("file", file);
body.add("path","/temp");
HttpEntity<MultiValueMap<String, Object>> requestEntity = new HttpEntity<>(body, headers);
response = restTemplate.postForEntity(serverUrl, requestEntity, String.class);

How to add file as Form data in Http request in spring boot

I'm writing test cases to a controller in spring boot which takes MultipartFile as RequestParam. In the test case method I'm using TestRestTemplate.exchange() to send the request to the controller. I'm not sure how to make the Headers correctly so that I can send the request.
The Postman curl looks like this:
curl --location --request POST 'localhost:9091/response/upload'
--form 'file=#"/home/adityak/Downloads/ClientLog_NEW.txt"'
For file uploading to any service or endpoint
private String testExchange(File file) {
//add file
LinkedMultiValueMap<String, Object> params = new LinkedMultiValueMap<>();
params.add("file", new FileSystemResource(file));
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.MULTIPART_FORM_DATA);
HttpEntity<LinkedMultiValueMap<String, Object>> requestEntity =
new HttpEntity<>(params, headers);
ResponseEntity<String> responseEntity = restTemplate.exchange(
"/upload-file",
HttpMethod.POST,
requestEntity,
String.class);
HttpStatus statusCode = responseEntity.getStatusCode();
if (statusCode == HttpStatus.ACCEPTED) {
result = responseEntity.getBody();
}
return result;
}

RestTemplate - 415 UNSUPPORTED_MEDIA_TYPE Error

I want to call a REST service from my application. I'm not passing any request to this call. But I can't figure out from where it comes from?
RestTemplate restTemplate = new RestTemplate();
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
MultiValueMap<String, String> map = new LinkedMultiValueMap<String, String>();
map.add("username", bonitaUsername);
map.add("password", bonitaPassword);
map.add("redirect", "false");
HttpMessageConverter formHttpMessageConverter = new FormHttpMessageConverter();
HttpMessageConverter stringHttpMessageConverternew = new StringHttpMessageConverter();
List<HttpMessageConverter<?>> converters = new ArrayList<>();
converters.add(formHttpMessageConverter);
converters.add(stringHttpMessageConverternew);
restTemplate.setMessageConverters(converters);
HttpEntity<MultiValueMap<String, String>> httpEntity = new HttpEntity<>(map, headers);
ResponseEntity<?> response = restTemplate.exchange(url, HttpMethod.POST, httpEntity, String.class);
List<String> cookies = response.getHeaders().get("Set-Cookie");
String cookieString = "";
for (String cookie : cookies) {
System.out.println();
cookieString += cookie.split(";")[0] + "; ";
}
return cookieString;
This happens due to the mismatch of content types which passing to REST template. Please make sure to send the correct content type. Some times we are receiving JSON request but we need to send as another format.

Spring RestTemplate exchange return 204 and in postman 200

I'm turning around since this morning , i've this method that return NO_CONTENT (204) in Java, but when i execute the same URL in postman i got Content (200)
String encodedCredentials = getEncodedCredentials(deviceConfigurationInstance);
RestTemplate restTemplate = getRestTemplate(url, deviceConfigurationInstance);
HttpHeaders headers = new HttpHeaders();
headers.add("Authorization", "Basic " + encodedCredentials);
headers.setContentType(MediaType.APPLICATION_JSON);
headers.add("Accept", "*/*");
HttpEntity<String> request = new HttpEntity<String>(headers);
ResponseEntity<T> response = restTemplate.exchange(url, HttpMethod.GET, request, retType);
return response;
I've add the credential in postman also
What i've forgot in Java ?
Note : retType has Class<T> as type

RestTemplate authentication while setting userName and password

I have a curl command but I want to pass this information with userName and password while calling the rest API, every thing I have tried doesn't work.
curl -u E-BOARD:HVRid992Xl740NnWOkjk -X GET --header 'Accept: application/json' 'https://XXXXXX.fr/AAAAAA/BBBBB/v1/details?abc=hsdfh&zyx=asdfsdf
My rest API looks something like this
String url = new StringBuilder(urlConfigService.getProfiles().getBaseUrl()).append(relativeUrl).toString();
**String hiddenAccess = "ASHGHGHJ:HVRid992Xl740NnWOkjk";**
// #formatter:off
UriComponentsBuilder builder = UriComponentsBuilder.fromHttpUrl(url)
.queryParam("refEboard", refEboard)
.queryParam("idLangue", "FR");
// #formatter:on
HttpHeaders requestHeaders = new HttpHeaders();
requestHeaders.setContentType(MediaType.APPLICATION_JSON);
requestHeaders.add("Authorization", hiddenAccess);
HttpEntity<?> httpEntity = new HttpEntity<String>(requestHeaders);
restTemplate.getMessageConverters().add(0, new StringHttpMessageConverter(Charset.forName("UTF-8")));
String result =
restTemplate.exchange(builder.build().toUri(), HttpMethod.GET, httpEntity, String.class).getBody();
return (T) new Gson().fromJson(result, type.getClass());
It seems to me that you are trying to send basic authentication credentials. To do this you have to encode username and password in Base64 and set request header like this:
Basic (username:password Base64 Encoded)
This is how you do it:
RestTemplate restTemplate = new RestTemplate();
HttpHeaders header = new HttpHeaders();
String auth = username + ":" + password;
byte [] authentication = auth.getBytes();
byte[] base64Authentication = Base64Utils.encode(authentication);
String baseCredential = new String(base64Authentication);
header.add(HttpHeaders.AUTHORIZATION, "Basic " + baseCredential);
header.setAccept(Collections.singletonList(MediaType.TEXT_PLAIN));
HttpEntity<String> request = new HttpEntity<String>(header);
restTemplate.exchange(builder.build().toUri(), HttpMethod.GET, request, String.class);

Resources