Na podstawie odpowiedzi na problem z x-www-form-urlencoded przy użyciu Spring @Controller
Poniżej napisałem metodę @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");
}
}
żądanie, które kończy się niepowodzeniem z powodu poniższego błędu
{
"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 był o wiele bardziej przyjazny, ale nie mógł go teraz używać, biorąc pod uwagę praktyczne ograniczenia]
spring
spring-mvc
model-view-controller
Somasundaram Sekar
źródło
źródło
JSON.stringify({"ordersToDownload":"00417002"}
$.ajax({url:"/myurl", type:"POST", data: JSON.stringify({"someAttribute":"someData"}) })
Odpowiedzi:
Problem polega na tym, że kiedy używamy application / x-www-form-urlencoded , Spring nie rozumie tego jako RequestBody. Tak więc, jeśli chcemy tego użyć, musimy usunąć @RequestBody adnotację .
Następnie spróbuj wykonać następujące czynności:
@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; }
Zwróć uwagę, że usunięto adnotację @RequestBody
Odpowiedź : Żądanie Http Post z typem zawartości application / x-www-form-urlencoded nie działa na wiosnę
źródło
application/x-www-form-urlencoded
?@ModelAttribute, even though this behaviour is (sadly) not documented. And
@ModelAttribute rozumieć x-www-form-urlencodedWygląda na to, że teraz możesz po prostu oznaczyć parametr metody za pomocą
@RequestParam
i zrobi to za Ciebie.@PostMapping( "some/request/path" ) public void someControllerMethod( @RequestParam Map<String, String> body ) { //work with Map }
źródło
Dodaj nagłówek do żądania, aby ustawić typ zawartości na application / json
curl -H 'Content-Type: application/json' -s -XPOST http://your.domain.com/ -d YOUR_JSON_BODY
w ten sposób wiosna wie, jak przeanalizować zawartość.
źródło
Wiosną 5
@PostMapping( "some/request/path" ) public void someControllerMethod( @RequestParam MultiValueMap body ) { // import org.springframework.util.MultiValueMap; String datax = (String) body .getFirst("datax"); }
źródło
Samo usunięcie
@RequestBody
adnotacji rozwiązuje problem (testowane na Spring Boot 2):@RestController public class MyController { @PostMapping public void method(@Valid RequestDto dto) { // method body ... } }
źródło
O alternatywie pisałem w tej odpowiedzi StackOverflow .
Tam pisałem krok po kroku, wyjaśniając kodem. Krótka droga:
Po pierwsze : napisz obiekt
Po drugie : utwórz konwerter do mapowania modelu rozszerzającego AbstractHttpMessageConverter
Trzeci : powiedz, by wiosna użyła tego konwertera implementującego WebMvcConfigurer.class nadpisującego metodę configureMessageConverters
Czwarty i ostatnie: używając tego ustawienia implementacji w mapowaniu wewnątrz kontrolera, konsumuje = MediaType.APPLICATION_FORM_URLENCODED_VALUE i @RequestBody przed obiektem.
Używam buta sprężynowego 2.
źródło
@PostMapping(path = "/my/endpoint", consumes = { MediaType.APPLICATION_FORM_URLENCODED_VALUE }) public ResponseEntity<Void> handleBrowserSubmissions(MyDTO dto) throws Exception { ... }
U mnie to działa
źródło
Możesz spróbować włączyć obsługę w konwerterze Springa
@EnableWebMvc @Configuration public class WebConfig implements WebMvcConfigurer { @Override public void extendMessageConverters(List<HttpMessageConverter<?>> converters) { // add converter suport Content-Type: 'application/x-www-form-urlencoded' converters.stream() .filter(AllEncompassingFormHttpMessageConverter.class::isInstance) .map(AllEncompassingFormHttpMessageConverter.class::cast) .findFirst() .ifPresent(converter -> converter.addSupportedMediaTypes(MediaType.APPLICATION_FORM_URLENCODED_VALUE)); } }
źródło
@RequestBody MultiValueMap paramMap
tutaj Usuń adnotację @RequestBody
@RequestMapping(value = "/signin",method = RequestMethod.POST) public String createAccount(@RequestBody LogingData user){ logingService.save(user); return "login"; } @RequestMapping(value = "/signin",method = RequestMethod.POST) public String createAccount( LogingData user){ logingService.save(user); return "login"; }
tak
źródło