0

I've been reading the following and trying to send a POST request with Spring Boot, using RestTemplate.

HttpHeaders headers = new HttpHeaders();
headers.add("content-type", "application/x-www-form-urlencoded");

final String body = "clipmessage={ bridgeId: \"" + user.getBridgeId() + "\", clipCommand: { url: \"" + setLightState("3") + "\", method: \"PUT\", body: { \"on\": " + state.isOn() + " } } }";
final String url = API_ADDRESS + user.getAccessToken();

HttpEntity<String> entity = new HttpEntity<>(body, headers);

restTemplate.postForEntity(url, entity, String.class);

If I log the URL and the body and send the exact same in Postman, it succeeds. However, not when I send it from my Spring Boot application.

I'm guessing that special body has to be sent in some special way which that I am not aware off?

Anyone has any tips on what to try here next?

UPDATE 1: I tried the MultiValueMap as suggested, but did not get that to work either.

MultiValueMap<String, Object> map = new LinkedMultiValueMap<>();

final String body = "{ bridgeId: \"" + user.getBridgeId() + "\", clipCommand: { url: \"" + setLightState("3") + "\", method: \"PUT\", body: { \"on\": " + state.isOn() + " } } }";

map.add("clipmessage", body);

HttpEntity<String> entity = new HttpEntity<>(body, headers);
Viktor Plane
  • 127
  • 3
  • 16
  • 3
    The value of the `clipmessage` field needs to be URL encoded. – Andreas Jun 04 '17 at 19:45
  • 1
    https://docs.oracle.com/javase/8/docs/api/java/net/URLEncoder.html. And frankly, sending hand-crafted JSON as the value of a unique POST parameter is really ugly. Why don't you just send a JSON body? – JB Nizet Jun 04 '17 at 19:47
  • Since you're using Spring and a `RestTemplate`, just build a `MultiValueMap` as shown in the javadoc of [`FormHttpMessageConverter`](http://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/http/converter/FormHttpMessageConverter.html). – Andreas Jun 04 '17 at 19:53
  • It's the Philips Hue Remote API that requires it to be like that, ugly as hell, of course I would prefer a simple JSON body. – Viktor Plane Jun 04 '17 at 19:55
  • @Andreas Can't get it to work with a MultiValueMap either. Created one with and added value clipmessage, and added the body minus clipmessage= – Viktor Plane Jun 04 '17 at 20:01
  • @ViktorPlane Impossible to determine if you did it right, unless you edit the question and show what you've tried. – Andreas Jun 04 '17 at 22:12
  • what do you send in Postman and with the `RestTemplate`. Looks like you are trying to send a body that should actually be parameters. A body is a request body and isn't the same as parameters. – M. Deinum Jun 05 '17 at 06:35
  • The exact data that was in body String in my initial code, it worked perfectly fine with Postman. – Viktor Plane Jun 05 '17 at 08:12
  • FWIW you can set the content type more directly: `headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED)` – Josh M. Jun 12 '19 at 13:46

1 Answers1

1

I have the same scenario. solved after using the following code :

  restTemplate = new RestTemplate();

    List<HttpMessageConverter<?>> messageConverters = new ArrayList<>();
    MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();
    converter.setSupportedMediaTypes(Collections.singletonList(MediaType.ALL));
    FormHttpMessageConverter formMessageConverter = new FormHttpMessageConverter();
    messageConverters.add(formMessageConverter);
    messageConverters.add(converter);
    restTemplate.setMessageConverters(messageConverters);

Parameters and headerpart

...
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
MultiValueMap<String, String> parameters = new LinkedMultiValueMap<>();
        parameters.add("signature", "signature");
        //other parameters
HttpEntity<MultiValueMap<String, String>> requestEntity = new HttpEntity<>(parameters, headers);
ResponseEntity<ResponseMessage> responseEntity = restTemplate.postForEntity(url,  requestEntity, ResponseMessage.class);
ResponseMessage respMsg =responseEntity.getBody();
logMsg.append(",HTTP STATUS=").append(responseEntity.getStatusCode()).append(", RES:").append(marshal(respMsg));
Ramgau
  • 420
  • 2
  • 6
  • 16