Я конвертирую существующее PHP-приложение в Spring Boot 2.1.x.
Один запрос, который отправляют клиенты (и, следовательно, должен поддерживаться для обратной совместимости), - это запрос POST
с Content-Type: application/x-www-form-urlencoded
некоторые параметры запроса и полезная нагрузка в кодировке Base64.Запрос curl выглядит следующим образом: curl -H "Content-Type: application/x-www-form-urlencoded" -d "abc+123/XYZ=" http://localhost:8080/testing\?x\=\&Z\=U
Наше PHP-приложение не очень строгое и с радостью принимает этот запрос, и я легко могу декодировать заданную полезную нагрузку base64.
С помощью Spring Boot, однако,проблема в том, что он очищает входные данные, потому что они считаются входными данными из формы.Это делается в
org.springframework.http.server.ServletServerHttpRequest#getBody
- ->
org.springframework.http.server.ServletServerHttpRequest#isFormPost
- ->
org.springframework.http.server.ServletServerHttpRequest#getBodyFromServletRequestParameters
Теперь, еслиЯ отправляю запрос с Content-Type: text/plain
, весной он работает безупречно: curl -H "Content-Type: text/plain" -d "abc+123/XYZ=" http://localhost:8080/testing\?x\=\&Z\=U
Поэтому я хотел просто создать Filter
, обернуть запрос и вернуть text/plain
как Content-Type
:
@Component
@Order(Ordered.HIGHEST_PRECEDENCE)
class MyFilter : Filter {
override fun doFilter(request: ServletRequest?, response: ServletResponse?, chain: FilterChain?) {
if (request is HttpServletRequest && "application/x-www-form-urlencoded" == request.contentType && HttpMethod.POST.matches(request.method)) {
chain?.doFilter(PlainHeadersRequest(request), response)
} else {
chain?.doFilter(request, response)
}
}
}
class PlainHeadersRequest(request: HttpServletRequest?) : HttpServletRequestWrapper(request) {
override fun getContentType(): String {
return "text/plain"
}
}
Это первый фильтр в цепочке, и он работает в отношении типа контента, который теперь всегда принимается как text/plain
.
Я ожидал, что с этимфильтр, обе команды curl сверху будут работать взаимозаменяемо.
Но это не так.С фильтром я получаю:
$> curl -i -X POST -H "Content-Type: application/x-www-form-urlencoded" -d "abc+123/XYZ=" http://localhost:8080/testing\?x\=\&Z\=U
HTTP/1.1 400
Content-Type: application/json;charset=UTF-8
Transfer-Encoding: chunked
Date: Thu, 27 Jun 2019 21:57:35 GMT
Connection: close
{"timestamp":"2019-06-27T21:57:35.516+0000","status":400,"error":"Bad Request","message":"Required request body is missing: public java.lang.String com.example.demo.stuff.MyController.myMapping(java.lang.String)","path":"/testing"}%
Мои вопросы сейчас:
- Где тип контента имеет значение до первого фильтра?
- (Как это исправить без какого-либо дополнительного программного обеспечения, такого как прокси nginx, перед приложением Spring Boot? -> решено, см. Комментарий)