it-swarm.com.de

POST JSON schlägt mit 415 nicht unterstützter Medientyp, Spring 3 MVC, fehl

Ich versuche, eine POST - Anforderung an ein Servlet zu senden. Die Anfrage wird auf folgende Weise über jQuery gesendet:

var productCategory = new Object();
productCategory.idProductCategory = 1;
productCategory.description = "Descrizione2";
newCategory(productCategory);

wo ist newCategory

function newCategory(productCategory)
{
  $.postJSON("ajax/newproductcategory", productCategory, function(
      idProductCategory)
  {
    console.debug("Inserted: " + idProductCategory);
  });
}

und postJSON ist

$.postJSON = function(url, data, callback) {
    return jQuery.ajax({
    'type': 'POST',
    'url': url,
    'contentType': 'application/json',
    'data': JSON.stringify(data),
    'dataType': 'json',
    'success': callback
    });
};

Mit Firebug sehe ich, dass JSON korrekt gesendet wird:

{"idProductCategory":1,"description":"Descrizione2"}

Ich bekomme jedoch 415 nicht unterstützten Medientyp. Der Frühling-MVC-Controller verfügt über eine Signatur

    @RequestMapping(value = "/ajax/newproductcategory", method = RequestMethod.POST)
public @ResponseBody
Integer newProductCategory(HttpServletRequest request,
        @RequestBody ProductCategory productCategory)

Vor einigen Tagen hat es funktioniert, jetzt nicht mehr. Ich werde bei Bedarf mehr Code anzeigen. Danke

146
gc5

Ich habe herausgefunden, wie es funktioniert. Sagen Sie mir, falls ich falsch liege ... Ich habe nur eine Möglichkeit zum Serialisieren/Deserialisieren verwendet: Ich habe alle Anmerkungen zu diesem Code (@JSONSerialize und @JSONDeserialize) entfernt und Serialisierer und Deserialisierer in der Klasse CustomObjectMapper registriert Artikel, der dieses Verhalten erklärt, aber ich habe das so gelöst. Ich hoffe es ist nützlich.

3
gc5

Ich habe das schon mal mit Spring @ResponseBody passiert und es war, weil mit der Anfrage kein Accept-Header gesendet wurde. Accept-Header kann mit jQuery sehr schwer zu setzen sein, aber das hat für mich funktioniert source

$.postJSON = function(url, data, callback) {
    return jQuery.ajax({
    headers: { 
        'Accept': 'application/json',
        'Content-Type': 'application/json' 
    },
    'type': 'POST',
    'url': url,
    'data': JSON.stringify(data),
    'dataType': 'json',
    'success': callback
    });
};

Der Content-Type-Header wird von @RequestBody verwendet, um zu bestimmen, in welchem ​​Format die Daten vom Client in der Anforderung gesendet werden. Der Accept-Header wird von @ResponseBody verwendet, um zu bestimmen, in welchem ​​Format die Daten in der Antwort an den Client gesendet werden. Deshalb brauchen Sie beide Header.

217
theon

Ich hatte ein ähnliches Problem, stellte jedoch fest, dass ich es versäumt hatte, einen Standardkonstruktor für die DTO bereitzustellen, der mit @RequestBody kommentiert wurde.

18
John Shepherd

Ich glaube, ich bin genau in dieselbe Ausgabe geraten. Nach unzähligen Stunden des Kampfes mit dem JSON, dem JavaScript und dem Server fand ich den Schuldigen: In meinem Fall hatte ich ein Date-Objekt in der DTO, dieses Date-Objekt wurde in einen String konvertiert, sodass wir es in der Ansicht mit dem anzeigen konnten Format: HH: mm.

Wenn JSON-Informationen zurückgesendet wurden, musste dieses Date-String-Objekt wieder in ein vollständiges Date-Objekt konvertiert werden. Daher benötigen wir auch eine Methode, um es in der DTO festzulegen. Das große ABER ist, dass Sie nicht zwei Methoden mit demselben Namen (Overload) im DTO haben können, auch wenn sie einen anderen Parametertyp (String vs. Date) haben, da dies auch den Fehler 415 Unsupported Media type (Nicht unterstützter Medientyp) ergibt.

Dies war meine Controller-Methode

  @RequestMapping(value = "/alarmdownload/update", produces = "application/json", method = RequestMethod.POST)
  public @ResponseBody
  StatusResponse update(@RequestBody AlarmDownloadDTO[] rowList) {
    System.out.println("hola");
    return new StatusResponse();
  }

Dies war mein DTO-Beispiel (id get/set und preAlarm get Methods sind nicht enthalten für Code Shortness):

@JsonIgnoreProperties(ignoreUnknown = true)
public class AlarmDownloadDTO implements Serializable {

  private static final SimpleDateFormat formatHHmm = new SimpleDateFormat("HH:mm");

  private String id;
  private Date preAlarm;

  public void setPreAlarm(Date date) { 
    this.preAlarm == date;
  }
  public void setPreAlarm(String date) {    
    try {
      this.preAlarm = formatHHmm.parse(date);
    } catch (ParseException e) {
      this.preAlarm = null;
    } catch (NullPointerException e){
      this.preAlarm = null;
    }
  }
}

Damit alles funktioniert, müssen Sie die Methode mit dem Parameter Date type entfernen. Dieser Fehler ist sehr frustrierend. Hoffe, das kann jemand stundenlanges Debugging sparen.

11
will824

hinzufügen des Inhaltstyps in die Anforderung als application/json behebt das Problem

11
uiroshan

Ich war mit einem ähnlichen Problem konfrontiert und so habe ich es behoben.

Das Problem ist auf den Konvertierungsprozess von JSON nach Java zurückzuführen. Man muss über die richtigen Laufzeit-Jackson-Bibliotheken verfügen, damit die Konvertierung korrekt ausgeführt wird.

Fügen Sie die folgenden Gläser hinzu (durch Abhängigkeit oder durch Herunterladen und Hinzufügen zum Klassenpfad).

<dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-mapper-asl</artifactId>
<version>1.9.13</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.5.3</version>
</dependency>

Dies sollte das Problem beheben. 

Vollständiger Code:

function() {
  $.ajax({
    type: "POST",
    url: "saveUserDetails.do",
    data: JSON.stringify({
      name: "Gerry",
      ity: "Sydney"
    }),
    headers: {
      'Accept': 'application/json',
      'Content-Type': 'application/json'
    },
    success: function(data) {
      if (data.status == 'OK')
        alert('Person has been added');
      else
        alert('Failed adding person: ' + data.status + ', ' + data.errorMessage);
}

und die Controller-Signatur sieht so aus:

@RequestMapping(value = "/saveUserDetails.do", method = RequestMethod.POST)
public @ResponseBody Person addPerson( @RequestBody final  Person person) {

Hoffe das hilft

9
vinSan

Ich habe dieses Problem gesehen, als ich Springboot mit Spring MVC integriert habe. Ich habe es gelöst, indem ich diese Abhängigkeiten hinzugefügt habe.

<dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-mapper-asl</artifactId>
<version>1.9.13</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.5.3</version>
</dependency>
8
deep

Eine kleine Randbemerkung - bei der Entwicklung einer Webanwendung auf diesen Fehler gestoßen. Der Fehler, den wir beim Spielen mit dem Dienst Firefox Poster fanden, bestand darin, dass sowohl Felder als auch Werte im Json von Anführungszeichen umgeben sein sollten. Zum Beispiel..

[ {"idProductCategory" : "1" , "description":"Descrizione1"}, 
  {"idProductCategory" : "2" , "description":"Descrizione2"} ]

In unserem Fall füllten wir den Json über Javascript, was beim Umgang mit einfachen/doppelten Anführungszeichen etwas verwirrend sein kann, was ich gehört habe.

Was in diesem und anderen Beiträgen bereits gesagt wurde, gilt auch für die Überschriften 'Accept' und 'Content-Type'.

Hoffe, ich helfe.

5
Carlos Romero

Ich hatte das gleiche Problem. Ich musste diese Schritte ausführen, um das Problem zu beheben:

1. Stellen Sie sicher, dass Sie die folgenden Abhängigkeiten haben:

    <dependency>
        <groupId>com.fasterxml.jackson.core</groupId>
        <artifactId>jackson-core</artifactId>
        <version>${jackson-version}</version> // 2.4.3
    </dependency>
    <dependency>
        <groupId>com.fasterxml.jackson.core</groupId>
        <artifactId>jackson-databind</artifactId>
        <version>${jackson-version}</version> // 2.4.3
    </dependency>

2. Erstellen Sie den folgenden Filter:

    public class CORSFilter extends OncePerRequestFilter {

        @Override
        protected void doFilterInternal(HttpServletRequest request,
                                        HttpServletResponse response, FilterChain filterChain)
                throws ServletException, IOException {

            String Origin = request.getHeader("Origin");
            Origin = (Origin == null || Origin.equals("")) ? "null" : Origin;
            response.addHeader("Access-Control-Allow-Origin", Origin);
            response.addHeader("Access-Control-Allow-Methods", "POST, GET, PUT, UPDATE, DELETE, OPTIONS");
            response.addHeader("Access-Control-Allow-Credentials", "true");
            response.addHeader("Access-Control-Allow-Headers",
                    "Authorization, Origin, content-type, accept, x-requested-with");

            filterChain.doFilter(request, response);
        }
    }

3. Wenden Sie den obigen Filter für die Anforderungen in web.xml an

    <filter>
        <filter-name>corsFilter</filter-name>
        <filter-class>com.your.package.CORSFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>corsFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

Ich hoffe, das ist jemandem nützlich.

1
Manoj Shrestha

Ich habe dieses Problem gelöst, indem ich meinem Pom die Datenbindung von Jackson-Json hinzugefügt habe.

<dependency>
        <groupId>com.fasterxml.jackson.core</groupId>
        <artifactId>jackson-databind</artifactId>
        <version>2.6.3</version>
</dependency>
0

Spring Boot + Spring MVN

mit Ausgabe @PostMapping ("/ addDonation") public String addDonation (@RequestBody DonatorDTO DonatorDTO) {

mit Lösung @RequestMapping (value = "/ addDonation", method = RequestMethod.POST) @ResponseBody public GenericResponse addDonation (final DonatorDTO-DonatorDTO, letzte Anforderung für HttpServletRequest) {