PUT: PathVariable и RequestParam не работают вместе

Я использую Spring boot 2.1.3-RELEASE. В моем RestController я пытаюсь настроить метод PUT с одной PathVariable и RequestParam (application/x-www-form-urlencoded). Однако, когда я называю это, ответ является неверным запросом, потому что требуемый RequestParam отсутствует.

Я попытался изменить PutMapping на RequestMapping, поменять местами параметры и использовать синтаксис @RequestParam(value="param2", required=false), но ничего не меняется.

Любопытно, что использование PostMapping работает. Также работает удаление PathVariable.

Вот код RestController:

@PutMapping(value = "/myurl/{param1}", consumes=MediaType.APPLICATION_FORM_URLENCODED_VALUE)
public String myMethod( @PathVariable("param1") Integer param1, @RequestParam("param2") String param2);

Я вызываю метод следующим образом:

curl -X PUT \
  http://localhost:8080/myurl/42 \
  -H 'Accept: application/json' \
  -H 'Content-Type: application/x-www-form-urlencoded' \
  -d 'param2=myparam2value'

Ответ:

{ "timestamp": 1553613278534, "status": 400, "error": "Bad Request", "message": "Required String parameter 'param2' is not present", "path": "/myurl/42" }

Я ожидаю, что PUT работает так же, как POST, но, похоже, это не так.

К сожалению, я не могу отправлять параметры как QueryParam, поэтому я должен поддерживать тот же вызов запроса, потому что я рефакторинг существующей конечной точки, которая работает именно таким образом.

Спасибо


РЕДАКТИРОВАТЬ

Я обнаружил, что это вызвано использованием HandlerInterceptorAdapter (через WebMvcConfigurer). Почему-то около

org.springframework.web.util.ContentCachingRequestWrapper.getParameterValues

org.apache.coyote.Request.parameters не имеет содержимого, и возникает исключение, поэтому он работает только для POST, а не для PUT (GET обрабатываются по-разному).

Я ценю, если кто-то может предложить, можно ли сообщить об этом как об ошибке, учитывая, что удаление перехватчика заставило его работать.

С уважением

некоторые.конечная точка/api/v1/пользователи{id}?selector = {foo} -- id -> PathParam и foo -> RequestParam. Я предполагаю, что вы объединяете «RequestParam» с «телом HTTP-запроса». Если ваш «param2» является телом запроса, удалите аннотацию @RequestParam.
Not a JD 26.03.2019 16:20

Можете попробовать это: curl -X PUT \ локальный: 8080/myurl/42?param2=myparam2value \ -H 'Принять: application/json' \ -H 'Content-Type: application/x-www-form-urlencoded' \

Logan Wlv 26.03.2019 16:25

Параметры входят в тело запроса, а не в файл param.

Roman C 26.03.2019 16:26

Спасибо, @Logan Wlv. К сожалению, мне нужно поддерживать то же соглашение о вызовах, потому что я рефакторинг существующей конечной точки.

Dave 26.03.2019 17:06
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
4
4
3 543
1

Ответы 1

Используйте -G вместе с --data-urlencode:

curl -G -X PUT \
  http://localhost:8080/myurl/42 \
  -H 'Accept: application/json' \
  -H 'Content-Type: application/x-www-form-urlencoded' \
  --data-urlencode 'param2=myparam2value'

Из документация:

-G, --get

When used, this option will make all data specified with -d, --data, --data-binary or --data-urlencode to be used in an HTTP GET request instead of the POST request that otherwise would be used. The data will be appended to the URL with a ? separator. [...]

--data-urlencode <data>

(HTTP) This posts data, similar to the other -d, --data options with the exception that this performs URL-encoding. [...]

можете ли вы объяснить, почему его пример работает с @PostMapping?

Logan Wlv 26.03.2019 16:27

Вам нужно просто прочитать документацию для опции -G: При использовании этой опции все данные, указанные с помощью -d, --data, --data-binary или --data-urlencode, будут использоваться в запросе HTTP GET вместо запроса POST, который в противном случае использовался бы. Данные будут добавлены к URL-адресу с помощью '?' разделитель.

nullptr 26.03.2019 16:37

Спасибо за ваш ответ. К сожалению, я рефакторинг устаревшей конечной точки, поэтому я не могу изменить вызов. По моему скромному мнению, мне кажется, что это ошибка загрузки Spring.

Dave 26.03.2019 16:59

Другие вопросы по теме