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"}

utilisateur3443794
la source
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.

utilisateur3443794
la source
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

Parth Solanki
la source
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

Dhruv
la source
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'
Karthik
la source
4

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

dataType: "json",
contentType:'application/json'
Dulith De Costa
la source
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.

Arjun Duggal
la source
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),
Nalan Madheswaran
la source
1

Parfois, Charset Metada rompt le json lors de l'envoi de la requête. Mieux, n'utilisez pas charset = utf8 dans le type de requête.

Murali Gundappan
la source
2
utf8 n'est tout simplement pas un jeu de caractères valide. Regardez les spécifications: iana.org/assignments/character-sets/character-sets.xhtml
Berin Loritsch
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
javaPlease42
la source
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

TiyebM
la source
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.

Rahul Rastogi
la source
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.

Spajdo
la source
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.

Jero Dungog
la source
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);
    }
}
Jéjé
la source
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

BHARATHWAJ
la source