Spring Pageable in handler - spring

I have a handler like this:
#GetMapping("/users")
#Timed
public ResponseEntity<List<UserDTO>> getAllUsers(#ApiParam Pageable pageable) {
log.debug("REST request to get a page of Users");
Page<UserDTO> page = userService.findAll(pageable);
HttpHeaders headers = PaginationUtil.generatePaginationHttpHeaders(page, "/api/users");
return new ResponseEntity<>(page.getContent(), headers, HttpStatus.OK);
}
It was generated by JHipster. My main issue with this is that i dont understand what the front end is supposed to send to match Pageable object.
This handler will should return paginated users based on search words submitted by the user. I am using mongodb.

Based on this github issue it states
The custom pagable parameters (limit, offset) are replaced to the
Spring custom argument resolver PageableHandlerMethodArgumentResolver
You can find the code for PageableHandlerMethodArgumentResolver here. The default parameter names are "page" and "size". You might want to take a look at the jhipster-sample-app-mongodb which does look to showcase pagination. Example can be found here

Related

Spring Boot MVC - How to generate etag value of an entity programatically?

I am using Spring Boot 1.5.18 with ReactJs and I am trying to conditionally update an entity using an eTag.
I have added the following config and Spring Boot is generating the etags in the response headers.
#Bean
public Filter shallowEtagHeaderFilter() {
return new ShallowEtagHeaderFilter();
}
Now I want to check in my controller method if the etags match before updating the entity. My controller method is as follows:
#RequestMapping(method = POST, value = "/assignments/{id}/edit")
public #ResponseBody
ResponseEntity<?> editStaffAssignment(#RequestBody Resource<AssignmentDTO> dtoResource,
#PathVariable Long id,
PersistentEntityResourceAssembler resourceAssembler, Pageable pageable) {
Assignment assignment = assignHandler.updateAssignment(dtoResource.getContent(), id);
return new ResponseEntity<>(resourceAssembler.toResource(assignment), HttpStatus.OK);
}
I have included the etag header in the Axios request from the reactjs client and I can extract it in the controller method but how do I generate the current etag value on the server side programatically?
The ShallowEtagHeaderFilter calculates the ETag value based on the serialized response body, so it's not easily possible to calculate it upfront (i.e. before the response body is actually sent).
If I understand you correctly you want to employ an optimistic locking mechanism. If that's the case I'd suggest to drop the ShallowEtagHeaderFilter and instead calculate the ETag manually in the first place, like this:
String etag = calculateETag(); // TODO
return ResponseEntity.ok()
.eTag(etag)
.body(resourceAssembler.toResource(assignment));
If using JPA you could re-use the #Version field as an ETag value here.

Caching with Pagination on Spring Boot

I have an endpoint which fetches data from the database returns huge number of records. All of this records needs to be visible on the UI but as we scroll the view.
These records are used in 2 ways, one is displaying as it is another is displaying subset of the records based on some filter (through same/another endpoint).
Any suggestions on how this can be achieved using Spring features or without ?
You can achieve this using pageable. Sample controller code for pageable
#PostMapping
#ResponseStatus(HttpStatus.OK)
public Page<AllInventoryTransactions> fetchAllInwardInventory(#PageableDefault(page = 0, size = 10, sort = "created", direction = Direction.DESC) Pageable pageable) throws Exception
{
return allInventoryService.fetchAllInventory(pageable);
}
You can pass this pageable received from UI directly to Repo. Below is the service method
public Page<AllInventoryTransactions> fetchAllInventory(FilterDataList filterDataList, Pageable pageable) throws ParseException
{
Page<AllInventoryTransactions> data = allInventoryRepo.findAll(spec,pageable);
allInventoryReturnData.setTransactions(data);
return data;
}
in UI, you can handle logic to make next API call as user scrolls the page

What's the reason to use ResponseEntity<?> return type instead of simple ResponseEntity in Spring Controller?

I've seen a lot of examples of Spring Controllers implementation that use ResponseEntity<?> in order to return HTTP response that have a specific status code and optional body.
ResponseEntity<?> notation is present even in official Spring tutorials like the following one: Building REST services with Spring
What's the reason to use ResponseEntity<?> instead of simple ResponseEntity?
It's a little bit related to my previous question: SonarQube complains about using ResponseEntity with a wildcard
There is some explanation in What is a raw type and why shouldn't we use it? thread, but I'd like to pay more attention to ResponseEntity class and it's use in Spring Controllers.
Consider the following snippet of code where somethingService returns an Optional of Something class:
#GetMapping
ResponseEntity<?> getSomething() {
return somethingService.getSomething()
.map(smth -> new ResponseEntity<>(smth, HttpStatus.OK))
.orElse(new ResponseEntity<>(HttpStatus.NOT_FOUND));
}
Is there any reason to leave a wildcard even if I don't get any profit from compiler checks since ResponseEntity(HttpStatus status) parametrises ResponseEntity with Object class?

Spring URL mapping conflicts

At the moment I am bussy with implementing a new url structure for our webshop. The new url structure should be more optimized for search engines. We also want that our old structure will still be working and will use a 301 to redirect to a the new structure.
The problem is: the new structure sometimes conflicts with the old urls.
Example of the old url mapping:
#RequestMapping(value = "/brand/{categoryCode}/{categoryName}/{brandGroup}.do", method = RequestMethod.GET)
New structure:
#RequestMapping(value = "/brand/{brandGroup}/{superCategoryName}/{categoryName}.do", method = RequestMethod.GET)
As you can see the url's have the same amount of values, so the old mapping will catch the new one and vice versa.
What is the best way to fix this? Using a url filter to rewrite the old ones to the new url structure?
You could use an URL router in Spring MVC; you can define conflicting routes within your app and handle them with route prorities (first route to match the request wins) and refine request matching.
Your routes configuration file could look like:
GET /brand/{<[0-9]+>categoryCode}/{categoryName}/{brandGroup}.do oldcontroller.oldAction
GET /brand/{<[a-zA-Z]+>brandGroup}/{superCategoryName}/{categoryName}.do newController.newAction
In spring boot, regular expressions can be used when mapping the #PathVariable, and this can be useful to resolve url conflicts:
#RestController
public class TestController {
#PutMapping("/test/{id:^[1-9][0-9]*}") // id must be a number greater that 1
public void method1(#PathVariable long id, #RequestBody DataDto1 data) {
}
#PutMapping("/test/foo")
public void method1(#Valid #RequestBody DataDto2 data) {
}
}

Mapping same URL to different controllers in spring based on query parameter

I'm using spring annotation based controller. I want my URL /user/messages to map to some controller a if query parameter tag is present otherwise to some different controller b. This is required because when parameter tag is present then some more parameters can be present along with that which i want to handle in different controller to keep the implementation clean.Is there any way to do this in spring. Also is there any other elegant solution to this problem ?
You can use the params attribute of the #RequestMapping annotation to select an controller method depending on Http parameters.
See this example:
#RequestMapping(params = "form", method = RequestMethod.GET)
public ModelAndView createForm() {
...
}
#RequestMapping(method = RequestMethod.GET)
public ModelAndView list() {
...
}
It is a REST style like Spring ROO uses: if the request contains the parameter forms then the createForm handler is used, if not the list method is used.
If you want to go the Spring route, you can checkout the HandlerInterceptor mentioned here. The Interceptor can take a look at your query param and redirect the link to something else that can be caught by another SimpleUrlMapper.
The other way is to send it to a single controller and let the controller forward to another action if the query parameter is "b".

Resources