Тип контента 'application/x-www-form-urlencoded; charset = UTF-8' не поддерживается для @RequestBody MultiValueMap

Основано на ответе на проблему с x-www-form-urlencoded с Spring @Controller

Я написал ниже метод @Controller ниже

@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");
            }
    }

запрос на который не с приведенной ниже ошибкой

{
  "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: Джерси был гораздо более дружелюбным, но не мог использовать его сейчас, учитывая практические ограничения здесь]

Ответ 1

Проблема заключается в том, что, когда мы используем application/x-www-form-urlencoded, Spring не понимает его как RequestBody. Итак, если мы хотим использовать это мы должны удалить аннотацию @RequestBody.

Затем попробуйте следующее:

@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;
}

Обратите внимание, что удалили аннотацию @RequestBody

answer: Запрос на публикацию Http с приложением типа контента /x -www-form-urlencoded не работает в Spring

Ответ 2

Кажется, теперь вы можете просто отметить параметр метода с помощью @RequestParam, и он выполнит эту работу для вас.

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

Ответ 3

Добавьте заголовок к вашему запросу, чтобы задать тип контента для приложения /json

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

таким образом spring умеет разбирать содержимое.

Ответ 4

Я написал об альтернативе в fooobar.com/questions/12477717/....

Там я написал шаг за шагом, объясняя с помощью кода. Короткий путь:

Первый: написать объект

Второе: создать конвертер для отображения модели, расширяющей AbstractHttpMessageConverter

Третье: попросите spring использовать этот конвертер, реализующий класс WebMvcConfigurer.class, переопределяющий метод configureMessageConverters

Четвертое и последнее: при использовании этого параметра реализации в отображении внутри вашего контроллера перед вашим объектом будут потребляться = MediaType.APPLICATION_FORM_URLENCODED_VALUE и @RequestBody.

Я использую весеннюю загрузку 2.

Ответ 5

Spring 5

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

    // import org.springframework.util.MultiValueMap;

    String datax = (String) body .getFirst("datax");
}

Ответ 6

Простое удаление аннотации @RequestBody решает проблему (протестировано на Spring Boot 2):

@RestController
public class MyController {

    @PostMapping
    public void method(@Valid RequestDto dto) {
       // method body ...
    }
}

Ответ 7

Вместо использования карты вы можете использовать параметры напрямую:

   @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
}

Ответ 8

Мое решение с Alamofire на swift 3

Alamofire.request(url, method: .post, parameters: parameters, encoding: JSONEncoding.default, headers: headers).responseJSON