How do you access the RequestBody in a HandlerInterceptorAdapter? - java

I tried to pull the body out of request.getReader() but it was already read.
How can I get my hand on the requestbody within the interceptor?

As you say, the request body can only be read from the Reader once. This is not specific to interceptors, but for all users of the Servlet API.
If you need to access the body a second time, then you need to store the data somewhere, such as in a request attribute (using request.setAttribute() and request.getAttribute()).
How and where you do this depends on your interceptor, and you told us nothing about your specific case.

Related

How to change routes url based on request body in spring cloud

I want to route requests based on some values in requestBody in spring cloud, for example:
if value of firstField in requestBody is chagre, I want to route this request to /chagre api
else if value of firstField in requestBody is package, I want to route this request to /package api
Any help would be appreciated.
Best practice is not to route according to request body, but use different attributes of the HTTP request instead. Spring Cloud Gateway includes many built-in route predicate factories based on those attributes.
The problem is request body can be read only once. moreover you need to know the object class it contains in order to properly read it.
In order to construct a solution to your question, we can use Spring Cloud Gateway ModifyRequestBody to rewrite the request body after you read it and before it send to the downstream.
Read more about ModifyRequestBody

Is it possible to include a request body in a GET request using Spring WebClient?

I know sending a body with a GET request isn't the best idea but I'm trying to consume an existing API which requires it.
Sending a body with POST is straight-forward:
webClient.post()
.uri("/employees")
.body(Mono.just(empl), Employee.class)
.retrieve()
.bodyToMono(Employee.class);
It won't work with webClient.get() though, because while the post() method returns a WebClient.RequestBodyUriSpec, the get() method returns WebClient.RequestHeadersUriSpec<?>, which doesn't seem to allow any body definitions.
I've found a workaround for Spring RestTemplate here: RestTemplate get with body,
but had no luck finding any for the new WebClient.
While the other responses are correct that you shouldn't use a body with a GET request, that is not helpful when you do not own, or cannot change the already existing method you are calling.
The problems is WebClient#get returns a WebClient.RequestHeadersUriSpec which does not provide a way for us to set the body.
WebClient#post returns a WebClient.RequestBodyUriSpec which does provide us a way to set the body but will cause us to use the wrong HTTP method, POST instead of GET.
Thankfully for us stuck in this situation there is WebClient#method which returns a WebClient.RequestBodyUriSpec and allows us to set the HTTP method.
webClient.method(HttpMethod.GET)
.uri("/employees")
.body(Mono.just(empl), Employee.class)
.retrieve()
.bodyToMono(Employee.class);
You may still run into issues in your testing libraries though...
A GET reques has no body. It is forbidden (well, not forbidden, but not used at all) by the HTTP specification. You have two approaches here:
Do a POST. It is there just for that.
Use a query string and pass the data in that part of the URL.
Of course, you can attach the needed fields and pass a payload to the GET request, but it will probably be ignored, or worse, identified as an error and rejected by the server, before your served code has access to it. But if you are passing data to the server to do some processing with it, then POST is what you need to use.
Extracted from RFC-7231. HTTP 1.1. Semantics and code:
A payload within a GET request message has no defined semantics;
sending a payload body on a GET request might cause some existing
implementations to reject the request.
(markup is mine)
Reasons for this are, mainly, that a GET method must be idempotent, producing the same output for the same URL, if repeated. POST doesn't have these requirements, so POST is your friend.

Get the request body in custom filter java Play framework

I've read https://www.playframework.com/documentation/2.5.x/ScalaHttpFilters#more-powerful-filters, but I still don't understand how to access the request body inside the filter chain. I'm trying to make an accumulator but I'm not sure how to access the nextFilter in the apply method of EssentialAction. If anyone knows how to actually access the request body inside the filter chain let me know! I'm working in java
In order to parse the body of the request, you can use Action composition in your filters. You must actually stream / parse the body in the filter manually, and then let the framework parse it again as it passes to your controller.
Here is a good article on how this can be achieved.
https://www.javacodegeeks.com/2013/02/understanding-the-play-filter-api.html

Java interceptor reading request body makes the request empty

I have written an interceptor using spring that reads the request body from the HTTPServletRequest, in preHandle method. Request body contains json. I am able to read the request body also but something is happening to the request object and the request body is getting blank. And beause of this the request is becoming a bad request. Any help will be much appreciated. Thanks in advance.
I haven't used either JEE interceptors or Spring interceptors and don't know how they work.
But it sounds like the easier way would be to go with a filter (as configured from the web.xml). Since filters call each other in a chain, you could easily replace the HttpServletRequest object that is forwarded with a wrapped one (where you provide the body).
This could probably be accomplished by creating a class of your own, extending the HttpServletRequestWrapper and then override the appropriate methods (getInputStream sounds like the way to go here, yes?).
Your version of getInputStream would then return a ByteArrayInputStream of the body you already read, or whatever you kind of InputStream you feel is appropriate.

Is there a way to get post parameters from a http request in a filter but keep the input stream intact for servlet?

I am trying to fix a bug in sitebricks where it consumes the input stream in of the data of all servlets even those not using site bricks.
HiddenMethodFilter.java line:66
String methodName = httpRequest.getParameter(this.hiddenFieldName);
See http://code.google.com/p/google-sitebricks/issues/detail?id=45
Yes you can provide your own request, see Modify request parameter with servlet filter.
Furthermore may be extending the wrong sitebricks filter might be easier than chaining.
Obivously not, since the servlet container is required to read and consume the data in the InputStream before it is able to give you the request parameters. The other way around if you consume the InputStream first, the container won't have access to the request parameters later.
Why can't you fix the bug using the suggestion in the linked issue suggesting to configure the HiddenMethodFilter only for the URLs related to Site Bricks?

Categories

Resources