Http 415 Erro de tipo de mídia incompatível com JSON

115

Estou chamando um serviço REST com uma solicitação JSON e ele responde com um HTTP 415 "Unsupported Media Type"erro.

O tipo de conteúdo da solicitação é definido como ("Content-Type", "application/json; charset=utf8").

Funciona bem se eu não incluir um objeto JSON na solicitação. Estou usando a google-gson-2.2.4biblioteca para JSON.

Tentei usar algumas bibliotecas diferentes, mas não fez diferença.

Alguém pode me ajudar a resolver isso?

Aqui está o meu código:

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;

}
}

O valor de requestJson.toString()é:

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

user3443794
fonte
Atualize sua pergunta com o valor derequestJson.toString()
Sabuj Hassan
1
O valor de requestJson.toString é: {"type": "arl", "action": "remove", "domain": "staging", "objects": " abc.com "}
user3443794
Você escreveu a parte do servidor? Se você fizer a mesma solicitação com o Postman (extensões do Chrome, Google), funciona? Talvez o servidor não aceite o tipo de conteúdo JSON por algum motivo?
joscarsson
Sim, eu testei isso usando o soapUI. Enviei exatamente a mesma solicitação incluindo json e obtive uma resposta bem-sucedida do servidor.
user3443794
@joscarsson, desde 14 de março de 2017, a extensão Postman Chrome está obsoleta. Eles mudaram para o aplicativo nativo. Aqui está a postagem do blog deles: http://blog.getpostman.com/2017/03/14/going-native/
Serge Kishiko

Respostas:

81

Não tenho certeza sobre o motivo, mas a remoção das linhas charset=utf8de con.setRequestProperty("Content-Type", "application/json; charset=utf8")resolveu o problema.

user3443794
fonte
Provavelmente é um bug no serviço ReST. Provavelmente não se espera charsetque sejam configurados no Content-Type. Meu palpite é que eles estão verificando se a string "application/json; charset=utf-8" == "application/json". Dito isso, JSON deve ser utf-8, portanto, é perfeitamente válido deixar de fora o conjunto de caracteres.
Tim Martin
20
Porque charset=utf8não é uma designação de conjunto de caracteres válida. A versão correta seria charset=utf-8. O traço é importante. A lista de designações de conjuntos de caracteres válidos é gerenciada pela IANA RFC2879: iana.org/assignments/character-sets/character-sets.xhtml
Berin Loritsch
Perdi muito tempo tentando coisas diferentes e depois tentei remover o charset = utf8 e funcionou. Obrigado.
Salman
53

Adicione Content-Type: application/jsone Accept:application/json

Parth Solanki
fonte
1
Se você estiver usando o Postman para testes, tente adicionar esta parte aos cabeçalhos : Content-Type: application / json
Z3d4s
13

Isso ocorre porque charset=utf8deve ficar sem espaço depois application/json. Isso vai funcionar bem. Use comoapplication/json;charset=utf-8

Dhruv
fonte
Isso está incorreto; espaços são permitidos e devem ser ignorados; consulte tools.ietf.org/html/rfc2046 .
djb
11

Se você estiver fazendo uma solicitação jquery ajax, não se esqueça de adicionar

contentType:'application/json'
Karthik
fonte
4

Se você estiver usando AJAX jQueryRequest, é obrigatório se inscrever. Do contrário, você receberá um 415erro.

dataType: "json",
contentType:'application/json'
Dulith De Costa
fonte
2

Adicione o gerenciador de cabeçalho HTTP e adicione os nomes e valores de cabeçalho da API. por exemplo, Content-type, Accept, etc. Isso resolverá seu problema.

Arjun Duggal
fonte
2

Se você conseguir isso no middleware React RSAA ou similar, adicione os cabeçalhos:

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

Algumas vezes Charset Metada quebra o json ao enviar a solicitação. Melhor, não use charset = utf8 no tipo de solicitação.

Murali Gundappan
fonte
2
utf8 simplesmente não é um conjunto de caracteres válido. Veja as especificações: iana.org/assignments/character-sets/character-sets.xhtml
Berin Loritsch
1

Eu consertei isso atualizando a Requestclasse que meu controlador recebe.

I removido a seguinte anotação nível da classe de minha Requestclasse no lado meu servidor. Depois disso, meu cliente não obteve o erro 415.

import javax.xml.bind.annotation.XmlRootElement;
@XmlRootElement
javaPlease42
fonte
1

O código de status 415 (Tipo de mídia não suportado) indica que o servidor de origem se recusa a atender à solicitação porque a carga útil está em um formato não suportado por este método no recurso de destino. O problema de formato pode ser devido ao Content-Type ou Content-Encoding indicado na solicitação, ou como resultado da inspeção direta dos dados. DOC

TiyebM
fonte
0

Eu estava enviando uma solicitação de resto "delete" e falhou com 415. Eu vi qual tipo de conteúdo meu servidor usa para atingir a API. No meu caso, era "application / json" em vez de "application / json; charset = utf8".

Portanto, pergunte ao seu desenvolvedor de API. Enquanto isso, tente enviar a solicitação apenas com content-type = "application / json".

Rahul Rastogi
fonte
0

Eu tive o mesmo problema. Meu problema era um objeto complicado para serialização. Um atributo do meu objeto era Map<Object1, List<Object2>>. Eu mudei este atributo como List<Object3>, onde Object3contém Object1e Object2e tudo funciona bem.

Spajdo
fonte
0

Eu sei que é tarde demais para ajudar o OP com seu problema, mas para todos nós que estão apenas encontrando esse problema, eu resolvi esse problema removendo o construtor com parâmetros de minha classe que deveria conter os dados json.

Jero Dungog
fonte
0

Adicionar MappingJackson2HttpMessageConverter manualmente na configuração resolveu o problema para mim:

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

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

O motivo pode ser não adicionar "orientado a anotações" no arquivo xml do servlet do distribuidor. e também pode ser devido a não adicionar como application / json nos cabeçalhos

BHARATHWAJ
fonte