Fehler 415 Nicht unterstützter Medientyp: POST erreicht REST bei JSON nicht, bei XML jedoch nicht

78

Ich bin eigentlich neu bei REST WS, aber das verstehe ich wirklich nicht 415 Unsupported Media Type.

Ich teste mein REST mit Poster auf Firefox und das GETfunktioniert gut für mich, auch das POST(wenn es ein ist application/xml), aber wenn ich es versuche application/json, erreicht es das WS überhaupt nicht, der Server lehnt es ab.

Dies ist meine URL: http: // localhost: 8081 / RestDemo / services / customers / add

Das JSONsende ich:{"name": "test1", "address" :"test2"}

Das XMLsende ich:

<customer>
    <name>test1</name>
    <address>test2</address>
</customer>

und das ist meine Ressourcenklasse:

@Produces("application/xml")
@Path("customers")
@Singleton
@XmlRootElement(name = "customers")
public class CustomerResource {

    private TreeMap<Integer, Customer> customerMap = new TreeMap<Integer, Customer>();

    public  CustomerResource() {
        // hardcode a single customer into the database for demonstration
        // purposes
        Customer customer = new Customer();
        customer.setName("Harold Abernathy");
        customer.setAddress("Sheffield, UK");
        addCustomer(customer);
    }

    @GET
    @XmlElement(name = "customer")
    public List<Customer> getCustomers() {
        List<Customer> customers = new ArrayList<Customer>();
        customers.addAll(customerMap.values());
        return customers;
    }

    @GET
    @Path("/{id}")
    @Produces("application/json")
    public String getCustomer(@PathParam("id") int cId) {
        Customer customer = customerMap.get(cId); 
        return  "{\"name\": \" " + customer.getName() + " \", \"address\": \"" + customer.getAddress() + "\"}";

    }

    @POST
    @Path("/add")
    @Produces(MediaType.APPLICATION_JSON)
    @Consumes({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
    public String addCustomer(Customer customer) {
         //insert 
         int id = customerMap.size();
         customer.setId(id);
         customerMap.put(id, customer);
         //get inserted
         Customer result = customerMap.get(id);

         return  "{\"id\": \" " + result.getId() + " \", \"name\": \" " + result.getName() + " \", \"address\": \"" + result.getAddress() + "\"}";
    }

}

EDIT 1:

Dies ist meine Kundenklasse:

@XmlRootElement 
public class Customer implements Serializable {

    private int id;
    private String name;
    private String address;

    public Customer() {
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }

}
mzereba
quelle
Wie sieht deine CustomerKlasse aus? Welche JAXB-Annotationen verwenden Sie darauf?
Vielen Dank, ich habe den Code mit meiner Kundenklasse aktualisiert.
Mzereba

Antworten:

20

Das Problem liegt in der Deserialisierung des Bean-Kunden. Ihre Programme wissen, wie es in XML gemacht wird, mit JAXB, wie Daniel schreibt, aber höchstwahrscheinlich wissen sie nicht, wie es in JSON geht.

Hier haben Sie ein Beispiel mit Resteasy / Jackson http://www.mkyong.com/webservices/jax-rs/integrate-jackson-with-resteasy/

Das gleiche gilt für Jersey: http://www.mkyong.com/webservices/jax-rs/json-example-with-jersey-jackson/

unludo
quelle
1
In diesen Beispielen ist die Eingabe genau die gleiche wie meine, die Rendite ist unterschiedlich (wie Daniel sagte), aber mein Problem liegt vor mir und ich treffe die Klasse überhaupt nicht.
Mzereba
@Maged benutzt du Resteasy oder Trikot?
Unludo
@Maged Haben Sie Ihre web.xml wie im Artikel beschrieben aktualisiert?
Unludo
Ja, ich habe das Zuordnungsbit <init-param> <param-name> com.sun.jersey.api.json.POJOMappingFeature </ param-name> <param-value> true </ param-value> </ init- hinzugefügt param>
mzereba
1
Das Problem wurde über diesen Link behoben. Stackoverflow.com/questions/19396696/… aus dem ios-Teil, den wir erwähnen müssen. Machen Sie den Inhaltstyp "application / json; odata = verbose" in Ihrer POST-Anfrage
Naveenbos
135

Hinzufügen Content-Type: application/jsonund Accept: application/json im REST-Client-Header-Bereich

Anup Awasthi
quelle
4
Wo befindet sich der Header-Abschnitt des REST-Clients?
Tamuren
1
Wenn Sie den Curl-Aufruf über die Befehlszeile verwenden, können Sie den Header wie folgt hinzufügen: [$> curl -H "Inhaltstyp: application / json" -X POST -d '{"name": "my_name", "password" ":" 123456 "} ' localhost: 8080 / url]
Muhammad Suleman
Benötigen Sie Ihre Hilfe? Ich bin neu in dieser Rest-API-Erstellung. Wo befindet sich der EST-Client-Header-Bereich?
Naveenbos
2
Für alle, die aus einer anderen Sprache hierher gekommen sind und diese Sprache Ruby war und Sie Rest-Client verwenden, hat mir diese Antwort eine Menge geholfen. Anwendungsbeispielresponse = RestClient.post "https://pod12.salesforce.com/services/data/v33.0/sobjects/Contact/", {Email: user.email, LastName: user.last_name, FirstName: user.first_name, Phone: user.phone}.to_json, {Authorization: "Bearer #{access_token}", :"Content-Type" => "application/json", :"Accept" => "application/json"}
Michael
Hat mir auch bei Python geholfen. Denken Sie daran, die Nutzlast als JSON zu übergeben:requests.post("/login", data = json.dumps(loginCredentials), headers = {"Content-Type": "application/json", "Accept": "application/json"})
Kaivosukeltaja
16

Nur für den Fall, dass dies für andere hilfreich ist, hier meine Anekdote:

Ich habe diesen Thread als Ergebnis eines Problems gefunden, auf das ich gestoßen bin, als ich Postman zum Senden von Testdaten an meinen RESTEasy-Server verwendet habe. Nach einer wesentlichen Codeänderung wurden nur 415 nicht unterstützte Medientypfehler angezeigt.

Kurz gesagt, ich habe alles herausgerissen und schließlich versucht, das triviale Beispiel für das Hochladen von Dateien auszuführen, von dem ich wusste, dass es funktioniert. es tat es nicht. Da wurde mir klar, dass das Problem bei meiner Postbotenanfrage lag. Normalerweise sende ich keine speziellen Header, aber in einem früheren Test hatte ich einen "Content-Type": "application / json" -Header hinzugefügt. Natürlich habe ich versucht, "mehrteilige / Formulardaten" hochzuladen. Das Entfernen löste mein Problem.

Moral: Überprüfen Sie Ihre Überschriften, bevor Sie Ihre Welt in die Luft jagen. ;)

Max P Magee
quelle
3
+1 für den Hinweis "Stellen Sie sicher, dass der Toaster angeschlossen ist". Hatte gerade das gleiche Problem und es ist leicht zu übersehen, wenn Sie überzeugt sind, dass das Problem im Code liegt.
Jared G
3

Ich hatte dieses Problem und stellte fest, dass das Problem darin bestand, dass ich die JacksonFeature-Klasse nicht registriert hatte:

// Create JAX-RS application.
final Application application = new ResourceConfig()
    ...
    .register(JacksonFeature.class);

Ohne dies zu tun, kann Ihre Anwendung den JSON nicht in ein Java-Objekt konvertieren.

https://jersey.java.net/documentation/latest/media.html#json.jackson

David Hopkins
quelle
1
Kannst du etwas mehr erklären? Ich habe fast alles versucht und ich glaube, ich vermisse diesen Punkt. Wo soll ich diese Registrierung machen? Danke
Armen
Vielen Dank, ich bin darauf gestoßen, als ich einen Grizzly-Server gestartet habe. Beim Start mit IDE oder mvn: Führen Sie alles ordnungsgemäß aus, jedoch nicht, wenn Sie ein JAR mit Abhängigkeiten verwenden. Sie haben meinen Tag gemacht, Sir!
Julien
1

Ich hatte das gleiche Problem:

curl -v -H "Inhaltstyp: application / json" -X PUT -d '{"Name": "json", "Nachname": "gson", "verheiratet": wahr, "Alter": 32, " Gehalt ": 123," hasCar ": true," childs ": [" serkan "," volkan "," aybars "]} 'XXXXXX / ponyo / UserModel / json

* About to connect() to localhost port 8081 (#0)
*   Trying ::1...
* Connection refused
*   Trying 127.0.0.1...
* connected
* Connected to localhost (127.0.0.1) port 8081 (#0)
> PUT /ponyo/UserModel/json HTTP/1.1
> User-Agent: curl/7.28.1
> Host: localhost:8081
> Accept: */*
> Content-Type: application/json
> Content-Length: 121
> 
* upload completely sent off: 121 out of 121 bytes
< HTTP/1.1 415 Unsupported Media Type
< Content-Type: text/html; charset=iso-8859-1
< Date: Wed, 09 Apr 2014 13:55:43 GMT
< Content-Length: 0
< 
* Connection #0 to host localhost left intact
* Closing connection #0

Ich habe es gelöst, indem ich die Abhängigkeit wie folgt zu pom.xml hinzugefügt habe. Versuch es bitte.

    <dependency>
        <groupId>com.owlike</groupId>
        <artifactId>genson</artifactId>
        <version>0.98</version>
    </dependency>
DàChún
quelle
1

Ich bekomme das gleiche Problem. Tatsächlich erreichte die Anfrage nicht die mit Trikot annotierte Methode. Ich habe das Problem mit dem Hinzufügen der Anmerkung gelöst: @Consumes (MediaType.APPLICATION_FORM_URLENCODED) Die Anmerkung @Consumes (" / ") funktioniert nicht!

    @Path("/"+PropertiesHabilitation.KEY_EstNouvelleGH)
    @POST
    //@Consumes("*/*")
    @Consumes(MediaType.APPLICATION_FORM_URLENCODED)
    public void  get__EstNouvelleGH( @Context HttpServletResponse response) {
        ...
    }
Bertrand
quelle
0

Geben Sie in Ihren Methoden keine Strings zurück, aber der Kunde widerspricht sich selbst und lässt JAXB die De- / Serialisierung übernehmen.

Daniel Kutik
quelle
2
Könnte sein, aber ich denke hier liegt das Problem vor mir, ich treffe den Service überhaupt nicht.
Mzereba
0

Ich hatte das gleiche Problem, da es den Fehler-415-nicht unterstützten Medientyp gab, während ich mit json auf einen Post-Call traf, während ich bereits den hatte

@Consumes(MediaType.APPLICATION_JSON) 

und fordern Sie Header wie in meinem erholsamen Webdienst mit Jersey 2.0+ an

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

Ich habe dieses Problem behoben, indem ich meinem Projekt folgende Abhängigkeiten hinzugefügt habe

<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-json-jackson</artifactId>
<version>2.25</version>
</dependency>

Dadurch werden Ihrer Bibliothek folgende Gläser hinzugefügt:

  1. jersey-media-json-jackson-2.25.jar
  2. Trikot-Entity-Filtering-2.25.jar
  3. jackson-module-jaxb-annotations-2.8.4.jar
  4. jackson-jaxrs-json-provider-2.8.4.jar
  5. jackson-jaxrs-base-2.8.4.jar

Ich hoffe, dass es auch für andere funktioniert, so wie es für mich getan hat.

Prakhar Agrawal
quelle
0

Ändern Sie einfach den Inhaltstyp in application / json, wenn Sie JSON mit POST / PUT usw. verwenden.

Chirag
quelle
0

Wenn Sie versuchen, die ARC-App von Google zu verwenden und eine zu posten, XMLund diese Fehlermeldung angezeigt wird, ändern Sie den Inhaltstyp des Körpers in application/xml. Beispiel hier

Swati Shilpa
quelle
0

Ich habe das gleiche Problem beim Postboten festgestellt. Ich habe im Header-Abschnitt Akzeptieren ausgewählt und den Wert als "application / json" angegeben. Also habe ich den Inhaltstyp deaktiviert und ausgewählt und den Wert als "application / json" angegeben. Das hat funktioniert!

Harish
quelle
0

Ich hatte ein ähnliches Problem bei der Verwendung im Postboten. Für POST-Anforderungen im Header-Bereich fügen Sie diese als hinzu

Schlüssel: Wertpaar

Inhaltstyp: application / json Akzeptieren: application / json

ich hoffe, dass es funktionieren wird.

Phanindra Nath
quelle
0

Wenn keine der Lösungen funktioniert hat und Sie mit JAXB arbeiten, müssen Sie Ihre Klasse mit Anmerkungen versehen @XmlRootElement , um dies zu vermeiden415 unsupported media type

Amrit
quelle