jodekpotasu
jodekpotasu

Reputation: 515

Spring boot Unsupported Media Type with @RequestBody

I checked in several different ways, also downloaded a new project to see what to check where is bug but I still do not know the answer.

That is my RestController

@RestController
@RequestMapping(value = "/message")
public class MessageController {

    @RequestMapping(value = "/", method = RequestMethod.POST)
    public void createMessage(@RequestBody Message message){
        System.out.println(message);
    }
}

That is my Model

@Data
@Entity
public class Message {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private long id;

    private String sender;
    private String telephone;
    private String message;
}

Gradle dependencies if necessary

dependencies {
    compile group: 'com.fasterxml.jackson.core', name: 'jackson-core', version: '2.9.0.pr3'
    compile('org.springframework.boot:spring-boot-starter-data-jpa')
    compile('org.springframework.boot:spring-boot-starter-web')
    runtime('com.h2database:h2')
    runtime('org.postgresql:postgresql')
    compileOnly('org.projectlombok:lombok')
    testCompile('org.springframework.boot:spring-boot-starter-test')
}

and in postman i'm getting that error

{ "timestamp": 1495992553884, "status": 415, "error": "Unsupported Media Type", "exception": "org.springframework.web.HttpMediaTypeNotSupportedException",
"message": "Content type 'application/x-www-form-urlencoded;charset=UTF-8' not supported",
"path": "/message/" }

It is simplest way for rest but where I make a mistake?

Upvotes: 32

Views: 130471

Answers (10)

vhs
vhs

Reputation: 10051

Make sure you pass the expected Content-Type header when creating new records:

curl -X POST 'localhost:8080/message' \
  --header 'Content-Type: application/json' \
  --data-raw $'{
  "id": 3,
  "sender": "Jennifer",
  "telephone": "555-867-5309",
  "message": "143"
}'

Upvotes: 0

Ondra Žižka
Ondra Žižka

Reputation: 46796

You can use @RequestBody for FORM_URL_ENCODED data. But it seems that the only supported receiving type for that is the MultiValueMap.

@PostMapping("/oauth/token", 
    consumes = [MediaType.APPLICATION_FORM_URLENCODED_VALUE], 
    produces = [APPLICATION_JSON_VALUE])
fun oauth(@RequestBody body: MultiValueMap<String, String>) {
    ...
}

(This is Kotlin, but you get the idea.)

For any other type, Spring Web produces this 415 Unsupported Media Type response.

On a related note, in this article at Baeldung, it explicitly shows that Spring should be able to fill the values into an instance of a custom class. I did not make that work.

Upvotes: 0

Vitaly Sazanovich
Vitaly Sazanovich

Reputation: 694

What I did:

  1. Set debug priority level in log4j.xml to 'debug'. Found HttpMediaTypeNotSupportedException.

  2. Put a debugger breakpoint in org.springframework.web.HttpMediaTypeNotSupportedException

  3. Realized that the incoming media type is text and the supported types are json and *json, although I used all - '*/*' in my annotation. Strange.

  4. Anyway, in my Angular application added headers:

    readonly headers = new HttpHeaders({'Content-Type': 'application/json; charset=utf-8'}); this.http.post(url, JSON.stringify(this.model.value), {headers: this.headers})...

Upvotes: 1

Juan Pablo G
Juan Pablo G

Reputation: 959

What i did was to remove jackson libray and now I don't longer have that error, spent 2 days trying to figure out this, I hope this works for you!

    <dependency>
        <groupId>com.fasterxml.jackson.core</groupId>
        <artifactId>jackson-databind</artifactId>
        <version>2.11.3</version>
        <scope>test</scope>
    </dependency>

Upvotes: 1

meenakshi
meenakshi

Reputation: 111

You need a @NoArgsConstructor for the deserialization to work. If the no arguments constructor is not there, the Http message converters fail to map the json(other media type) to the Java object. And a 415 is returned

Upvotes: 6

user12858831
user12858831

Reputation: 1

I got the same case with Json. Finally only this works Here code on react

export function setServices(jsonString) {
var myHeaders = new Headers();
myHeaders.append("Content-Type", "application/json;charset=UTF-8;");

var raw = jsonString;

var requestOptions = {
    method: 'POST',
    headers: myHeaders,
    body: raw,
    redirect: 'follow'
};

fetch("http://localhost:8080/setservices", requestOptions)
    .then(response => response.text())
    .then(result => console.log(result))
    .catch(error => console.log('error', error));}

Code on controller

@RequestMapping(value = "/setservices", method = RequestMethod.POST,
        consumes = MediaType.APPLICATION_JSON_VALUE,
        produces = MediaType.APPLICATION_JSON_VALUE)
public @ResponseBody  String createMessage() throws Exception {
    //do smthg

    return "Ok";    }

Upvotes: -1

Ankit Kesharwani
Ankit Kesharwani

Reputation: 129

You can write the code as
headers.put("Content-Type", Arrays.asList("application/json"));
instead of
headers.setAccept(Arrays.asList(MediaType.APPLICATION_JSON));

Upvotes: 6

adeshina.O
adeshina.O

Reputation: 912

In Postman. under Body, select raw and choose JSON from the drop down menu that appears. Then write the JSON that is the request body. You can't use form-data or x-www-form-urlencoded with @RequestBody, they are used when the binding is @ModelAttribute.

Upvotes: 76

VK321
VK321

Reputation: 5953

I had a similar issue using $.post Jquery. By adding correct contentType and dataType it worked for me.

$.ajax({
    type: "POST",
    url: "/api/design/save",
    data: JSON.stringify({
        id: floorId,
        shapes: shapes,
    }),
    contentType: "application/json; charset=utf-8",
    dataType: "json",
    success: function(data){
        console.log(data);
   },
    error: function(err) {
        console.log(err);
    }
});

Upvotes: 5

user2618324
user2618324

Reputation: 111

The problem is that when we use application/x-www-form-urlencoded, Spring doesn't understand it as a RequestBody. So, if we want to use this we must remove the @RequestBody annotation.

@RequestMapping(value = "/", method = RequestMethod.POST, consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE)
    public void createMessage(Message message){
        //TODO DO your stuff here
    }

Upvotes: 8

Related Questions