Как получить многочастные или полезные данные по GET-запросу в Spring Web-Flux Controller - PullRequest
0 голосов
/ 14 марта 2020

В настоящее время мы переписываем некоторые устаревшие сервисы для Spring Framework с Web-Flux. Поскольку устаревшая логика c позволяет получать полезную нагрузку или составные данные по запросу GET, нам необходимо воссоздать это поведение в нашем новом сервисе.

Веб-поток не позволяет нам получать полезную нагрузку или составные данные в случае Получить запрос. Я проверял это поведение в @RestController и @Controller. Можно ли изменить конфигурацию для веб-потока, чтобы иметь возможность обрабатывать такие случаи?

Пример UploadFileController:

@Controller
public class UploadController {

    @GetMapping(value = "/upload")
    public @ResponseBody Mono<ResponseEntity<String>> upload(@RequestBody Flux<Part> parts) {
        System.out.println("Upload controller was invoked");
        return parts.next()
            .flatMap(part -> DataBufferUtils.join(part.content()))
            .map(this::mapDataBufferToByteArray)
            .map(data -> {
                String uploadedData = new String(data);
                System.out.println("Uploaded file data: " + uploadedData);
                return ResponseEntity.ok(uploadedData);
            });
    }

    private byte[] mapDataBufferToByteArray(DataBuffer buffer) {
        byte[] data = new byte[buffer.readableByteCount()];
        buffer.read(data);
        return data;
    }
}

public class UploadControllerTest {

    @Autowired
    private TestRestTemplate testRestTemplate;

    @Test
    public void shouldUpload() {
        // given
        final HttpHeaders httpHeaders = new HttpHeaders();
        httpHeaders.setContentType(MediaType.MULTIPART_FORM_DATA);

        LinkedMultiValueMap<String, Object> parameters = new 
        LinkedMultiValueMap<>();
        parameters.add("file", "Test");

        // when
        ResponseEntity<String> response = 
        testRestTemplate.exchange("/upload",
                HttpMethod.GET,
                new HttpEntity<>(parameters, httpHeaders),
                String.class);

        assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK);
    }
}

1 Ответ

2 голосов
/ 15 марта 2020

Как насчет создания веб-фильтра, который преобразует входящие запросы на получение сообщений внутри себя

@RestController
public static class GetPostHandler {
    @PostMapping("/test")
    public Flux<String> getName(@RequestPart("test") String test, @RequestPart("test2") String test2) {
      return Flux.just(test,test2);
    }
}


@Component
public class GetPostFilter implements WebFilter {
    @Override
    public Mono<Void> filter(ServerWebExchange serverWebExchange,
                             WebFilterChain webFilterChain) {
        ServerHttpRequest req = serverWebExchange.getRequest().mutate().method(HttpMethod.POST).build();

        return webFilterChain.filter( serverWebExchange.mutate().request(req).build());
    }
}

Я протестировал

curl -X GET \
  http://localhost:8080/test \
  -H 'cache-control: no-cache' \
  -H 'content-type: multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW' \
  -F test=1 \
  -F test2=2

и результат правильный:

12

...