Search code examples
javaspring-bootunit-testingsecurityresttemplate

How to create a plain http request with json content type header in RestTemplate from Spring Test?


Have a simple rest/api spring boot project and need test when have a bad schema input, like as:

curl -D- -X POST -H 'Content-Type: application/json' \
  -d 'BAD-SCHEMA-$@#%{[|!/-' \
  http://127.0.0.1:8080/auth/sign-up

I try use in test planning the RestTemplate for native JUnit 5 for Spring Test:

    @Test
    public void signUpBadInputSchemaValidation() {
        /*
        curl -D- -X POST -H 'Content-Type: application/json' \
        -d 'BAD-SCHEMA-$@#%{[|!/-' \
        http://127.0.0.1:8080/auth/sign-up
        */

        // Prepare request headers
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON);

        // Prepare request body
        HttpEntity<String> requestEntity = new HttpEntity<>("BAD-SCHEMA-$@#%{[|!/-");

        // Create http request
        ResponseEntity<Object> responseEntity = restTemplate.exchange(
            "http://127.0.0.1:" + port + "/auth/sign-up",
            HttpMethod.POST, requestEntity, Object.class);

        // Response validation
        assertThat(responseEntity.getStatusCode())
            .isEqualTo(HttpStatus.UNPROCESSABLE_ENTITY);
    }

But restTemplate change Content-Type automatically to text/plain, but need keep the application/json.

I try change port in test request and sniff with netcat:

ncat -vlp 9999
Ncat: Version 7.80 ( https://nmap.org/ncat )
Ncat: Listening on :::9999
Ncat: Listening on 0.0.0.0:9999
Ncat: Connection from 127.0.0.1.
Ncat: Connection from 127.0.0.1:54478.
POST /system/access/first HTTP/1.1
Accept: application/json, application/*+json
Content-Type: text/plain;charset=UTF-8
User-Agent: Java/17.0.8
Host: 127.0.0.1:9999
Connection: keep-alive
Content-Length: 21

BAD-SCHEMA-$@#%{[|!/-

restTemplate change header to Content-Type: text/plain;charset=UTF-8.

How to keep application/json with plain text body using restTemplate for execute the security test?


Solution

  • It is because you miss to configure the HttpHeaders with Content-Type=application/json to the HttpEntity that is sent out by the RestTemplate .

    Change to the following should fix the problem :

    // Prepare request headers
    HttpHeaders headers = new HttpHeaders();
    headers.setContentType(MediaType.APPLICATION_JSON);
    
    // Prepare request body
    HttpEntity<String> requestEntity = new HttpEntity<>("BAD-SCHEMA-$@#%{[|!/-", headers);