How to send URL encoded data in spring webflux

Viewed 696

I am writing a spring 5 web app and my requirement is to get a urlencoded form and in response send url encoded response back

This is Router Function code

@Configuration
public class AppRoute {

  @Bean
  public RouterFunction<ServerResponse> route(FormHandler formHandler) {

    return RouterFunctions.route()
           // .GET("/form", formHandler::sampleForm)
           // .POST("/form", accept(MediaType.APPLICATION_FORM_URLENCODED), formHandler::displayFormData)
            .POST("/formnew", accept(MediaType.APPLICATION_FORM_URLENCODED).and(contentType(MediaType.APPLICATION_FORM_URLENCODED)), formHandler::newForm)
            .build();
  }
}

and here's my Handler code

public Mono<ServerResponse> newForm(ServerRequest request) {
    Mono<MultiValueMap<String, String>> formData = request.formData();
    MultiValueMap<String, String> newFormData = new LinkedMultiValueMap<String, String>();

    formData.subscribe(p -> newFormData.putAll(p));
    newFormData.add("status", "success");

    return ServerResponse.ok().contentType(MediaType.APPLICATION_FORM_URLENCODED)
            .body(fromObject(newFormData));
}

Here's the error I get

2020-04-07 02:37:33.329 DEBUG 38688 --- [ctor-http-nio-3] org.springframework.web.HttpLogging : [07467aa5] Resolved [UnsupportedMediaTypeException: Content type 'application/x-www-form-urlencoded' not supported for bodyType=org.springframework.util.LinkedMultiValueMap] for HTTP POST /formnew

Whats the issue here. I couldn't find any way to write the url encoded response back. Could anyone point what's the issue.

1 Answers

Try to refactor your code to functional style:

public Mono<ServerResponse> newForm(ServerRequest request) {
    Mono<DataBuffer> resultMono = request.formData()
        .map(formData -> new LinkedMultiValueMap(formData))
        .doOnNext(newFormData -> newFormData.add("status", "success"))
        .map(linkedMultiValueMap -> createBody(linkedMultiValueMap));

    return ServerResponse.ok().contentType(MediaType.APPLICATION_FORM_URLENCODED)
        .body(BodyInserters.fromDataBuffers(resultMono));


}

private DataBuffer createBody(MultiValueMap multiValueMap) {
    try {
        DefaultDataBufferFactory factory = new DefaultDataBufferFactory();
        return factory.wrap(ByteBuffer.wrap(objectMapper.writeValueAsString(multiValueMap).getBytes(StandardCharsets.UTF_8)));
    } catch (JsonProcessingException e) {
        throw new IllegalArgumentException("incorrect body");
    }
}
Related