Someone have a simple explanation about the effects the value of tag <url-pattern> in my web.xml file will have in a Spring application? I ever use *.html without problems, but if I change to / to a more wide scope, I can't reach any page from my application.
If I choose /, how should be my mapping value in my controller, and how I should link to my views in the JSP files?
First, you need to understand what the <url-pattern> mappings are. They are described in the Servlet specification, here in chapter 12.
In the Web application deployment descriptor, the following syntax is
used to define mappings:
A string beginning with a ‘/’ character and ending with a ‘/*’ suffix is used for path mapping.
A string beginning with a ‘*.’ prefix is used as an extension mapping.
The empty string ("") is a special URL pattern that exactly maps to the application's context root, i.e., requests of the form
http://host:port/<contextroot>/. In this case the path info is ’/’ and
the servlet path and context path is empty string (““).
A string containing only the ’/’ character indicates the "default" servlet of the application. In this case the servlet path is the
request URI minus the context path and the path info is null.
All other strings are used for exact matches only.
So [/...]/* is path mapping, anything prefixed with *. is extension mapping, and / is the default match.
The Servlet specification also explains in what order those are checked.
When a request arrives, the Servlet container goes through all your url-pattern elements to find a match and then calls the service(..) method of the corresponding Servlet. In our case, this is DispatcherServlet.
The DispatcherServlet then, typically, uses a RequestMappingHandlerMapping bean to figure out which handler method is the best match to handle the request. Basically it determines which #Controller #RequestMapping method to dispatch to. RequestMappingHandlerMapping has a property called useSuffixPatternMatch (which is true by default) which determines
Whether to use suffix pattern match (".") when matching patterns to
requests. If enabled a method mapped to "/users" also matches to
"/users.".
So if your servlet is mapped to
<url-pattern>*.html</url-pattern>
and the handler method is mapped
#RequestMapping(value = "/test")
then a request to /context/test.html will be handled by that method.
If I choose /, how should be my mapping value in my controller, and
how I should link to my views in the JSP files?
There are a million answers to this. It depends. Just take note of all the information above and decide for yourself.
Related
All over the Internet I find code examples of JAX-WS beans being defined in this fashion:
<jaxws:client name="{http://cxf.apache.org/}MyService" createdFromAPI="true">
What is the meaning of the curly braces here exactly?
You might need to specify individual examples of where you've seen it, but from what you've shared here, this seems to be erroneous use of that naming convention.
See, the schema for the Spring-CXF XML configuration document supports two types of "name" attributes:
name: use this to name just the bean within the spring context - treat it no differently as you would adding id to a spring bean. No need for a namespace or prefixing of any kind
serviceName: this name should come from the WSDL as part of the name attribute from the definitions root element. It's this one that uses the QName format - what you have here as {http://cxf.apache.org/}MyService which the CXF API will try to match with what's in the WSDL of the SOAP service you're consuming.
TL;DR: that naming convention with the URL prefix doesn't belong on the name attribute but on the serviceName attribute and its value ought to come from the WSDL file.
What is the best way to change path parameter (may be using interceptor) before passing it to controllers ? I am using spring mvc.
Right now, i am adding an extra parameter to get the job done, and checking for that in the controller, but i would rather change the parameter and not change anything in the controller
I stumbled across this question after reading the log of my spring boot applicaiton in debug mode.
At startup, the While the spring RequestMappingHandlerMapping is "Looking for request mappings in application context" and finds the resquest mappings defined on my controllers. Later the BeanNameUrlHandlerMapping is "Looking for URL mappings in application context" and fails to find one for every bean defined in my context (no URL paths identified)
My question is, what the difference between a request mapping and an url mapping, can someone link a documentation to read what the BeanNameUrlHandlerMapping is looking for?
RequestMappingHandlerMapping
According to the documentation, the RequestMappingHandlerMapping:
Creates RequestMappingInfo instances from type and method-level #RequestMapping annotations in #Controller classes.
A RequestMappingInfo can be instantiated with the constructor:
public RequestMappingInfo(String name,
PatternsRequestCondition patterns,
RequestMethodsRequestCondition methods,
ParamsRequestCondition params,
HeadersRequestCondition headers,
ConsumesRequestCondition consumes,
ProducesRequestCondition produces,
RequestCondition<?> custom)
and represents a request with a set of conditions to be matched.
BeanNameUrlHandlerMapping
The BeanNameUrlHandlerMapping is an:
Implementation of the HandlerMapping interface that map from URLs to beans with names that start with a slash ("/"),
and as a AbstractDetectingUrlHandlerMapping is:
detecting URL mappings for handler beans through introspection of all defined beans in the application context.
RequestMappingHandlerMapping defines all possible URLs you can process in the application. It is not necessary read the URLs from controllers annotation. The mappings could be calculated. E.g. the question provides a solution when request mappings are generated on fly from method names.
RequestMapping should be comlex with e.g. #PathParameter when mapping text is "\user\{userId}"
So step 1 kind of register all URLs we can process.
Then for each the URL we need to find a bean which actually should be invoked to process some URL (to find a method which spring should call).
I have to map different url to single controller
e.g.
/test/read
/test1/read
/test2/read
/test/submit
/test1/submit
/test2/submit
So at the class level I use #RequestMapping(values ={"/test/*", "/test1/*","/test2/*"}) and at method level #RequestMapping(read) and for other method #RequestMapping("submit").
This fails and says that read is already mapped.
By default I think RequestMappingHandlerMapping is being used.
How to do this kind of mapping please suggest.
I am new to spring framework. Even I dont have any deep concept about annotation.
I am developing a very small application using spring mvc 3 framework and also I used annotation.
I have a confusion. I have one spring-servlet.xml. Here I have not defined any handler mapping. But still it is working. So must be there some default handler mapping. Can you please let me what is this default handler mapping and how I can override it so that I do some customization.
It is all explained in: http://static.springsource.org/spring/docs/3.2.x/spring-framework-reference/html/mvc.html#mvc-config
Also see this question: How to use default-servlet-handler and Where to put default-servlet-handler in Spring MVC configuration
Spring 3.1 and later doesnt need DefaultAnnotationHandlerMapping and AnnotationMethodHandlerAdapter declaration in the [servelt-name]-servlet.xml
These links might help:
Spring Controller to handle all requests not matched by other Controllers
https://dzone.com/articles/using-the-spring-requestmapping-annotation
I had the same problem that I just resolved so I have confirmed the approach below works, although this is with annotations rather than an XML configuration.
You specify URL prefixes at the controller class level and include a request mapping annotation for ** to ensure you match on anything that falls through your other handlers for this class. There's really nothing special or default about this handler other than the fact that you're defining a handler that is guaranteed to match everything under the class level mappings.
Note: This is not magic. Your handlers are still subject to Spring's ordering algorithm regarding the "best match". It would be nice to have an annotation providing for a true default when nothing else matches handler, especially in cases with complex mappings where "**" is useful outside of this catch-all handler. The basic implementation is:
#RestController
#RequestMapping(value={"/path1/","/path2/"})
public class MyRestController {
#RequestMapping("/subpath")
String matchedRequestHandler () {
return "This matches /path1/subpath and /path2/subpath.";
}
#RequestMapping("**")
String unmatchedRequestsHandler () {
return "This matches everything else.";
}
}
In my actual use case, I needed to handle arbitrary paths to resources inside of the URL pattern and therefore needed to support a variable number of directories. Ideally, that would be handled using a pattern such as:
"/base/{optionaldir}/**/{entityName}/{describeVar:describe.json}"
which works fine by itself, but it isn't compatible with a default handler bound to "**" since the "**" mapping is calculated by Spring as a better match for these types of requests.
Instead, I had to add a bunch of separate entries to my request mapping to support the arbitrary paths within the URL pattern, e.g.
value={"/base/{optionaldir}/{entityName}/{describeVar:describe.json}",
"/base/{optionaldir}/*/{entityName}/{describeVar:describe.json}",
"/base/{optionaldir}/*/*/{entityName}/{describeVar:describe.json}",
"/base/{optionaldir}/*/*/*/{entityName}/{describeVar:describe.json}"
}
Alternatively, I could have handled everything with a "**" mapping and parsed the URL myself, but that kind of defeats the purpose of using request mappings with path variables. Hopefully Spring's capabilities will evolve in this area in the future.