25

An Url, Credentials works in RestClient UI as well as with Curl where as i'm getting "500" error when access the same via Spring RestTemplate.

I am using the following code:

MultiValueMap<String, Object> map = new LinkedMultiValueMap<String, Object>();
map.add("name", user);
map.add("password", password);
restTemplate.postForObject(url, request, Employee.class, map);

Please let me know your suggestions or comments to fix the problem.

Alex Barnes
  • 7,174
  • 1
  • 30
  • 50
Kathir
  • 2,733
  • 12
  • 39
  • 67
  • Does your Employee class really start with a lower case e? – Alex Barnes Jun 24 '12 at 16:19
  • sorry it is a typo error..It is Employee.class – Kathir Jun 24 '12 at 16:27
  • 500 is a server error; is there any detail in the body of the response or anything useful in the server's log? – Donal Fellows Jun 24 '12 at 19:53
  • No. Below is the stack trace for reference: org.springframework.web.client.HttpServerErrorException: 500 Internal Server Error at org.springframework.web.client.DefaultResponseErrorHandler.handleError(DefaultResponseErrorHandler.java:77) at – Kathir Jun 25 '12 at 05:55
  • For Post: restTemplate.postForObject(url, parametersMap, Employee.class); url is : String - rest api URL parametersMap - MultiValueMap Employee - object which needs to be converted from the JSON response – Kathir Nov 15 '12 at 06:46

9 Answers9

18

I would suggest to create your HttpComponentsClientHttpRequestFactory and pass it to your RestTemplate as described below:

ClientHttpRequestFactory requestFactory = new     
      HttpComponentsClientHttpRequestFactory(HttpClients.createDefault());

RestTemplate restTemplate = new RestTemplate(requestFactory);

By this way, you would avoid server-side issues (like facing error code 500) when testing your application.

I had the same issue that worked in my local environment and not on the server.

It is a good practice to pass HttpClients.createDefault() to your HttpComponentsClientHttpRequestFactory while constructing it since by default, this factory uses system properties to create HttpClient for your factory and that may cause lots of pain in real server environment. You may also pass your custom HttpClient.

Youness
  • 1,920
  • 22
  • 28
  • 1
    hi, what is the HttpClients object please? I cant find any maven dependency that will let me import this. I am trying to use RestTemplateXhrTransport to connect to a websocket and i am getting the error above. thanks – a.hrdie Nov 24 '15 at 13:59
  • Sorry! It is a bit late to answer but as far as I remember, It belonged to one of the following projects (based on priority). You can try each and see if you get compiler error; org.springframework spring-web .... Or org.apache.httpcomponents httpclient .... Or commons-httpclient commons-httpclient ... – Youness Feb 02 '16 at 17:12
  • 1
    @DuncanJones It is explained in Spring Framework Issue: https://jira.spring.io/browse/SPR-9367 – Hemanth Dec 09 '18 at 19:16
10
RestTemplate header Accept problem 
--> accept - text/plain, application/json, */*

HttpClient 4.x header Accept
--> accept - application/json

so i fixed

HttpHeaders headers = new HttpHeaders();
headers.add("Accept", MediaType.APPLICATION_JSON_VALUE);

http://www.manning-sandbox.com/message.jspa?messageID=119733

codercat
  • 22,873
  • 9
  • 61
  • 85
webmadeup
  • 171
  • 2
  • 4
5

I have also faced a situation where server response was "500 Internal server error"

Though I have received success response from Postman for the same parameter value. So the problem was not in server side.

The problem was typo in parameter name, mismatch spelling between application parameter and server parameter

Server parameter        -> requestLabel
Application parameter   -> requestLable

Hope someone new like me get help from this.

iOS-Developer84
  • 654
  • 8
  • 19
2

This may happen if your data contract class is missing default constructor - so Jackson fails to construct it. You can try solve this issue by adding a private default constructor to your class (despite it is private, Jackson will be able to construct your class instance).

Illidan
  • 4,047
  • 3
  • 39
  • 49
1

Below works fine

For Post:

restTemplate.postForObject(url, parametersMap, Employee.class);

url is : String - rest api URL parametersMap - MultiValueMap Employee - object which needs to be converted from the JSON response

Kathir
  • 2,733
  • 12
  • 39
  • 67
1

You are passing name and password as uri variable:

public <T> T postForObject(java.lang.String url,
                                     @Nullable
                                     java.lang.Object request,
                                     java.lang.Class<T> responseType,
                                     java.util.Map<java.lang.String,?> uriVariables)

                          throws RestClientException

docs.spring.io

If you had some url like: http://yourhost:8080/dosomethingwithemployee/name/password and you extracted name&password from url itself, then it probably would work.

String url = "http://yourhost:8080/dosomethingwithemployee/{name}/{password}"
restTemplate.postForObject(url, request, Employee.class, map);

However, I think you have been trying to send name and password in request body:

public SomeType getResponse(String login, String password) {
        MultiValueMap<String, String> headers = new LinkedMultiValueMap<>();
        headers.add("Content-Type", "application/json");
        Employee employee = new Employee();
        employee.setName(login);
        employee.setPassword(password);
        SomeType responseBody = post("http://locahost:8080/dosomethingwithemployee", employee, headers, SomeType.class);
        return responseBody;
    }

    public <T> T post(String url, Object requestObject, MultiValueMap<String, String> headers, Class<T> responseType) {
        RestTemplate restTemplate = new RestTemplate();
        restTemplate.getMessageConverters().add(new MappingJackson2HttpMessageConverter());
        restTemplate.getMessageConverters().add(new StringHttpMessageConverter());

        HttpEntity request = new HttpEntity(requestObject, headers);
        T responseObject = restTemplate.postForObject(url, request, responseType);

        return responseObject;
    }
valijon
  • 1,304
  • 2
  • 20
  • 35
0

Though its too late to answer, below solution will help someone if above solutions did not work. For me, the error was with Request object and its header. Your request object should generate JSON as required by api. It should not have any extra field or additional getter method. In my case, I had additional getter method which was adding unnecessary field to request

postForEntity = restTemplate.postForEntity(uri,entity,String.class);
0

If you are using an external library/sdk that uses rest service (like Twilio), it can override the JSON structure.

It may be a solution to downgrade the version of the relevant package.

AhuraMazda
  • 460
  • 4
  • 22
-2

I had the same issue. Restarting my local server reset the connection and solved the problem for me.

I Stand With Israel
  • 1,971
  • 16
  • 30
Sachin
  • 7