Trouble with url-pattern in web.xml - java

My filter mapping in web.xml is as follows:
<filter>
<filter-name>LoginCheckFilter</filter-name>
<filter-class>com.tutorial.filter.LoginCheckFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>LoginCheckFilter</filter-name>
<url-pattern>/admin*</url-pattern>
</filter-mapping>
When I run my app and hit http://localhost:8080/admin my filter is not getting executed. I'm not able to understand why.
Is there any problem with the pattern. Also If I remove '*' from the pattern then the filter is getting executed on hitting above url.
Need help on this. Thanks.

The specifications (paragraph 12.2) says the following:
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 the * is taken literally, unless the pattern ends with /* or starts with *.

Use /admin/* instead of /admin*.
Servlet container will not recognize /admin* as correct URL pattern.

Maybe try:
<url-pattern>/admin/*</url-pattern>

Related

How to use #WebServlet to accept arguments (in a RESTFul way)?

suppose that I want to accept the following urls:
http://myserver/myapplication/posts
http://myserver/myapplication/posts/<id>
http://myserver/myapplication/posts/<id>/delete
how can I use the servlet decorator #WebServlet to do so? I'm investigating value and urlPatterns but I don't get how to do so. For example,
#WebServlet(urlPatterns={"/posts", "/posts/*"})
[..]
String param = request.getPathInfo();
gives me some result, but how to use it? Also, request.getPathInfo() seems to return the value of the wildcard, but what if I want more parameters like in http://http://myserver/myapplication/posts/<id>/delete/<force>?
In servlet specification, you have no notion of path variables. Some MVC frameworks do support them, for example Struts or Spring MVC.
For a servlet point of view, an URL is :
scheme://host.domain/context_path/servlet_path/path_info?parameters
where any of the parts (starting from context path may be null)
Spec for servlet 3.0 states :
Context Path: The path prefix associated with the ServletContext that this
servlet is a part of. If this context is the “default” context rooted at the base of the
Web server’s URL name space, this path will be an empty string. Otherwise, if the
context is not rooted at the root of the server’s name space, the path starts with a
/ character but does not end with a / character.
Servlet Path: The path section that directly corresponds to the mapping which
activated this request. This path starts with a ’/’ character except in the case
where the request is matched with the ‘/*’ or ““ pattern, in which case it is an
empty string.
PathInfo: The part of the request path that is not part of the Context Path or the
Servlet Path. It is either null if there is no extra path, or is a string with a leading
‘/’.
The following methods exist in the HttpServletRequest interface to access this
information:
getContextPath
getServletPath
getPathInfo
It is important to note that, except for URL encoding differences between the request
URI and the path parts, the following equation is always true:
requestURI = contextPath + servletPath + pathInfo
That means that you just have to use #WebServlet(urlPatterns={"/posts"}), and then decode by hands the pathInfo part to extract commands and parameters
I think you cannot do so using only the #WebServlet annotation. The urlPatterns only acts as a directive to the Servlet to indicate which url patterns should attend.
And as you can see by this docs https://docs.oracle.com/javaee/6/api/javax/servlet/annotation/WebServlet.html the value is just the case when urlPatterns is one string instead of an array of them.
As brso05 stated, you will need to parse from the request your parameters.

Java EE Security Model Web collection: Difference URL pattern "/" and "/*"

A "/" when comes to servlet mapping means default servlet.
How do you interpret this when comes to a URL pattern embedded inside a web-resource-collection element as below:
<security-constraint>
<web-resource-collection>
<web-resource-name>fixmyhome</web-resource-name>
<url-pattern>/*</url-pattern>
</web-resource-collection>
<auth-constraint>
<role-name>*</role-name>
</auth-constraint>
<user-data-constraint>
<transport-guarantee>NONE</transport-guarantee>
</user-data-constraint>
</security-constraint>
What about "/*'? This URL pattern is not a servlet mapping since it's enclosed by tag web-resource-collection.
I also noticed using http://localhost:8081/fixmyhome/main.jsp using both URL pattern "/" and "/*" gives the same results- which is it gives me the main.jsp page. I thought "/" might not work since there's no wildcard.
The <url-pattern> is looking for an Ant pattern. The patterns available are ?, *, and **; which match 1 character, 0 or more characters, and 0 or more directories respectively.
In your case of http://localhost:8081/fixmyhome/main.jsp, both / and /* are working the same because the * is not a requirement for their to be a character.
If you have a resources directory in your root, I would imagine your <url-pattern> would looks something like this:
<url-pattern>/resources/**</url-pattern>, thereby allowing you access to all sub-directories of the resources directory.
This may help provide some more clarity:
https://ant.apache.org/manual/dirtasks.html
According to this I would say that by writing / you are restricting access to the servlet while by writing /* you are restricting access to a certain path. So essentially "/" and "/*" would be the same.
The url pattern under security constraint does not belong to any mapping for servlet instead it is a regular expression. With the security constraint you can allow/restrict users with the mentioned role (in auth-constraint) for the given URL pattern.
Section 12.2 of servlet specification (version 3) states following:
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

How does a servlets filter identify next destination is another filter or a servlet/jsp?

We usually end up with writing <url-pattern>/*</url-pattern> in web.xml for any Filter in servlets.
<filter-mapping>
<filter-name>requestRedirectorFilter</filter-name>
<url-pattern>/action</url-pattern>
</filter-mapping>`.
Now my doubt is how java identifies which is next servlet/jsp is? Because any request we make through
request.getRequestDispatcher("/ABCXYZ").forward(request, (HttpServletResponse)servletResponse);
to navigate on next servlet/jsp, container by default is going to search in web.xml. And in web.xml <url-pattern>/*</url-pattern> is already there for the filter we use. Exactly here actual problem begins.
If <url-pattern>/*</url-pattern> [which is acting like a universal receiver for any request] is already there in web.xml then How the heck container knows to follow <url-pattern>/ABCXYZ</url-pattern> instead <url-pattern>/*</url-pattern> ? Please share your views and knowledge on this front.
Servlet Matching Procedure
A request may match more than one servlet-mapping in a given context. The servlet container uses a straightforward matching procedure to determine the best match.
The matching procedure has four simple rules.
First, the container prefers an exact path match over a wildcard path match.
Second, the container prefers to match the longest pattern.
Third, the container prefers path matches over filetype matches.
Finally, the pattern <url-pattern>/</url-pattern> always matches any request that no other pattern matches.
For example, a context web.xml file can map the home page for an online catalog to one pattern and the search page for the catalog to a different pattern, as shown below:
<servlet-mapping>
<servlet-name>catalogBrowse</servlet-name>
<url-pattern>/Catalog/*</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>catalogSearch</servlet-name>
<url-pattern>/Catalog/search/*</url-pattern>
</servlet-mapping>
Below figure illustrates the matching process for a context. Since the container prefers to match the longest pattern, a URL that includes /Catalog/search/ always matches the mapping for catalogSearch rather than the mapping for catalogBrowse.
URL pattern matching
It is copied form the below link if your are not interested to go to the link.
Please have a look at URL Patterns where it is described in detail with examples.

Configuring Spring to directory structure rather than *.html or other pattern

I want my spring application to access url like http://myapplication.com/app1/feature/ rather than http://myapplication.com/app1/feature.html
So basically how should I configure.
My Current config is below it works with *.html
web.xml
and it gives 404 error it I do map it to * .* etc
and it gives 404 error it I do map it to * .* etc
The servlet spec is very strict about what's allowed in a url-pattern. You're probably looking for /*, which will direct all requests to the DispatcherServlet, regardless of the path. Then it's up to you to define what happens.
For reference, "Specification of Mappings" (12.2) allows the following patterns:
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

Mapping a specific servlet to be the default servlet in Tomcat

I am trying to implement a servlet that gets raw requests, and decide either to process them, or forward them to another backend server. It is similar to a load-balancer, where a received request is forwarded to one of the (in my case 2) destinations. One of the destination is remote (on another host). Furthermore, the requests could come to the root (http://mycompany.com/).
Since I want to get raw requests, I implemented my own servlet (subclassing HttpServlet), and that works great. My servlet looks like:
public class MyProxyServlet extends HttpServlet {
#Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
processOrForward(req, resp);
}
// also doGet(), doHead(), ...
}
Since the service I want to process may send requests to the root, I would like to map my servlet to be the default servlet, thereby receiving any request that does not have an explicit servlet mapping. Assume my servlet's name is "myservlet", and is running along side of another servlet "foo", I expect all requests in the form of http://mycompany.com/foo/... to be delivered to foo, and everything else (e.g., /, /bar/..., /myservlet/...) to "myservlet". Looking at earlier posts (eg., root mapping here and here, or url rewriting here), I thought I figured it out, but it does not work.
Here is my web.xml:
<web-app>
<servlet>
<servlet-name>ProxyServlet</servlet-name>
<servlet-class>com.mycompany.MyProxyServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>ProxyServlet</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
</web-app>
In the above web.xml, for url-pattern I tried
"/" and "/*" and empty (i.e., <url-pattern></url-pattern>), all behave the same -->
Requests to root (/)goes to tomcat's default servlet
Requests to /myservlet/... are handled by "myservlet"
Requests to /fubar/... are always 404
Is there a way of turning my servlet to be the default. I.e., any request that does not map specifically to a servlet comes to mine (it is even acceptable to receive all requests, since I can deploy this servlet in its own container). In case it matters, I am using Tomcat 7.0.30 on Ubuntu 12.10.
This should be useful to you.
From the Java™ Servlet Specification Version 3.1 (JSR 340)
Chapter 12. Mapping Requests to Servlets
12.2 Specification of Mappings
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.
As an addition, read this nice explanation with short examples from the book Head First Servlets & JSP: Passing the Sun Certified Web Component Developer Exam (2nd edition) (quote):
The THREE types of <url-pattern> elements
1) EXACT match
Example:
<url-pattern>/Beer/SelectBeer.do</url-pattern>
MUST begin with a slash (/).
Can have an extension (like .do), but it’s not required.
2) DIRECTORY match
Example:
<url-pattern>/Beer/*</url-pattern>
MUST begin with a slash (/).
Always ends with a slash/asterisk (/*).
3) EXTENSION match
Example:
<url-pattern>*.do</url-pattern>
MUST begin with an asterisk (*) (NEVER with a slash).
After the asterisk, it MUST have a dot extension (.do, .jsp, etc.).
IMPORTANT NOTE:
The URL patterns represent logical / virtual structure, i.e. the patterns (paths) specified does not need to exist physically.
UPDATE
If you want, as you say in your comment,
I want host:port to hit my servlet, not the default tomcat servlet
then see the solution here:
How do I make my web application be the Tomcat default application
In other words, what you want is a path without application context, which implies the application context of the Tomcat default application.
Quote from the above link:
In a standard Tomcat installation, you will notice that under the same
directory (CATALINA_BASE)/webapps/, there is a directory called ROOT
(the capitals are important, even under Windows). That is the
residence of the current Tomcat default application, the one that is
called right now when a user calls up
http://myhost.company.com[:port]. The trick is to put your
application in its place.
I am not sure did I understood what you want but probably intercept 404 is what you want to do, then redirect where you want.
I've came here to forum because I have strange problem with tomcat 7, mine is doing just what you want ;)
This is only one way how I can have root, EMPTY
<servlet-mapping>
<servlet-name>Default</servlet-name>
<url-pattern></url-pattern>
</servlet-mapping>
That way : anything is redirected to this servlet, including images, etc, for example, I open another page, this show this one, root, then I can see in log 4 more request to same page, 3 for css and one for image.
<servlet-mapping>
<servlet-name>Default</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>

Categories

Resources