NeuroAgent

How to POST JSON with cURL to Spring REST API

Learn how to properly POST JSON data to Spring REST applications using cURL. Fix 415 Unsupported Media Type errors with correct Content-Type headers and JSON formatting. Complete guide with examples.

Question

How to POST JSON data with cURL to test a Spring REST application?

I’m trying to test my Spring REST application using cURL on Ubuntu. I need to send a POST request with JSON data, but I’m receiving a 415 Unsupported Media Type error.

Here’s the JSON data I want to send:

json
{"value":"30","type":"Tip 3","targetModule":"Target 3","configurationGroup":null,"name":"Configuration Deneme 3","description":null,"identity":"Configuration Deneme 3","version":0,"systemId":3,"active":true}

Here’s the cURL command I’m using:

bash
curl -i \
    -H "Accept: application/json" \
    -H "X-HTTP-Method-Override: PUT" \
    -X POST -d "value":"30","type":"Tip 3","targetModule":"Target 3","configurationGroup":null,"name":"Configuration Deneme 3","description":null,"identity":"Configuration Deneme 3","version":0,"systemId":3,"active":true \
    http://localhost:8080/xx/xxx/xxxx

The error response is:

HTTP/1.1 415 Unsupported Media Type
Server: Apache-Coyote/1.1
Content-Type: text/html;charset=utf-8
Content-Length: 1051
Date: Wed, 24 Aug 2011 08:50:17 GMT

Error description: The server refused this request because the request entity is in a format not supported by the requested resource for the requested method ().

Tomcat log: “POST /ui/webapp/conf/clear HTTP/1.1” 415 1051

My Java code for handling PUT requests (GET and DELETE work fine):

java
@RequestMapping(method = RequestMethod.PUT)
public Configuration updateConfiguration(HttpServletResponse response, @RequestBody Configuration configuration) {
    configuration.setName("PUT worked");
    return configuration;
}

What is the correct format for the cURL command to POST JSON data to my Spring REST application?

NeuroAgent

Your cURL command has two main issues causing the 415 Unsupported Media Type error: missing Content-Type header and invalid JSON format. Here’s the correct solution:

To send JSON data to your Spring REST application using cURL, you need to properly format the JSON and include the Content-Type header:

bash
curl -i \
    -H "Accept: application/json" \
    -H "Content-Type: application/json" \
    -H "X-HTTP-Method-Override: PUT" \
    -X POST -d '{"value":"30","type":"Tip 3","targetModule":"Target 3","configurationGroup":null,"name":"Configuration Deneme 3","description":null,"identity":"Configuration Deneme 3","version":0,"systemId":3,"active":true}' \
    http://localhost:8080/xx/xxx/xxxx

Contents

Understanding the 415 Error

The 415 Unsupported Media Type status code indicates that “the origin server is refusing to service the request because the payload is in a format not supported by this method on the target resource.”

In Spring applications, this typically occurs when:

  • The Content-Type header is missing or incorrect
  • The JSON payload is malformed
  • The controller method doesn’t accept the specified media type
  • Spring’s message converter cannot process the request body

Common Causes of JSON POST Issues

1. Missing Content-Type Header

The most common cause of 415 errors when sending JSON is failing to specify the Content-Type: application/json header. According to the research findings, this is essential for Spring to understand the request format.

2. Invalid JSON Format

Your original cURL command had malformed JSON:

bash
# WRONG - missing outer braces and incorrect quoting
-d "value":"30","type":"Tip 3",...

Correct JSON format requires:

  • Outer braces {} to create a JSON object
  • Properly quoted keys and string values
  • Proper null value representation

3. Method Override Confusion

Using X-HTTP-Method-Override: PUT with a POST request can cause confusion. Consider using the actual PUT method instead:

bash
curl -i \
    -H "Accept: application/json" \
    -H "Content-Type: application/json" \
    -X PUT -d '{"value":"30","type":"Tip 3",...}' \
    http://localhost:8080/xx/xxx/xxxx

Correct cURL Syntax for JSON POST

Basic JSON POST Command

bash
curl -X POST \
    -H "Content-Type: application/json" \
    -H "Accept: application/json" \
    -d '{"key":"value"}' \
    http://localhost:8080/api/endpoint

Advanced Examples from Research

Several authoritative sources provide examples of proper cURL syntax for JSON:

  1. From Stack Overflow: curl -H "Accept: application/json" -H "Content-type: application/json" -X POST -d '{"id":100}' http://localhost/api/postJsonReader.do

  2. From GitHub: curl -X POST -H "Content-Type: application/json" -d @FILENAME DESTINATION

  3. From TecAdmin: curl -d "@request.json" -H "Content-Type: application/json" -H "Authentication: XXX" -X POST https://<notification API URL>/notifications/quick-send

Using JSON Files

For better readability, you can store your JSON in a file and reference it:

bash
# Create a file (config.json) with your JSON data
curl -X POST \
    -H "Content-Type: application/json" \
    -d @config.json \
    http://localhost:8080/xx/xxx/xxxx

Spring REST Controller Configuration

Your Java code looks correct, but ensure your controller is properly configured:

java
@RequestMapping(method = RequestMethod.PUT, consumes = "application/json")
public Configuration updateConfiguration(
    HttpServletResponse response, 
    @RequestBody Configuration configuration) {
    
    configuration.setName("PUT worked");
    return configuration;
}

Key points for Spring configuration:

  • Ensure you have Jackson dependency in your project (usually included with Spring Boot)
  • Use @RequestBody annotation for JSON binding
  • Consider adding consumes = "application/json" to restrict media types
  • Make sure your Configuration class has proper getters and setters

Troubleshooting Checklist

If you still encounter issues, check these common problems:

  1. Verify JSON Validity

    bash
    # Test your JSON is valid
    echo '{"value":"30","type":"Tip 3"}' | python -m json.tool
    
  2. Check Headers

    bash
    # Use verbose mode to see all headers
    curl -v -X POST \
        -H "Content-Type: application/json" \
        -H "Accept: application/json" \
        -d '{"value":"30"}' \
        http://localhost:8080/xx/xxx/xxxx
    
  3. Test with Simple JSON
    Start with minimal JSON to isolate the problem:

    bash
    curl -X POST \
        -H "Content-Type: application/json" \
        -d '{"name":"test"}' \
        http://localhost:8080/xx/xxx/xxxx
    
  4. Verify Spring Configuration

    • Ensure @EnableWebMvc is present if using Spring MVC
    • Check that Jackson is in your dependencies
    • Look for any @Configuration classes that might override default settings

Alternative Testing Methods

Using Postman

Postman provides a GUI interface for testing REST APIs:

  1. Set request method to POST
  2. Go to Headers tab and add:
    • Content-Type: application/json
    • Accept: application/json
  3. Go to Body tab and select raw JSON
  4. Paste your JSON and send

Using HTTPie

HTTPie is a more user-friendly alternative to cURL:

bash
http POST localhost:8080/xx/xxx/xxxx \
    Accept:application/json \
    Content-Type:application/json \
    'value=30' \
    'type=Tip 3' \
    'targetModule=Target 3' \
    'configurationGroup=null' \
    'name=Configuration Deneme 3'

Using wget

bash
wget -qO- --post-data='{"value":"30"}' \
    --header='Content-Type: application/json' \
    --header='Accept: application/json' \
    http://localhost:8080/xx/xxx/xxxx

Best Practices

  1. Always Include Content-Type Header: Never send JSON without specifying Content-Type: application/json

  2. Use Proper JSON Syntax: Always validate your JSON using online validators or tools

  3. Method Consistency: Match your HTTP method to your controller mapping. If your controller handles PUT, use curl -X PUT instead of POST with method override

  4. Error Handling: Add error handling in your Spring controller:

    java
    @RequestMapping(method = RequestMethod.PUT, consumes = "application/json")
    public ResponseEntity<Configuration> updateConfiguration(
        @RequestBody Configuration configuration) {
        
        try {
            // Your business logic
            configuration.setName("PUT worked");
            return ResponseEntity.ok(configuration);
        } catch (Exception e) {
            return ResponseEntity.status(HttpStatus.BAD_REQUEST).build();
        }
    }
    
  5. Logging: Add debug logging to see what Spring receives:

    java
    @RequestMapping(method = RequestMethod.PUT, consumes = "application/json")
    public Configuration updateConfiguration(@RequestBody Configuration configuration) {
        logger.debug("Received configuration: {}", configuration);
        // rest of your code
    }
    

Conclusion

To successfully POST JSON data to your Spring REST application using cURL:

  1. Always include the Content-Type header: -H "Content-Type: application/json"
  2. Validate your JSON format: Use proper braces {} and quoting
  3. Consider using the correct HTTP method: Use PUT directly instead of POST with method override
  4. Test incrementally: Start with simple JSON and gradually add complexity
  5. Verify Spring configuration: Ensure proper dependencies and annotations

The corrected command for your specific case is:

bash
curl -i \
    -H "Accept: application/json" \
    -H "Content-Type: application/json" \
    -X PUT -d '{"value":"30","type":"Tip 3","targetModule":"Target 3","configurationGroup":null,"name":"Configuration Deneme 3","description":null,"identity":"Configuration Deneme 3","version":0,"systemId":3,"active":true}' \
    http://localhost:8080/xx/xxx/xxxx

If you continue to experience issues, check your Spring application logs, verify the JSON structure matches your Configuration class, and ensure all required dependencies are properly configured.

Sources

  1. 415 Unsupported MediaType in Spring Application - Baeldung
  2. cURL POST JSON examples - Stack Overflow
  3. How to post JSON using Curl - ReqBin
  4. POST JSON with curl examples - GitHub
  5. Spring MVC 415 Unsupported media type - Stack Overflow