RequestMapping in spring with weird patterns - spring

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.

Related

Spring #RequestMapping value annotations

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)

Unable to exclude URL's in the servlet mapping in Spring MVC

I have a controller in Spring MVC 3.2 which I want to allow the follow url's:
http://localhost:8080/mypage
http://localhost:8080/mypage/
http://localhost:8080/mypage/foo
I want to exclude anything else i.e. http://localhost:8080/mypage/bar should result in an error. Currently bar gets mapped to the getStuff method.
I assume I must be able to accomplish this without using a filter?
My servlet mapping looks like this:
<servlet-mapping>
<servlet-name>MyServlet</servlet-name>
<url-pattern>/mypage/*</url-pattern>
</servlet-mapping>
The controller request mapping:
#RequestMapping(method = RequestMethod.GET)
public String getView(HttpServletRequest request, #ModelAttribute("myform") final MyForm form) {
return "myview";
}
#ResponseBody
#Produces(MediaType.APPLICATION_JSON)
#Consumes(MediaType.APPLICATION_JSON)
#POST
#RequestMapping(value = "/save")
public String onSave(#RequestBody MyForm form, HttpServletRequest request, HttpServletResponse response) {
return "saved";
}
You have to use the Spring MVC filters called Interceptors.
If you write your own Interceptor you have two options as below:
1. option:
Use the postHandle() method to check your conditions. If you use the postHandle() method you have access to the ModelAndView and if your url doesn't match with one of your 3 url's you just can throw an Exception or change the ModelAndView.
2. option:
Use the preHandle() method, check the url's and if they don't match throw a ModelAndViewDefiningException with a new ModelAndView() like this:
ModelAndViewDefiningException(new ModelAndView("errorPage"))
The <url-pattern> Tag of servlet does not support exclusions. This is a limitation of the Servlet specification.
You have to create this functionality programmatically in a filter.

Spring MVC #PathVariable to catch only first level

I have a Spring Boot app that includes some controllers and static resources. I need to be able to have a controller that matches:
/hello
and
/hello/
but not
/wonder/hello
(or anything else). It seems that when I use the following mapping:
#RequestMapping(value = "/{slug}", method = RequestMethod.GET)
public String mapping(#PathVariable("slug") String slug)
it does a "catch-all" whereas I only need it to catch the first level. This causes issues with the static resource mapping.
use #RequestMapping("/hello") in the starting of controller

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.

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