Representing multiple ordering through Spring #RequestParam - java

My Application currently serves requests for data, and can order the data to the users requirements, using RequestParams
#RequestParam(value = "orderBy", required = false, defaultValue = "severity") String orderBy,
#RequestParam(value = "order", required = false, defaultValue = "desc") String order,
You get the idea.
However, I want to implement multi sorting, (ordering by severity, then matching severities are ordered by date). Code wise, this is easy (google-collections to the rescue), but how would I expose this to the user calling the service?
Ideally, I wouldn't want multiple orderBy #RequestParams (orderBy2, orderBy3, orderBy4) , as that's just plain ugly.
Thoughts?
Cheers

Usually you should be able to just turn your request param into an array like:
#RequestParam(value = "orderBy", required = false, defaultValue = "severity") String[] orderBy,
#RequestParam(value = "order", required = false, defaultValue = "desc") String[] order,

Related

Methods of adding many (unspecified number) objects form database via Rest service

I'm trying to write my own app. It should provide adding food products with parameters, what I was already done , further aim is to sum all property form added products, compare with daily balance, etc.
I have a problem with concept of connecting products to a meal. Im wondering if is some pretty alternative to function with specific number of (optional) parameters, witch is a certain limitation of functionality. Here is a makeshift solution, but I don't like it, so I'm not developing it for now. Is there a better way to do this?
#RequestMapping("/add")
public Integer adding(#RequestParam("i") Long index,
#RequestParam("i2") Long index2,
#RequestParam(value="i3", required = false, defaultValue = "0") Long index3,
#RequestParam(value="i4", required = false, defaultValue = "0") Long index4,
#RequestParam(value="i5", required = false, defaultValue = "0") Long index5,
#RequestParam(value="i6", required = false, defaultValue = "0") Long index6
){
Integer sum = null;
Integer i1 = productManager.findById(index).get().getCalories();
Products second = productManager.findById(index2).get();
Integer i2 = second.getCalories();
Integer i3,a,b,c;
if (index3==0){
i3=0;
} else {
Products thrid = productManager.findById(index3).get();
i3 = thrid.getCalories();
}
sum= i1+i2+i3;
return sum;
}
You can use list as query param.
#RequestMapping("/add")
public Integer adding(#RequestParam("index") List<Long> indicies){...}
The URL will be the following: http://yourhost:port/add?index=1&index=2&index=3
I suggest to use better name to method and url param then add. Maybe sumCalories or something like that.
If you use RDBMS to persist your products (can you give me more detail please?), you can write a query to sum the requiered value:
#Query("select sum(p.calorie) from Products p where p.id in :ids")
Long sumCaloriesByIds(#Param("ids") List<Long> ids);

Set default sort order in Pageable request

I want to use this code with specification-arg-resolver with #PageableDefault(sort = "createdAt", direction = Sort.Direction.DESC) in order to implement search and to set sort order but it's not working. I tried this:
#GetMapping("find")
public Page<PaymentTransactionsDTO> getAllBySpecification(
#PageableDefault(sort = "createdAt", direction = Sort.Direction.DESC)
#And({
#Spec(path = "unique_id", spec = LikeIgnoreCase.class)
}) Specification<PaymentTransactions> specification,
Pageable pageable
) {
return transactionService.getAllBySpecification(specification, pageable));
}
Do you know how I can set the sort order with annotations into the above code>
I don't know the library but I strongly expect the #DefaultPageable annotation needs to go on the Pageable argument.

Map dynamic field names while deserializing a JSON to a Java object

I have an interesting problem that I want to solve. This is while I am parsing a response from one of the platforms that we interact with. The response changes based on the User.
Say for User A, I have the following JSON :
{
"userId": "AA001",
"AA001_Name": "Username",
"AA001_Email": "user#gmail.com",
"AA001_Phone": "000-000-0000"
}
For User B, I have :
{
"userId" : "AA002",
"AA002_Name" : "Username",
"AA002_Email" : "user#gmail.com",
"AA002_Phone" : "000-000-0000"
}
Now, while deserializing, I want to map both of them to the following object, ignoring the field name the json came with :
class User {
private String userId,
private String name,
private String email,
private String phone
}
It is easy to map the userId, as that's the field in the JSON as well, but what about the custom fields?
Now, I can't use the #JsonProperty as the name of the field is dynamically changing based on the user.
Is there any way this could be accomplished?
Please note that I might have several such custom objects like Department, Organization etc, and the platform returns the data in such a manner, meaning the keys have the user-specific information appended.
Any help is appreciated. I am badly stuck at this.
I think you can't do any better than using #JsonCreator:
class User {
private String userId;
private String name;
private String email;
private String phone;
#JsonCreator
public User(Map<String, Object> map) {
this.userId = (String) map.get("userId");
map.entrySet().stream()
.filter(e -> e.getKey().endsWith("_Name"))
.findFirst()
.ifPresent(e -> this.name = (String) e.getValue());
// repeat for other fields
}
// getters & setters (if needed)
}
You can change the stream by a traditional for each on the map's entry set to optimize performance-wise.
You can't use #JSONProperty as is, but what if you reformatted the keys before deserializing the JSON? I.E
String key = "AA001_Name"
String[] key = key.split("_")
key[0] = "AA001"
key[1] = "Name"
//Use key[1] as the new field name
Do this for each key, create a new JSON Object with the correct field names, then deserialize it.

How to set default value to get array parameter in Spring MVC

I have a search method and it has keywords parameter. What I want to do is set a default value(empty String array) to keywords parameter. Is there any way to do this?
#GetMapping(value = "search")
public List<Integer> search(#RequestParam String[] keywords){
return calculate(Arrays.asList(keyword));
}
#RequestParam has an attribute defaultValue to set default value.
public List<Integer> search(#RequestParam(defaultValue="default value") String[] keywords){
return calculate(Arrays.asList(keyword));
}
Try to use below:
#RequestParam(value="keywords[]", required=false) String[] keywords
or
#RequestParam(value=" ", required=false) String[] keywords

Spring #PageableDefault default direction changes after passing sort

Given I have this argument in my #RestController GET method:
#PageableDefault(size = 20, sort = "updated_at", direction = Direction.DESC)
When I GET without specifying sort then everything is fine: sort == update_at and direction == DESC.
But when I GET ...?page=1&size=33&sort=asdasd it ignores default direction and sets it to ASC.
Did not get any results of this being a bug. Is it not ?
#PageableDefault() has defaut direction ASC value, you can add as following
#SortDefault.SortDefaults({
#SortDefault(sort = "name", direction = Sort.Direction.DESC)
})
So the request controller look like
public ResponseEntity<Page<Brand>> findAll(
#PageableDefault(sort = { "name", "displayOrder" }, value = 10)
#SortDefault.SortDefaults({
#SortDefault(sort = "name", direction = Sort.Direction.DESC) })
Pageable pageable) {
Page<Brand> brandPage = brandService.findAll(pageable);
}

Categories

Resources