it-swarm.com.de

REST Mehrteilige gemischte Anforderung (Datei + Json) mit Spring

Ich muss eine Datei zusammen mit einem Json an meinen Spring Controller senden. Ich habe die folgende Controller-Klasse: 

@Controller
@RequestMapping("/perform")
public class PerformController {

    ...

    @RequestMapping(path = "gopdf", method = RequestMethod.POST, consumes = { "multipart/mixed" })
    @ResponseStatus(HttpStatus.CREATED)
    public void handleFileUpload(@RequestPart("file") MultipartFile file, @RequestPart("map") String map,   HttpServletResponse response) throws Exception {
        ...
    }

}

Wenn ich mich aber auf meinem Server mit dem folgenden Befehl einrollen:

 curl -H "Content-Type: multipart/form-data" -F "[email protected]; type=application/json" -F "[email protected]" -X POST localhost:9000/perform/gopdf-i -v

Ich bekomme 415 nicht unterstützte Medientypen!

Irgendeine Ahnung ?

6
ElArbi

Das verbrauchte Ding in den anderen Antworten war für mich kein Mist. Der Schlüssel bestand darin, die speziellen Multipart/* -Typen, die ich unterstützen wollte, auf einige Headerschlüssel im RequestMapping zu übertragen. Es war wirklich schwer herauszufinden, meist nur zu raten und den Quellcode von Spring anzustarren. Ich bin irgendwie mit Springs Unterstützung dafür nicht so begeistert, aber es ist mir gelungen, es in unserer Spring Boot App zum Laufen zu bringen, aber nur mit Tomcat?!? Etwas, das als MultipartResolver-Chokes bezeichnet wird, wenn Sie Ihre Boot-Anwendung für die Verwendung von Jetty konfigurieren ... so lange Jetty. Aber ich schweife ab...

In meinem Controller habe ich für Multipart/Mixed oder Multipart/Formulardaten wie ...

@RequestMapping(value = "/user/{userId}/scouting_activities", method = RequestMethod.POST,
        headers = {"content-type=multipart/mixed","content-type=multipart/form-data"})
public ResponseEntity<String> POST_v1_scouting_activities(
        @RequestHeader HttpHeaders headers,
        @PathVariable String userId,
        @RequestPart(value = "image", required = false) MultipartFile image,
        @RequestPart(value = "scouting_activity", required = true) String scouting_activity_json) {
  LOG.info("POST_v1_scouting_activities: headers.getContentType(): {}", headers.getContentType());
  LOG.info("POST_v1_scouting_activities: userId: {}", userId);
  LOG.info("POST_v1_scouting_activities: image.originalFilename: {}, image: {}",
          (image!=null) ? image.getOriginalFilename() : null, image);
  LOG.info("POST_v1_scouting_activities: scouting_activity_json.getType().getName(): {}, scouting_activity: {}",
          scouting_activity_json.getClass().getName(), scouting_activity_json);
  return new ResponseEntity<String>("POST_v1_scouting_activities\n", HttpStatus.OK);
}

Durch dieses Kopfzeilen-Ding konnte es eindeutig die mehrteiligen Inhaltstypen identifizieren, auf die er einen Schuss werfen wollte. Dies lässt Locken wie ...

curl -i -X POST 'http://localhost:8080/robert/v1/140218/scouting_activities' \
-H 'Content-type:multipart/mixed' \
-F '[email protected]_128x128.png;type=image/png' \
-F 'scouting_activity={
  "field": 14006513,
  "longitude": -93.2038253,
  "latitude": 38.5203231,
  "note": "This is the center of Dino Head.",
  "scouting_date": "2017-01-19T22:56:04.836Z"
};type=application/json'

...oder...

curl -i -X POST 'http://localhost:8080/robert/v1/140218/scouting_activities' \
-H 'Content-type:multipart/form-data' \
-F '[email protected]_128x128.png;type=image/png' \
-F '[email protected];type=application/json'

arbeit.

4
Bob Kuhar

Ich habe die Lösung gefunden: Ich muss @RequestParam anstelle von @RequestPart verwenden

@RequestMapping(path = "gopdf", method = RequestMethod.POST, consumes = { "multipart/form-data" })
@ResponseStatus(HttpStatus.OK)
public void handleFileUpload2(@RequestParam("file") MultipartFile file, @RequestParam("map") String jsonMap,
        HttpServletResponse response) throws Exceptio
2
ElArbi

Der Multipart/Mixed für Spring Webflux (2.1.0) hat bei mir nicht funktioniert. Hier ist ein alternativer Ansatz, der funktioniert hat

  • Working - Spring-Boot-Starter-Web/Multipart [] - Dateien hochladen, wobeiEine die Nutzlast ist, eine andere ist eine Datei selbst. In meinem Fall funktionierte es, da die Nutzlast konstant war.
  • Funktioniert nicht - Spring-Boot-Starter-Webflux/Flux. Der Fluss ist leer. Ich habe dies versucht https://github.com/spring-projects/spring-boot/issues/13268 , aber es hat nicht funktioniert
1
Aravind

Möglicherweise hängt dies mit Ihrer Annotation für Anforderungszuordnungen zusammen. Ich denke, dass der accept-Wert fehlt, um festzustellen, was der Dienst akzeptieren kann:

Beispiel:

@RequestMapping(path = "gopdf", method = RequestMethod.POST, consumes = { "multipart/mixed" }, accept = MediaType.MULTIPART_FORM_DATA_VALUE)

Einführen :

import org.springframework.http.MediaType;

Dokumentation/API:http://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/http/MediaType.html

0
Mickael