2
votes

I am attempting to send a String object to a rest service using HTTP Post method. and the String should be sent in the request body.

The controller

@RestController
@RequestMapping(value = "post", method = RequestMethod.POST)
public class HttpMethodPostController {

    /*HttpClientErrorException: 415 null*/
    @RequestMapping(value = "/string_as_text", consumes = MediaType.TEXT_PLAIN_VALUE)
    public ResponseEntity<Void> getStringAsText(@RequestBody String text) {
        System.out.println("[Server] text = " + text);
        return new ResponseEntity<Void>(HttpStatus.OK);
    }

    /*HttpClientErrorException: 400 null*/
    @RequestMapping(value = "/string_as_json", consumes = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public ResponseEntity<Void> getStringAsJSON(@RequestBody String text) {
        System.out.println("[Server] text = " + text);
        return new ResponseEntity<Void>(HttpStatus.OK);
    }

    @RequestMapping(value = "/type1_", consumes = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public ResponseEntity<Void> postType1_(@RequestBody Type1_ type1_) {
        System.out.println("[Server] type1_ = " + type1_);
        return new ResponseEntity<Void>(HttpStatus.OK);
    }

}

The consumer

public class HttpMethodPostConsumer {
    public static final String POST_ADDRESS = "http://localhost:55055/post";

    /*HttpClientErrorException: 415 null*/
    public static void postStringAsText(String text) {
        final RestTemplate restTemplate = new RestTemplate();
        final HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.TEXT_PLAIN);
        final HttpEntity<String> entity = new HttpEntity<>(text, headers);
        final URI uri = restTemplate.postForLocation(POST_ADDRESS + "/string_as_text", entity, String.class);
        System.out.println("uri = " + uri);
    }

    /*HttpClientErrorException: 400 null*/
    public static void postStringAsJSON(String text) {
        final RestTemplate restTemplate = new RestTemplate();
        final HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON_UTF8);
        final HttpEntity<String> entity = new HttpEntity<>(text, headers);
        final URI uri = restTemplate.postForLocation(POST_ADDRESS + "/string_as_json", entity, String.class);
        System.out.println("uri = " + uri);
    }

    public static void postType1_(Type1_ type1_) {
        final RestTemplate restTemplate = new RestTemplate();
        final HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON_UTF8);
        final HttpEntity<Type1_> httpEntity = new HttpEntity<Type1_>(type1_, headers);
        final URI result_URI = restTemplate.postForLocation(POST_ADDRESS + "/type1_", httpEntity, Type1_.class);
        System.out.println("result_URI = " + result_URI);
    }
}

The consumer test runner

public class HttpMethodPostConsumerTest {

    /*HttpClientErrorException: 415 null*/
    @Test
    public void test_postStringAsText() {
        final String text = Randomizers.getString();
        System.out.println("text = " + text);
        postStringAsText(text);
    }

    /*HttpClientErrorException: 400 null*/
    @Test
    public void test_postStringAsJSON() {
        final String text = Randomizers.getString();
        System.out.println("text = " + text);
        postStringAsJSON(text);
    }

    @Test
    public void test_postType1_() {
        final Type1_ type1_ = ModelFactory.getType1_();
        System.out.println("[Consumer] type1_ = " + type1_);
        postType1_(type1_);
    }

}

The Testing Procedure

  1. The server is run first (http://localhost:55055/)
  2. Wait until the server is up and running.
  3. Run test_postType1_() will work as expected.
  4. Run test_postStringAsText() Will result in client/consumer side error

org.springframework.web.client.HttpClientErrorException: 415 null

at org.springframework.web.client.DefaultResponseErrorHandler.handleError(DefaultResponseErrorHandler.java:94) at org.springframework.web.client.DefaultResponseErrorHandler.handleError(DefaultResponseErrorHandler.java:79) at org.springframework.web.client.ResponseErrorHandler.handleError(ResponseErrorHandler.java:63) at org.springframework.web.client.RestTemplate.handleResponse(RestTemplate.java:775) at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:728) at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:684) at org.springframework.web.client.RestTemplate.postForLocation(RestTemplate.java:405) at personal.learn.java.spring_rest.rest_general.non_automated.consumers.HttpMethodPostConsumer.postStringAsText(HttpMethodPostConsumer.java:21) at personal.learn.java.spring_rest.rest_general.non_automated.consumers.HttpMethodPostConsumerTest.test_postStringAsText(HttpMethodPostConsumerTest.java:17)

  1. Run test_postStringAsJSON() will result in errors
    • Client/consumer side error

org.springframework.web.client.HttpClientErrorException: 400 null

at org.springframework.web.client.DefaultResponseErrorHandler.handleError(DefaultResponseErrorHandler.java:94) at org.springframework.web.client.DefaultResponseErrorHandler.handleError(DefaultResponseErrorHandler.java:79) at org.springframework.web.client.ResponseErrorHandler.handleError(ResponseErrorHandler.java:63) at org.springframework.web.client.RestTemplate.handleResponse(RestTemplate.java:775) at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:728) at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:684) at org.springframework.web.client.RestTemplate.postForLocation(RestTemplate.java:405) at personal.learn.java.spring_rest.rest_general.non_automated.consumers.HttpMethodPostConsumer.postStringAsJSON(HttpMethodPostConsumer.java:31) at personal.learn.java.spring_rest.rest_general.non_automated.consumers.HttpMethodPostConsumerTest.test_postStringAsJSON(HttpMethodPostConsumerTest.java:25)

Server side error (In console)

02-May-2018 17:25:45.469 WARNING [http-nio-55055-exec-2] org.springframework.web.servlet.mvc.support.DefaultHandlerExceptionResolver.handleHttpMessageNotReadable Failed to read HTTP message: org.springframework.http.converter.HttpMessageNotReadableException: JSON parse error: Unrecognized token 'IAtQDIxTCh': was expecting 'null', 'true', 'false' or NaN; nested exception is com.fasterxml.jackson.core.JsonParseException: Unrecognized token 'IAtQDIxTCh': was expecting 'null', 'true', 'false' or NaN at [Source: (PushbackInputStream); line: 1, column: 21]

Server side error (In Tomcat Catalina Log)

02-May-2018 17:25:45.469 WARNING [http-nio-55055-exec-2] org.springframework.web.servlet.mvc.support.DefaultHandlerExceptionResolver.handleHttpMessageNotReadable Failed to read HTTP message: org.springframework.http.converter.HttpMessageNotReadableException: JSON parse error: Unrecognized token 'IAtQDIxTCh': was expecting 'null', 'true', 'false' or NaN; nested exception is com.fasterxml.jackson.core.JsonParseException: Unrecognized token 'IAtQDIxTCh': was expecting 'null', 'true', 'false' or NaN at [Source: (PushbackInputStream); line: 1, column: 21]

1
A trivial question. Is the controller up and running in a server before invoking the post request from the PostConsumer?Amal
How is the server configured to use port 55055? Is debug enabled? What do the logs say?Andrew S
Yes. I run the server first then run the consumer as a JUnit test.sero
I am going to update the question to include more relevant data.sero
did you tried using external client like postman as well? that'll filter out whether you have client side or server side issue.Shanu Gupta

1 Answers

1
votes

If you want to POST to your server using @RequestBody, it's necessary send a object to your controller.

Create a DTO class with your String param:

public class ExampleDTO {

 private String stringExample;

  public String getStringExample() {
    return stringExample;
  }

  public void setStringExample(String stringExample) {
    this.stringExample= stringExample;
  }

}

Your controller:

@RequestMapping(method = RequestMethod.POST, value = "/string_as_text")
public ResponseEntity<Void> getStringAsText(@RequestBody ExampleDTO exampleDTO) {
    System.out.println("[Server] text = " + exampleDTO.getStringExample());
    return new ResponseEntity<Void>(HttpStatus.OK);
}

The consumer

ExampleDTO param = new ExampleDTO();
param.setStringExample("text")