Erreur de type de média Http 415 non pris en charge avec JSON


115

J'appelle un service REST avec une requête JSON et il répond avec une HTTP 415 "Unsupported Media Type"erreur.

Le type de contenu de la demande est défini sur ("Content-Type", "application/json; charset=utf8").

Cela fonctionne bien si je n'inclus pas d'objet JSON dans la demande. J'utilise la google-gson-2.2.4bibliothèque pour JSON.

J'ai essayé d'utiliser quelques bibliothèques différentes mais cela n'a fait aucune différence.

Quelqu'un peut-il m'aider à résoudre ce problème?

Voici mon code:

public static void main(String[] args) throws Exception
{

    JsonObject requestJson = new JsonObject();
    String url = "xxx";

    //method call for generating json

    requestJson = generateJSON();
    URL myurl = new URL(url);
    HttpURLConnection con = (HttpURLConnection)myurl.openConnection();
    con.setDoOutput(true);
    con.setDoInput(true);

    con.setRequestProperty("Content-Type", "application/json; charset=utf8");
    con.setRequestProperty("Accept", "application/json");
    con.setRequestProperty("Method", "POST");
    OutputStream os = con.getOutputStream();
    os.write(requestJson.toString().getBytes("UTF-8"));
    os.close();


    StringBuilder sb = new StringBuilder();  
    int HttpResult =con.getResponseCode();
    if(HttpResult ==HttpURLConnection.HTTP_OK){
    BufferedReader br = new BufferedReader(new   InputStreamReader(con.getInputStream(),"utf-8"));  

        String line = null;
        while ((line = br.readLine()) != null) {  
        sb.append(line + "\n");  
        }
         br.close(); 
         System.out.println(""+sb.toString());  

    }else{
        System.out.println(con.getResponseCode());
        System.out.println(con.getResponseMessage());  
    }  

}
public static JsonObject generateJSON () throws MalformedURLException

{
   String s = "http://www.example.com";
        s.replaceAll("/", "\\/");
    JsonObject reqparam=new JsonObject();
    reqparam.addProperty("type", "arl");
    reqparam.addProperty("action", "remove");
    reqparam.addProperty("domain", "staging");
    reqparam.addProperty("objects", s);
    return reqparam;

}
}

La valeur de requestJson.toString()est:

{"type":"arl","action":"remove","domain":"staging","objects":"http://www.example.com"}


Veuillez mettre à jour votre question avec la valeur derequestJson.toString()
Sabuj Hassan

1
La valeur de requestJson.toString est: {"type": "arl", "action": "remove", "domain": "staging", "objects": " abc.com "}
user3443794

Avez-vous écrit la partie serveur? Si vous faites la même demande avec Postman (extensions Chrome, Google it), ça marche? Peut-être que le serveur n'accepte pas le type de contenu JSON pour une raison quelconque?
joscarsson

Oui, j'ai testé cela en utilisant soapUI. J'ai envoyé exactement la même demande, y compris json et j'ai obtenu une réponse réussie du serveur.
user3443794

@joscarsson, depuis le 14 mars 2017, l'extension Chrome Postman est obsolète. Ils sont passés à l'application native. Voici leur article de blog: http://blog.getpostman.com/2017/03/14/going-native/
Serge Kishiko

Réponses:


81

Vous n'êtes pas sûr de la raison, mais la suppression des lignes charset=utf8de a con.setRequestProperty("Content-Type", "application/json; charset=utf8")résolu le problème.


C'est probablement un bogue dans le service ReST. On ne s'attend probablement pas à ce charsetqu'ils soient définis dans Content-Type. Je suppose qu'ils vérifient si la chaîne "application/json; charset=utf-8" == "application/json". Cela étant dit, JSON doit être utf-8, il est donc parfaitement valide d'omettre le jeu de caractères.
Tim Martin

20
Car charset=utf8n'est pas une désignation de jeu de caractères valide. La version correcte serait charset=utf-8. Le tiret est important. La liste des désignations de jeux de caractères valides est gérée par IANA RFC2879: iana.org/assignments/character-sets/character-sets.xhtml
Berin Loritsch

J'ai perdu beaucoup de temps à essayer différentes choses, puis j'ai essayé de supprimer le charset = utf8 et cela a fonctionné. Merci.
Salman

53

Ajouter Content-Type: application/jsonet Accept:application/json


1
Si vous utilisez Postman pour les tests, essayez d'ajouter cette partie aux en- têtes : Content-Type: application / json
Z3d4s

13

C'est parce que charset=utf8devrait être sans espace après application/json. Cela fonctionnera très bien. Utilisez-le commeapplication/json;charset=utf-8


Ceci est une erreur; les espaces sont autorisés et doivent être ignorés; voir tools.ietf.org/html/rfc2046 .
djb

11

Si vous faites une requête jquery ajax, n'oubliez pas d'ajouter

contentType:'application/json'

4

Si vous utilisez AJAX jQueryRequest, c'est un must pour postuler. Sinon, cela vous lancera une 415erreur.

dataType: "json",
contentType:'application/json'

2

Ajoutez le gestionnaire d'en-têtes HTTP et ajoutez-y les noms et valeurs d'en-tête de votre API. Par exemple, Type de contenu, Accepter, etc. Cela résoudra votre problème.


2

Si vous obtenez cela dans le middleware React RSAA ou similaire, ajoutez les en-têtes:

  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
  },
  body: JSON.stringify(model),


1

J'ai résolu ce problème en mettant à jour la Requestclasse que mon contrôleur reçoit.

J'ai supprimé l'annotation de niveau de classe suivante de ma Requestclasse du côté de mon serveur. Après cela, mon client n'a pas eu d'erreur 415.

import javax.xml.bind.annotation.XmlRootElement;
@XmlRootElement

1

Le code d'état 415 (Unsupported Media Type) indique que le serveur d'origine refuse de traiter la demande car la charge utile est dans un format non pris en charge par cette méthode sur la ressource cible. Le problème de format peut être dû au Content-Type ou Content-Encoding indiqué dans la demande, ou à l'inspection directe des données. DOC


0

J'envoyais une demande de repos "Supprimer" et cela a échoué avec 415. J'ai vu quel type de contenu mon serveur utilise pour atteindre l'API. Dans mon cas, c'était "application / json" au lieu de "application / json; charset = utf8".

Alors demandez à votre développeur api Et en attendant, essayez d'envoyer la requête avec content-type = "application / json" uniquement.


0

J'ai eu le même problème. Mon problème était un objet compliqué pour la sérialisation. Un attribut de mon objet était Map<Object1, List<Object2>>. J'ai changé cet attribut comme List<Object3>where Object3contains Object1et Object2et tout fonctionne bien.


0

Je sais que c'est trop tard pour aider l'OP avec son problème, mais pour nous tous qui rencontrons ce problème, j'avais résolu ce problème en supprimant le constructeur avec les paramètres de ma classe qui était censé contenir les données json.


0

Ajouter manuellement MappingJackson2HttpMessageConverter dans la configuration a résolu le problème pour moi:

@EnableWebMvc
@Configuration
@ComponentScan
public class RestConfiguration extends WebMvcConfigurerAdapter {

    @Override
    public void configureMessageConverters(List<HttpMessageConverter<?>> messageConverters) {
        messageConverters.add(new MappingJackson2HttpMessageConverter());
        super.configureMessageConverters(messageConverters);
    }
}

0

La raison peut être de ne pas ajouter "piloté par annotations" dans votre fichier xml de servlet de répartiteur. et aussi cela peut être dû à ne pas ajouter en tant qu'application / json dans les en-têtes

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.