How to modify headers of WebMVC.fn RouterFunction response? - spring-boot

I've defined a RouterFunction bean, with handler function returning a response with string body, which is a JSON. The builder however sets the content type to text/plain on passing a string to body
ServerResponse.ok().body(responseString).build() // Content type set to text/plain
#Bean
public RouterFunction<ServerResponse> infoRouter(MyHandler myHandler) {
return nest(
path("info"),
route().GET("definitions", __ -> myHandler.getDefinitions()).build()
).filter(HandlerFilterFunction.ofResponseProcessor((serverRequest, serverResponse) ->
// TODO: Set content type header to application/json
));
}
I tried to clone the response using ServerResponse::from but it doesn't include the response body. Is there another way to do this?

Related

How to use #PostMapping and Postman to send post request and JSON Object as a request parameter

**I am trying to make a POST controller in springboot having request parameter as JSON object and hiting the controller from the postman .The problem I am facing is that I want to pass a JSONObject in the parameter itself from the postman. I am sending JSON from POSTMAN in body, basically pasted JSON object in the raw body **
#RestController
public class PostController {
#PostMapping(value="/status")
public JSONObject status (#RequestBody JSONObject jsonObject){
System.out.println(jsonObject.toString());
return jsonObject;
}
}
`
I am hitting from the postman with POST request at the url : localhost:8080/status ,,
I am not getting the appropriate response. Main problem is that the JSON object is not getting passed to the request . PLease explain.
Intellij terminal response :
{}
AT line 19
and POSTMAN response is :
{
"empty": true,
"mapType": "java.util.HashMap"
}
enter image description here

Spring Boot Content Type Error even when specified in Kotlin

I have an issue in Spring Boot with Kotlin
I have a function that accepts all major Content Types as defined below:
#PostMapping(
value = ["/users/new"],
consumes = [
MediaType.APPLICATION_JSON_VALUE,
MediaType.APPLICATION_XML_VALUE,
MediaType.MULTIPART_FORM_DATA_VALUE,
MediaType.APPLICATION_FORM_URLENCODED_VALUE]
)
fun registerNewUser(
#RequestHeader("X-Forward-For") ipAddress: String?,
newUser: NewUser,
request: HttpServletRequest
): ResponseEntity<ObjectNode> {
var realIPAddress = ipAddress
if (realIPAddress == null) {
realIPAddress = request.remoteAddr
}
return userService.registerUser(realIPAddress!!, newUser)
}
Here is how my NewUser class is defined in kotlin
data class NewUser(val email: String?, val password: String?)
Here is how I am doing the check in the registration function
if (!StringUtils.hasText(newUser.email)) {
return responseHandler.errorResponse(
HttpStatus.BAD_REQUEST,
"Please provide an email address"
)
}
Now when I sent a post request with postman and even axios I keep getting the error as shown in the screenshot below
That error message should only be displayed if email address is not provided. But as you can see clearly, the email address is provided in the JSON Payload.
What could be wrong?
Note: This works when the Content-Type is application/x-www-form-urlencoded but doesn't work when the Content-Type is application/json
put #RequestBody before newUser parameter to specify that input should be inside http body part. by default function parameters in spring are considered to be url parameters which can be further clarified with #RequestParam.
there are 2 ways to insert request parameters into http request. one is to attach request parameters to end of the url and the other is to put in http body with application/x-www-form-urlencoded as the content-type.

Fetch Request Body from org.springframework.web.reactive.function.BodyInserter

I have the below code where I am able to log the headers and URL. But the body() method is returning an object of type BodyInserter. In the debug mode(STS), we can see the request body object. Is there any way to log the request?
[private ExchangeFilterFunction logRequest() {
return ExchangeFilterFunction.ofRequestProcessor(clientRequest -> { loggingService.info(clientRequest.url());
loggingService.info(clientRequest.headers());
BodyInserter<?, ? super ClientHttpRequest> bodyInserters= clientRequest.body();
return Mono.just(clientRequest);
});
}

response with appropriate mime type requested with accept

Say I have a route:
Route::get('list',...);
If I call that route with Accept: text/html it should return a view with all the blade hoopla.
If I call that route with Accept: application/json it should return json, Accept: application/xml it will return xml.
And so on...
How do I realise that with Laravel 5.1?
You can handle Accept header using these methods of the Request class:
bool accepts(string|array $contentTypes)
If you just care about Json and HTML there is
bool acceptsJson() / bool wantsJson()
bool acceptsHtml()

Changing default header for JSON data in Gin

I've noticed that using Gin to return a response like this:
c.JSON(http.StatusOK, jsonData)
automatically creates the following header:
application/json; charset=utf-8
Is it possible to modify the header somehow to just return
application/json
I'd rather take this approach than splitting the string at the ;
Modify the source code to remove the ; charset=utf-8 string, or
Have a wrapper function which manually sets Content-Type before the gin.Context.JSON call:
func JSON(c *gin.Context, code int, obj interface{}) {
c.Header("Content-Type", "application/json")
c.JSON(code, obj)
}
// ...
JSON(c, http.StatusOK, jsonData)
You can add new headers in the request like this :
c.Request.Header.Add("x-request-id", requestID)

Resources