Spring #RequestMapping value annotations - spring

I want to learn that is there any difference between #RequestMapping(/home) and #RequestMapping(value="/home")
Thanks,

As per Spring , both are same. The first one is used when only one url maps to a path.
#RequestMapping("/home") will map the urls:
<hostname>:<port>/home to the class or method on which the annotation has been applied.
The second one is used when you have more urls to map to same path.
#RequestMapping(value="/home") will do the same as first one. but
#RequestMapping(value = {
"/home",
"/someotherurl",
"/moreUrl"
})
will map the following url:
<hostname>:<port>/home
<hostname>:<port>/someotherurl
<hostname>:<port>/moreUrl
to the method or class on top of which the annotation is applied.
Refer: https://dzone.com/articles/using-the-spring-requestmapping-annotation for more details.

Assuming you mean #RequestMapping("/home") not #RequestMapping(/home) then no, there is no difference.
For annotations with a property named value this is also assumed to be the default and can be passed into the annotation definition without reference to value=. However, this is only valid if you want to define a single property. Otherwise the value= is required.
e.g.:
#RequestMapping(value = "/home", method = RequestMethod.GET)

Related

javax regex validation of path variables in Spring

I have validation working for the beans and request parameters, however, my path variables fail to get validated:
#PathVariable #Pattern(regexp = "[A-Za-z0-9]+") String protocol
When I provide path var as ab!ab it doesn't fail the request with 400 status code but lets it pass with the value assigned to the argument.
I have also validated my regex online and it is valid and should be working fine.
Also, my rest controller does have #Validated annotation.
What am I missing here?
================UPDATE=============
I have tried other constraint annotations and none of them work, so it must something to do with the path variable validation. But what??
Make sure you have
hibernate-validator
dependency and add following bean:
#Bean
public MethodValidationPostProcessor methodValidationPostProcessor() {
return new MethodValidationPostProcessor();
}

Automatically document #PathVariable annotated parameters within #ModelAttribute annotated methods

In our REST-API we need to be multi-tenant capable. For achiving this all rest controllers subclass a common REST controller which defines a request mapping prefix and exposes a model attribute as follows
#RequestMapping(path = "/{tenantKey}/api")
public class ApiController {
#ModelAttribute
public Tenant getTenant(#PathVariable("tenantKey") String tenantKey) {
return repository.findByTenantKey(tenantKey);
}
}
Derived controllers make use of the model attributes in their request mapping methods:
#RestController
public class FooController extends ApiController {
#RequestMapping(value = "/foo", method = GET)
public List<Foo> getFoo(#ApiIgnore #ModelAttribute Tenant tenant) {
return service.getFoos(tenant);
}
}
This endpoint gets well documented in the swagger-ui. I get an endpoint documented with a GET mapping for path /{tenantKey}/api/foo.
My issue is, that the {tenantKey} path variable is not documented in swagger-ui as parameter. The parameters section in swagger is not rendered at all. If I add a String parameter to controller method, annotating it with #PathVariable("tenantKey) everything is fine, but I don't want a tenantKey parameter in my controller method, since the resolved tenant is already available as model attribute.
So my question is: Is there a way do get the #PathVariable from the #ModelAttriute annotated method in ApiController documented within swagger-ui in this setup?
Project-Setup is
Spring-Boot (1.4.2)
springfox-swagger2 (2.6.1)
springfox-swagger-ui (2.6.1)
This is certainly possible. Model attributes on methods are not supported currently. Instead, you could take the following approach.
Mark the getTenant method with an #ApiIgnore (not sure if it gets treated as a request mapping.)
In your docket you can add tenantKey global path variable (to all end points). Since this is a multi-tenant app it's assuming this applies to all endpoints.

Spring rest use of pathVariable and RequestParam

With spring rest is there any reason to use request param?
For a search i don't know if i shoud use
#RequestMapping(value = "/lodgers/{searchParam}", method = RequestMethod.GET)
public Lodger getAllLogders(#PathVariable("searchParam") String searchParam)
or
#RequestMapping(value = "/lodgers/", method = RequestMethod.GET)
public Lodger getAllLogders(String searchParam)
As I use it, a path (pathVariables) points to a resource.
A queryParam (requestParam) results in a subset of a resource.
If you want certain users from /Users (e.g. beginning with "A", or lodgers named "Curt") this would be a subset, of all /Users and I see not a very good reason for having a special resource with that criteria, so I would use a queryParam here.

RequestMapping in spring with weird patterns

I have defined the controller method in spring like following
#RequestMapping(value = "/register", method = RequestMethod.GET)
public ModelAndView register(HttpSession session) {
and when i try to access the register page it is working fine.
localhost:8080/myapp/register
but the issue is it is giving me the same page with all these patterns
localhost:8080/myapp/register.htm
localhost:8080/myapp/register.abc
localhost:8080/myapp/register.pqrasdfdadf
i want to stop this behaviour. can anyone suggest ?
Depending on how you do your Web MVC configuration, you have to set the RequestMappingHandlerMapping useSuffixPatternMatch property to false.
If you're doing your configuration through a WebMvcConfigurationSupport sub class, simply do
#Override
public RequestMappingHandlerMapping requestMappingHandlerMapping() {
RequestMappingHandlerMapping mapping = super.requestMappingHandlerMapping();
mapping.setUseSuffixPatternMatch(false);
return mapping;
}
With XML configuration, you'll need to explicitly declare a RequestMappingHandlerMapping with id requestMappingHandlerMapping and set the corresponding <property>.
This property, which is true by default, determines
Whether to use suffix pattern match (".*") when matching patterns to
requests. If enabled a method mapped to "/users" also matches to
"/users.*".
I think if you use #RequestMapping(value = "/register/", method = RequestMethod.GET) , you can easily solve your problem.
Another Solution:
Use regular expression.
#RequestMapping(value = "{varName:/register$}")
Here $ represents the end of the string.

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