Get STRING response from restTemplate.put
Asked Answered
U

4

27

I'm having a problem using Spring restTemplate.

For now i'm sending a PUT request for a restful service and that restful service send me back important informations in response.

The question is that restTemplate.put are a void method and not a string so i can't see that response.

Following some answers i've change my method and now i'm using restTemplate.exchange, here are my method:

public String confirmAppointment(String clientMail, String appId)
{
    String myJsonString = doLogin();

    Response r = new Gson().fromJson(myJsonString, Response.class);

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

    // JSONObject json;
    // json = new JSONObject();

    // json.put("status","1");

    // map.add("data",json.toString());

    String url = getApiUrl() + "company/" + getCompanyId() + "/appointment/" + appId + "?session_token=" + r.data.session_token;
    String jsonp = "{\"data\":[{\"status\":\"1\"}]}";

    RestTemplate rest = new RestTemplate();

    HttpHeaders headers = new HttpHeaders();
    headers.add("Content-Type", "application/json");
    headers.add("Accept", "*/*");

    HttpEntity<String> requestEntity = new HttpEntity<String>(jsonp, headers);
    ResponseEntity<String> responseEntity = 
            rest.exchange(url, HttpMethod.PUT, requestEntity, String.class);

    return responseEntity.getBody().toString();
}

Using the method above, i receive a 400 Bad Request

I know my parameters, url and so, are just fine, cause i can do a restTemplate.put request like this:

try {
    restTemplate.put(getApiUrl() + "company/" + getCompanyId() + "/appointment/" + appId + "?session_token=" + r.data.session_token, map);
} catch(RestClientException j)
{
    return j.toString();
}

The problem (like i said before) is that the try/catch above does not return any response but it gives me a 200 response.

So now i ask, what can be wrong?

Uredium answered 3/6, 2013 at 14:30 Comment(13)
Use the execute methods: static.springsource.org/spring/docs/3.0.x/javadoc-api/org/…Codel
@Uredium : Conventionally HTTP PUT is used for the operations which the user is aware. For an example, to Update something we can use HTTP PUT, there it is not intended to return a response body. May be status code or status message you can send. For that you can use headers to get it done. If you are expecting a response body that means you should deviate from HTTP PUT to HTTP POST. There you will be able to read the response in proper manner.Kitts
@MCF, unfortunately the restful service i'm accessing requires a PUT to update information's about a object and return information's about the update. If i send a POST request, the restful service return error.Uredium
@SotiriosDelimanolis, can you show me a example of usage? Sorry, my english are not so good and i'm new to restTemplate and Java :(Uredium
@Uredium See an example here: https://mcmap.net/q/534316/-resttemplate-usageCodel
@SotiriosDelimanolis, i don't understand, your link shows a exchange example, not a execute.Uredium
@Uredium Please read the javadoc in my first comment. The methods are different, but the end result is much the same. Use either.Codel
Sorry @SotiriosDelimanolis, as i said before, i do not understand Spring well yet and i didnt understand how the execute method works. I've edited my question by using the exchange method. With more accurate informations about my structure. I'll be thankful if you can solve this problem. Thanks in advance bro :)Uredium
@Uredium I'm pretty sure it's because of String jsonp = map.toString();. jsonp will not be valid json because of missing quotation marks (try to println() it before you call the method). Bad json, means the content-type is invalid and therefore your request is bad, ie. 400 error.Codel
@SotiriosDelimanolis, ok, i edited the question with the modifications but still get 400 BAD REQUESTUredium
@Uredium The = should be : in the json string. Always make sure to validate your json with services like JSONLintCodel
@SotiriosDelimanolis, ok, i put the : and the validation are fine. But i still get a 400 BAD REQUEST... :(Uredium
@Uredium Then your headers are incorrect.Codel
T
37

Here's how you can check the response to a PUT. You have to use template.exchange(...) to have full control / inspection of the request/response.

    String url = "http://localhost:9000/identities/{id}";       
    Long id = 2l;
    String requestBody = "{\"status\":\"testStatus2\"}";
    HttpHeaders headers = new HttpHeaders();
    headers.setContentType(MediaType.APPLICATION_JSON); 
    HttpEntity<String> entity = new HttpEntity<String>(requestBody, headers); 
    ResponseEntity<String> response = template.exchange(url, HttpMethod.PUT, entity, String.class, id);
    // check the response, e.g. Location header,  Status, and body
    response.getHeaders().getLocation();
    response.getStatusCode();
    String responseBody = response.getBody();
Tracee answered 23/7, 2014 at 22:54 Comment(1)
Your example on using HttpHeaders solved this issue for me. I was using StringEntity instead of HttpHeaders and was getting 400 errors that way.Reminiscent
K
10

You can use the Header to send something in brief to your clients. Or else you can use the following approach as well.

restTemplate.exchange(url, HttpMethod.PUT, requestEntity, responseType, ...)

You will be able to get a Response Entity returned through that.

Kitts answered 3/6, 2013 at 14:35 Comment(4)
I still don't understand what you mean by can use the Header to send something in brief to your clients.Codel
@SotiriosDelimanolis I have seen an apporach where the Headers to send some very brief information via HTTP.PUT. The clients need to read the headers and retrieve it.Kitts
Let's say that you want to communicate the clients that the operation which was done through HTTP.PUT was unsuccessful. In that case from server side we can set an additional header parameter to communicate that incident. Therefore, the people who requested for HTTP.PUT will be aware by reading the header at least.Kitts
Ok, so you want to use HTTP headers. That doesn't answer his question of getting the HTTP PUT response. The other part of your answer does.Codel
W
0

Had the same issue. And almost went nuts over it. Checked it in wireshark: The problem seems to be the escape characters from the request body:

String jsonp = "{\"data\":[{\"status\":\"1\"}]}";

The escape character (backslash) is not resolved. The String is sent with the backslashes, which is obviously not a valid json and therefore no valid request(-body).

I bypassed this by feeding everything in with an Object, that is mapping all the properties.

Whipstock answered 17/5, 2019 at 7:10 Comment(1)
Could you please provide an example with your solution?Unseasoned
H
0

You can use the httpEntityCallback() and responseEntityExtractor() from RestTemplate to construct your own put method:

ResponseEntity<MyJsonResponse> response = restTemplate.execute(url,
    HttpMethod.PUT,
    restTemplate.httpEntityCallback(myJsonAsJavaObject),
    restTemplate.responseEntityExtractor( MyJsonResponse.class)
);
Heartbroken answered 13/3, 2023 at 17:57 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.