web-dev-qa-db-fra.com

Type de contenu 'application / x-www-form-urlencoded; charset = UTF-8' non pris en charge pour @RequestBody MultiValueMap

Basé sur la réponse pour un problème avec x-www-form-urlencoded avec Spring @Controller

J'ai écrit la méthode @Controller ci-dessous

@RequestMapping(value = "/{email}/authenticate", method = RequestMethod.POST
            , produces = {"application/json", "application/xml"}
            ,  consumes = {"application/x-www-form-urlencoded"}
    )
     public
        @ResponseBody
        Representation authenticate(@PathVariable("email") String anEmailAddress,
                                    @RequestBody MultiValueMap paramMap)
                throws Exception {


            if(paramMap == null || paramMap.get("password") == null) {
                throw new IllegalArgumentException("Password not provided");
            }
    }

la demande à laquelle échoue avec l'erreur ci-dessous

{
  "timestamp": 1447911866786,
  "status": 415,
  "error": "Unsupported Media Type",
  "exception": "org.springframework.web.HttpMediaTypeNotSupportedException",
  "message": "Content type 'application/x-www-form-urlencoded;charset=UTF-8' not supported",
  "path": "/users/usermail%40gmail.com/authenticate"
}

[PS: Jersey était beaucoup plus sympathique, mais ne pouvait pas l'utiliser maintenant compte tenu des restrictions pratiques ici]

63
Somasundaram Sekar

Le problème est que lorsque nous utilisons application/x-www-form-urlencoded , Spring ne le comprend pas en tant que RequestBody. Donc, si nous voulons utiliser cela, nous devons supprimer l'annotation @ RequestBody .

Ensuite, essayez ce qui suit:

@RequestMapping(value = "/{email}/authenticate", method = RequestMethod.POST,
        consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE, 
        produces = {MediaType.APPLICATION_ATOM_XML_VALUE, MediaType.APPLICATION_JSON_VALUE})
public @ResponseBody  Representation authenticate(@PathVariable("email") String anEmailAddress, MultiValueMap paramMap) throws Exception {
   if(paramMap == null && paramMap.get("password") == null) {
        throw new IllegalArgumentException("Password not provided");
    }
    return null;
}

Notez que l’annotation a été supprimée @ RequestBody

answer : requête de publication HTTP avec le type de contenu application/x-www-form-urlencoded ne fonctionnant pas au printemps

75
Douglas Ribeiro

Il semble que maintenant vous pouvez simplement marquer le paramètre de méthode avec @RequestParam et le travail sera fait pour vous.

@PostMapping( "some/request/path" )
public void someControllerMethod( @RequestParam Map<String, String> body ) {
  //work with Map
}
53
Scadge

Ajoutez un en-tête à votre demande pour définir le type de contenu sur application/json

curl -H 'Content-Type: application/json' -s -XPOST http://your.domain.com/ -d YOUR_JSON_BODY

de cette façon, Spring sait comment analyser le contenu.

12
Agustin Almonte

Au printemps 5

@PostMapping( "some/request/path" )
public void someControllerMethod( @RequestParam MultiValueMap body ) {

    // import org.springframework.util.MultiValueMap;

    String datax = (String) body .getFirst("datax");
}
1
Edgardo Genini

J'ai écrit sur une alternative dans cette réponse StackOverflow .

Là j'ai écrit pas à pas, en expliquant avec du code. Le chemin court:

Premier : écrire un objet

Second : créer un convertisseur pour mapper le modèle étendant AbstractHttpMessageConverter

Troisième : dites à Spring d'utiliser ce convertisseur en implémentant un WebMvcConfigurer.class surchargeant la méthode configureMessageConverters

Quatrième et final: à l'aide de ce paramètre d'implémentation dans le mappage de votre contrôleur, le paramètre consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE et @RequestBody devant votre objet.

J'utilise Spring Boot 2.

1
Marco Blos

Au lieu d'utiliser une carte, vous pouvez utiliser les paramètres directement:

   @RequestMapping(method = RequestMethod.POST, value = "/event/register")
   @ResponseStatus(value = HttpStatus.OK)
   public void registerUser(@RequestParam(name = EVENT_ID) String eventId,
                            @RequestParam(name = ATTENDEE_ID) String attendeeId,
                            @RequestParam(name = SCENARIO) String scenario) {
    log.info("Register user: eventid: {}, attendeeid: {}, scenario: {} ", eventId,attendeeId,scenario);

    //more code here
}
0
Crenguta S