web-dev-qa-db-fra.com

415 MediaType non pris en charge pour POST demande en printemps application

J'ai une application Spring très simple (PAS de démarrage à ressort). J'ai implémenté des méthodes de contrôleur GET et POST. la méthode GET fonctionne bien. Mais la POST jette 415 Unsupported MediaType. Les étapes pour reproduire sont disponibles ci-dessous

ServiceController. Java

package com.example.myApp.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;


    @Controller
    @RequestMapping("/service/example")
    public class ServiceController {

        @RequestMapping(value="sample", method = RequestMethod.GET)
        @ResponseBody
    public String getResp() {
        return "DONE";
    }

    @RequestMapping(value="sample2", method = RequestMethod.POST, consumes = "application/json")
    @ResponseBody
    public String getResponse2(@RequestBody Person person) {
        return "id is " + person.getId();
    }

}

class Person {

    private int id;
    private String name;

    public Person(){

    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

AppConfig.Java

package com.example.myApp.app.config;

import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;

@Configuration
@EnableWebMvc
@ComponentScan("com.example.myApp")
public class AppConfig extends WebMvcConfigurerAdapter {

    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/test/**").addResourceLocations("/test/").setCachePeriod(0);
        registry.addResourceHandler("/css/**").addResourceLocations("/css/").setCachePeriod(0);
        registry.addResourceHandler("/img/**").addResourceLocations("/img/").setCachePeriod(0);
        registry.addResourceHandler("/js/**").addResourceLocations("/js/").setCachePeriod(0);
    }
}

AppInitializer.Java

package com.example.myApp.app.config;

import org.springframework.web.WebApplicationInitializer;
import org.springframework.web.context.ContextLoaderListener;
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
import org.springframework.web.servlet.DispatcherServlet;

import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRegistration;

public class AppInitializer implements WebApplicationInitializer {

    @Override
    public void onStartup(ServletContext servletContext) throws ServletException {


        // Create the 'root' Spring application context
        AnnotationConfigWebApplicationContext rootContext =
                new AnnotationConfigWebApplicationContext();

        rootContext.register(AppConfig.class);
        servletContext.addListener(new ContextLoaderListener(rootContext));

        // Register and map the dispatcher servlet
        ServletRegistration.Dynamic dispatcher =
                servletContext.addServlet("dispatcher", new DispatcherServlet(rootContext));

        dispatcher.setLoadOnStartup(1);
        dispatcher.addMapping("/");

    }


}

Le code est disponible ici: 

git clone https://bitbucket.org/SpringDevSeattle/springrestcontroller.git
./gradlew clean build tomatrunwar

Cela accélère Tomcat intégré. 

Maintenant, vous pouvez curl le suivant

curl -X GET -H "Content-Type: application/json" "http://localhost:8095/myApp/service/example/sample"

fonctionne bien

Mais 

curl -X POST -H "Content-Type: application/json" '{
    "id":1,
    "name":"sai"
}' "http://localhost:8095/myApp/service/example/sample2"

Lance 415 MediaType non pris en charge 

<body>
        <h1>HTTP Status 415 - </h1>
        <HR size="1" noshade="noshade">
        <p>
            <b>type</b> Status report
        </p>
        <p>
            <b>message</b>
            <u></u>
        </p>
        <p>
            <b>description</b>
            <u>The server refused this request because the request entity is in a format not supported by the requested resource for the requested method.</u>
        </p>
        <HR size="1" noshade="noshade">
        <h3>Apache Tomcat/7.0.54</h3>
    </body>
8
brain storm

J'ai trouvé la solution et je veux poster ici pour en faire profiter les autres. 

Tout d'abord, je dois inclure jackson dans mon classpath, que j'ai ajouté dans build.gradle comme suit:

 compile 'com.fasterxml.jackson.core:jackson-databind:2.7.5'
    compile 'com.fasterxml.jackson.core:jackson-annotations:2.7.5'
    compile 'com.fasterxml.jackson.core:jackson-core:2.7.5'

Ensuite, je dois changer ma AppConfig qui étend WebMvcConfigurerAdapter comme suit:

@Configuration
@EnableWebMvc
@ComponentScan("com.example.myApp")
public class AppConfig extends WebMvcConfigurerAdapter {

    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/test/**").addResourceLocations("/test/").setCachePeriod(0);
        registry.addResourceHandler("/css/**").addResourceLocations("/css/").setCachePeriod(0);
        registry.addResourceHandler("/img/**").addResourceLocations("/img/").setCachePeriod(0);
        registry.addResourceHandler("/js/**").addResourceLocations("/js/").setCachePeriod(0);
    }


    @Override
    public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {

        converters.add(new MappingJackson2HttpMessageConverter());
        super.configureMessageConverters(converters);
    }
}

C'est tout et tout a bien fonctionné

4
brain storm

Accepter en-tête pourrait être le problème . Pour autant que je m'en souvienne, lorsque vous envoyez une demande via curl, il ajoute un en-tête par défaut accept : */*
Mais dans le cas de JSON, vous devez mentionner l'en-tête accept
comme accept : application/json 
de même, vous avez mentionné le type de contenu.

Et un peu plus, je ne sais pas ce que c'est, mais vous ne pensez pas que vous devez placer des "requêtes de mappages" comme ça 

@RequestMapping(value="/sample" ...
@RequestMapping(value="/sample2" ...

Ce n'est peut-être pas le cas, mais accepter l'en-tête est la chose, je pense que c'est le problème principal .
Solution 2
Depuis que vous avez ce code 

public String getResponse2(@RequestBody Person person)

J'ai déjà fait face à ce problème avant et la solution deux peut aider ici

FormHttpMessageConverter qui est utilisé pour les paramètres annotés @ RequestBody lorsque le type de contenu est application/x-www-form-urlencoded ne peut pas lier les classes cibles de la même manière que @ModelAttribute. Par conséquent, vous avez besoin de @ModelAttribute au lieu de @RequestBody

Utilisez soit l'annotation @ModelAttribute au lieu de @RequestBody comme ceci 

public String getResponse2(@ModelAttribute Person person)

J'ai fourni la même réponse à quelqu'un et cela a aidé… .. voici ce que répondre à moi 

3
Tahir Hussain Mir

pouvez-vous essayer d'utiliser l'option -d dans curl

curl -H "Content-Type: application/json" -X POST -d
 '{"id":"1,"name":"sai"}'
 http://localhost:8095/myApp/service/example/sample2

En outre, si vous utilisez Windows, vous devez éviter les guillemets doubles.

-d "{ \"id\": 1, \"name\":\"sai\" }" 
0
Periklis Douvitsas