RestEasy #Path Question with regular expression - java

Is it possible to define path with optional path variables.
like the uri below:
/app/make/{make}/model/{model}/year/{year}/mileage/{mileage}/fuelType/{fuelType}/maxPrice/{maxprice}/transmission/{transmission}/engineSize/{engineSize}
URI may be composed of any 0 or more combinations of the parameters? Is there a way to tell resteasy that all those paths are optional?
cheers.

Why bother using path segments? If they are optional parameters then it can't be a real hierarchy so why not just use query string parameters. They work much better for this type of parameter.

#Path("/make/{make}{model:(/model/[^/]+)?}{fuel : (/fuel/[^/]+)?}{gearbox : (/gearbox/[^/]+)?}/cars")
app/{make:(/make/[^/]+)?}{model:(/model/[^/]+)?}{year:(/year/[^/]+)?}{mileage:(/mileage/[^/]+)?}
I came up with the above workaround which works but inside the method I need to remove the pathname.

Related

custom annotation on RequestParam and PathVariable

I have created a custom annotation
annotation class UserControl(
val userIdentifier: String
)
I wan to apply this annotation on query parameters, and path variables in different controllers.
fun userWithMobile(
#UserControl("PhoneNumber")
#RequestParam mobile: String
): RegisteredUser {
return userManager.getUserWithPhoneNumber(mobile))
}
How can i check if the query parameters have the UserControl annotation or not, and do some processing on that. Is there standard way to write a global handler , or a processor for that?
Would appreciate any help
AspectJ can directly match parameter annotations, but not bind them to advice method values like class or method annotations. So if you only want to match them, a simple pointcut is enough. If you want to access the annotations and maybe their parameter values, you need a little bit of reflection magic. I have answered related questions many times already, which is why I am going to close this one as a duplicate. But first, here are the resources you want to read. They all related to your question, showing examples of how to handle different specific situations:
https://stackoverflow.com/a/38162279/1082681
https://stackoverflow.com/a/10595712/1082681
https://stackoverflow.com/a/50540489/1082681
https://stackoverflow.com/a/49872132/1082681
https://stackoverflow.com/a/61284425/1082681
https://stackoverflow.com/a/16624766/1082681
Basically, the pointcut you want the following or some variation of it:
execution(* *(.., #my.package.UserControl (*), ..))
The naive, less efficient approach without matching the parameter in the pointcut, using only relfection:
https://stackoverflow.com/a/27784714/1082681
https://stackoverflow.com/a/42561014/1082681

When is expression used in mapStruct?

I am getting started with MapStruct. I am unable to understand when do we use "expression" tag in MapStruct? Why do we have certain mappings where we use "target" tag and "expression" tag? Does it mean that expressions are used when you want to map two or more fields within a bean to a single property/field in the target as mentioned in the documentation "http://mapstruct.org/documentation/stable/reference/html/#expressions"
Expressions are used when you can't map a source - to a target property or when a constant does not apply. MapStruct envisioned that several language could be used to address expressions. However, only plain java is implemented (hence "java(... )" ). EL was envisioned but not yet realised.
A typical use case that I use is generating a UUID. But even there you could try the new #Context to achieve that goal.
Remember, the stuff within the brackets is put directly in the generated code. The IDE can't check its correctness, and you will only spot problems during compilation.
Expressions are IMHO a fallback means / gap filler for stuff that is not yet implemented in MapStruct.
Note: Mapping target-to-source by means of a custom method as suggested in the other answers can be done automatically. MapStruct will recognised the signature (return type, source type) and call your custom method. You can do this in the same interface (default method) or in a used mapper.
In general, MapStruct expressions are used when you simple cannot write a MapStruct mapper. They should be used as a fallback approach when the library doesn't apply to your use-case.
For example, -- as the documentation says -- when a mapping requires more than one source variable, an expression can be used to "inject" them to a mapper method.
Another use case is when the source variable you need to use -- say bar -- is not a part of the source class but a member of one of its variables (here, classVar). You would map it to the target field foo using a custom myCustomMethod method with #Mapping(target="foo", expression="java(myCustomMethod(source.classVar.bar)))".

Optional parameter in #PathParam annotation

We are facing issue related with making a path parameter optional.
original URL /expire/{token}
What we are trying to do is have the same service work for the URL's below.
1. /expire/{token}
2. /expire
Ex:- #Path("/expire/{token}")
We have already applied other solutions from SO,but no luck so far.
What about adding another method annotated with only:
#Path("/expire")
And let this method pass a null value into the original method.
Logically, it doesn't seem to make sense to have it optional. Your URI should handle the type of request it's supposed to do. But, I came across a post to make the #PathParam to be optional with a small hack using regular expressions.
http://www.nakov.com/blog/2009/07/15/jax-rs-path-pathparam-and-optional-parameters/
I would go with having separate endpoint method in Controller where it can pass the call to your services with optional parameter.
We can use regular expressions,
"#Path("/add/{a:([0-9.]*)}/{b:([0-9.]*)}{p:/?}{c:([0-9.]*)}")"
here path can be
add/2/3
add/2/3/4
my case I am using regular expressions for allowing only numbers

Distinguish empty value from empty string ("") in Url query parameter

How to distinguish URL without value like this /url?var from /url?var="" in Spring MVC?
Method HttpServletRequest::getParameterMap() in controller returns "" in both ways.
I need this to separate commands from queries to specified resource.
One simple way of going about doing what you want to is use the getQueryString() of HttpServletRequest. You would just check and see if the returned String contains the pattern you are looking for.
If you need something like that often (as in many controller methods) you could also easily create a custom HandlerMethodArgumentResolver that will indicate the presence of a String in the URL.
Here is the relevant Javadoc and here is an example
/url?var is a valid URL which states that you have a parameter var which is not initialized.
So by default it is initialized to empty string. That's the framework behavior.
If you don't want to see that parameter coming in HttpServletRequest::getParameterMap(), just don't use it with URL (i.e. /url should be your call)

Can I somehow create 1 annotation to replace another with default values?

I fear title is bad, but could not formulate it better. So, I have this code:
#javax.interceptor.Interceptors({EjbSecurityServerInterceptor.class,PermissionInterceptor.class})
Is there a way to create annotation like #SecuredAsHell, that will be an equivalent to aforementioned annotation? Smth like macros, I suppose.
Thanks
No. Sorry, but the fact is that whatever reflection that is used to locate annotations of type javax.interceptor.Interceptors will only locate annotations of that type. There is not way to indicate that another annotation is somehow equivalent.

Categories