Error de tipo de medio no admitido Http 415 con JSON

115

Estoy llamando a un servicio REST con una solicitud JSON y responde con un HTTP 415 "Unsupported Media Type"error.

El tipo de contenido de la solicitud se establece en ("Content-Type", "application/json; charset=utf8").

Funciona bien si no incluyo un objeto JSON en la solicitud. Estoy usando la google-gson-2.2.4biblioteca para JSON.

Intenté usar un par de bibliotecas diferentes pero no hizo ninguna diferencia.

¿Alguien puede ayudarme a resolver esto?

Aquí está mi 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;

}
}

El valor de requestJson.toString()es:

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

usuario3443794
fuente
requestJson.toString()
Actualice
1
El valor de requestJson.toString es: {"type": "arl", "action": "remove", "domain": "staging", "objects": " abc.com "}
user3443794
¿Ha escrito la parte del servidor? Si hace la misma solicitud con Postman (extensiones de Chrome, Google), ¿funciona? ¿Quizás el servidor no acepta el tipo de contenido JSON por alguna razón?
Joscarsson
Sí, lo probé usando soapUI. Envié exactamente la misma solicitud, incluido json, y obtuve una respuesta exitosa del servidor.
user3443794
@joscarsson, desde el 14 de marzo de 2017, la extensión de Chrome Postman está obsoleta. Pasaron a la aplicación nativa. Aquí está la publicación de su blog: http://blog.getpostman.com/2017/03/14/going-native/
Serge Kishiko

Respuestas:

81

No estoy seguro de la razón, sino líneas Extracción charset=utf8de con.setRequestProperty("Content-Type", "application/json; charset=utf8")resuelto el problema.

usuario3443794
fuente
Probablemente sea un error en el servicio ReST. Probablemente no se espera charsetque se establezcan en el tipo de contenido. Supongo que están comprobando si la cuerda "application/json; charset=utf-8" == "application/json". Dicho esto, JSON debe ser utf-8, por lo que es perfectamente válido omitir el juego de caracteres.
Tim Martin
19
Porque charset=utf8no es una designación de juego de caracteres válida. La versión correcta sería charset=utf-8. El guión es importante. La lista de designaciones de conjuntos de caracteres válidos es administrada por IANA RFC2879: iana.org/assignments/character-sets/character-sets.xhtml
Berin Loritsch
Perdí mucho tiempo probando cosas diferentes y luego intenté eliminar charset = utf8 y funcionó. Gracias.
Salman
53

Agregar Content-Type: application/jsony Accept:application/json

Parth Solanki
fuente
1
Si usa Postman para las pruebas, intente agregar esta parte a los encabezados : Content-Type: application / json
Z3d4s
13

Esto se debe a que charset=utf8debe quedar sin un espacio después application/json. Eso funcionará bien. Úselo comoapplication/json;charset=utf-8

Dhruv
fuente
Esto es incorrecto; los espacios están permitidos y deben ignorarse; consulte tools.ietf.org/html/rfc2046 .
djb
11

Si está haciendo una solicitud jquery ajax, no olvide agregar

contentType:'application/json'
karthik
fuente
4

Si está utilizando AJAX jQuerySolicitar, esta es una solicitud obligatoria. Si no, te arrojará 415Error.

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

Agregue el administrador de encabezado HTTP y agregue en él los nombres y valores de encabezado de su API. por ejemplo, tipo de contenido, aceptar, etc. Eso resolverá su problema.

Arjun Duggal
fuente
2

Si obtiene esto en el middleware React RSAA o similar, agregue los encabezados:

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

Solucioné esto actualizando la Requestclase que recibe mi controlador.

Me quité la siguiente anotación nivel de clase de mi Requestclase en mi lado del servidor. Después de eso, mi cliente no recibió el error 415.

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

El código de estado 415 (Tipo de medio no admitido) indica que el servidor de origen se niega a atender la solicitud porque la carga útil está en un formato no admitido por este método en el recurso de destino. El problema de formato puede deberse al tipo de contenido o codificación de contenido indicados en la solicitud, o al resultado de inspeccionar los datos directamente. DOC

TiyebM
fuente
0

Estaba enviando una solicitud de descanso de "eliminación" y falló con 415. Vi qué tipo de contenido usa mi servidor para acceder a la API. En mi caso, era "application / json" en lugar de "application / json; charset = utf8".

Pregúntele a su desarrollador de api. Mientras tanto, intente enviar la solicitud con content-type = "application / json" solamente.

Rahul Rastogi
fuente
0

Tuve el mismo problema. Mi problema era un objeto complicado para la serialización. Un atributo de mi objeto fue Map<Object1, List<Object2>>. He cambiado este atributo como List<Object3>cuando Object3contiene Object1y Object2y todo funciona bien.

spajdo
fuente
0

Sé que es demasiado tarde para ayudar al OP con su problema, pero para todos los que acabamos de encontrarnos con este problema, resolví este problema eliminando el constructor con los parámetros de mi clase, que estaba destinado a contener los datos json.

Jero Dungog
fuente
0

Agregar MappingJackson2HttpMessageConverter manualmente en la configuración resolvió el problema para mí:

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

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

El motivo puede ser no agregar "controlado por anotaciones" en el archivo xml del servlet del despachador. y también puede deberse a no agregar como aplicación / json en los encabezados

BHARATHWAJ
fuente