How to get time zone from user request in Spring Weblux - java

In non-Reactive spring we can get Time zone from request in that way -
RequestContext.getTimeZone(request)
Is there any way to get time zone from ServerRequest, using Spring WebFlux ?

you can use ServerRequest.headers() which return a Headers object, from which you can call the first method passing the "Accept-Language" or "Timezone" header name, and get the timezone.
public Mono<String> getTimezone(ServerRequest request) {
return request.headers().header("Accept-Language").next().map(timezone -> timezone);
}

Related

Why Spring Boot Microservice has the parameter Principal with null value, and how to get the actual value that the client application has?

In Spring Boot, I have the following microservice, which needs the Principal object, in order to access logged in user info:
#RequestMapping(value="/circular-save")
public Boolean saveCircularView(HttpServletRequest request, Principal principal, HttpSession session, Locale locale, ModelAndView mav,
#ModelAttribute CircularsBean souqBean) {
System.out.println( "circular-save microservice Called...........principal="+principal);
//some user related code here that depends on principal
}
Output:
circular-save microservice Called.....................principal=null
I call the above microservice as the following:
System.out.println("Will call circulars with principal:"+principal.getName());
restTemplate.getForObject("http://localhost:8081/circular-save", Boolean.class);
Output:
Will call circulars with principal:travelling.salesman
As you can see, the principal value is not null on the client side, but it is null on the server side. How to correctly have this principal object passed between microservices?
My research:
At first, I was considering passing it in json request and using POST method, but I failed because it's not a POJO and it will not be possible to serialize it.
I did more research, and found this line that could be written on the server side.
principal = SecurityContextHolder.getContext().getAuthentication();
Unfortunately, the above solution gave me different object that resulted in having anonymous user that is different that the original user.
I would appreciate any help. Thanks.

How to correctly pass a formatted datetime into a HTTP request?

I was tasked with writing a test for a REST service by calling its endpoint with an HTTP request. One part of the HTTP request should be a date (to filter only items modified after that date). The problem is, that I cannot seem to properly pass the date into the HTTP request.
This is how the endpoint is defined in the Rest Controller:
#GetMapping("/{resourceType}/{application}")
public Map<String, Map<String, Map<String, Map<String, String>>>> findByTypeAndApplication(#PathVariable("resourceType") ResourceType type,
#PathVariable("application") String application,
#RequestParam(name = "modifiedAfter", required = false) #DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") Date modifiedAfter)
It is the "modifiedAfter" parameter that is giving me trouble. Trying to pass a date formatted according to the "pattern" does not appear to work for me. After parsing into URL, the request would look like this:
http://.../LANGTEXT/INTEGRATION-EXCEL-TEST?modifiedAfter=2019-06-11%2021%3A28%3A44
I also tried restassured.given to build the requests. I tried to pass the parameter in the address itself, as a param(), as a queryParam(), and as a formParam(). I tried to pass it both as a formatted string (as per the pattern), and as a Date object. Nothing seems to work.
I cannot change the controller itself (including the date format), so I need to properly pass the date in the HTTP request.
I'd be grateful for any advice.
Thanks, Petr
On server side, spring does this automatically. You don't need specify date pattern.

Using Spring #RestController to handle HTTP GET with ZonedDateTime parameters

I'm creating an endpoint that will receive dates to do some filtering in the server side. The code looks like this:
#RequestMapping(
value = "/test",
method = RequestMethod.GET,
produces = {MediaType.APPLICATION_JSON_VALUE, MediaType.APPLICATION_XML_VALUE}
)
#ResponseStatus(HttpStatus.OK)
public TestSummaryModel getTestSummaryByDate(
#RequestParam ZonedDateTime start,
#RequestParam ZonedDateTime end) {
return testService.getTestBetween(start, end);
}
When I try to invoke my endpoint I get an HTTP 400 error "The request sent by the client was syntactically incorrect."
I have try different date formats but none of them worked. Am I missing something? I read about the #DateTimeFormat but even though I added it, was not working.
#RequestParam #DateTimeFormat(pattern = "dd-MM-yyyy") ZonedDateTime start
This is an example of the request I'm doing:
http://host/test-api/v1/test-summary/test?start=09-09-2015&end=09-09-2015
Thanks!
#DateTimeFormat is what you need. Spring MVC 4 has the appropriate converters for ZonedDateTime.
However, you need to provide an appropriate pattern and send an appropriate value.
The information provided in a date formatted as dd-MM-yyyy is not enough to produce a ZonedDateTime.
Try
#RequestParam("start") #DateTimeFormat(iso = ISO.DATE_TIME) ZonedDateTime start
and send
...?start=2014-04-23T04:30:45.123Z
Alternatively, use a date type that doesn't need zone or time information and provide an appropriate date format to #DateTimeFormat.

How to configure locale based date format support in spring

Does someone had this problem:
I need to configure spring to recognize locale based date and number format, i.e. the following user behavior should be valid:
User select language to EN, then the number format 1.23 should be valid, spring mvc will accept this format and no valid error triggered. User can also change the date with date format MM/dd/yyyy and no valid error raised, user can post this form.
User select language to DE, then the number format 1,23 should bevalid, spring mvc will accept this format and no valid error triggered. User can also change the date with date format dd.MM.yyyy and no valid error triggerd. User can post this form.
I'v tried to use #DateTimeFormat(pattern="#{messageSource['date_format']}"),(I have date_format defined in messages_(locale).properties) but seems spring doesn't support this yet, see JIRA ISSUE
Does someone has the similar problem and got a solution.
Does it help to write my own converter, and register it in org.springframework.format.support.FormattingConversionServiceFactoryBean? I need some kind of request based converter
Since nobody answers my question, I just post one of my solution to solve this problem, it could help others:
I had a request scoped bean, which resolves locale using: RequestContextUtils.getLocale(request); request can be autowired to the request scoped class(NOTICE, it works only with field injection, not with construction or setter). In this class I get locale based date/number format.
In my controller (we have actually a abstractController). I have code like this:
#InitBinder
public void initBinder(WebDataBinder binder) {
binder.registerCustomEditor(Date.class, new LocalizedDateEditor(formatHelper));
}
formatHelper is the request scoped bean. LocalizedDateEditor looks like this:
public class LocalizedDateEditor extends CustomDateEditor {
public LocalizedDateEditor(FormatHelper formatHelper) {
super(new SimpleDateFormat(formatHelper.getDefaultDateFormat()), true);
}
}
It just tell spring to use my dateFormat.
That's all.

How to add a parameter at the end of a restFul service URL?

I am trying to add a parameter at the end of the restFul web service URL.
USING Spring3
#RequestMapping(value="/searchForXmlFormat/{lastName}*?format=xml"* ,headers="Accept=application/atom+xml",method=RequestMethod.GET)
I want to get something like this:
rest/name/abcd?format=xml
or
rest/name/abcd?format=json.
I have the codes to get the data in JSON /XML format. I need to figure out how to add the ?format=xml or ?format=json at the end.
Why doesn't the recipient of your request just check what data format you're accepting from your request headers?
Otherwise, I guess you could specify them as query parameters, but this is totally dependant on what language and frameworks you're using.
If you use JAX-RS, I think what you're looking for is the annotation QueryParam. Here's an example that may fit your case:
#GET
#Produces( { MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON } )
public String doGet(#QueryParam("format") String fmt) {
//...
}
With the code above the fmt will contain the value of the parameter format in your URL rest/name/abcd?format=...

Categories