Java servlet regex url - java

I have a servlet. But instead of making that servlet listen to a static URL (e.g: /testservlet), I want it to listen to a dynamic url, or a URL with regex (e.g: /testservlet[0-9]*) which in this case will listen to a url mysite.com/testservlet followed by any numbers.
How do I do that?

Assuming that your servlet class is: victor.serlets.MyServlet
In your application's web.xml, include the following:
<servlet>
<servlet-name>myTestServlet </servlet-name>
<servlet-class>victor.serlets.MyServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>myTestServlet</servlet-name>
<url-pattern>/testservlet*</url-pattern>
</servlet-mapping>
As for the wildcard in the url-pattern tag, if you want to be more specific than "*" (i.e. anything), I am not certain what wildcards are supported. I suggest you look at the Oracle servlet docs for more info. FWIW, I think the "*" wildcard will suffice for your app.

Related

How to avoid matching paths that don't have a slash with servlet-mappings?

I'm trying to set up a servlet so that any requests for /foo/* will go to my Foo servlet, except for requests in the form of /foo/bar/*, which go to the Bar one. However, I want /foo/bar to go to the Foo servlet, not the Bar one. Is there a way to do this with just url-patterns in web.xml?
My mappings:
<servlet-mapping>
<servlet-name>Bar</servlet-name>
<url-pattern>/foo/bar/*</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>Foo</servlet-name>
<url-pattern>/foo/*</url-pattern>
</servlet-mapping>
I've tried removing the asterisks and trying a few other patterns, but the only way I can see to do this is to have a specific mapping for /foo/bar, though it seems like there should be a better way.
If you are using servlet specification v2.5 or above then you could provide multiple url-pattern elements for the same servlet-mapping like:
<servlet-mapping>
<servlet-name>Foo</servlet-name>
<url-pattern>/foo/*</url-pattern>
<url-pattern>/foo/bar</url-pattern>
</servlet-mapping>

url-pattern /* serves jsp files and static assets as seperate requests

I have a simple servlet which renders different content based on different geo locations
for example:
example.com/us
example.com/de
example.com/uk
example.com/..
so actually the servlet should supports all geo locations as url-pattern. So thats why I defined the rule below in my web.xml file:
<servlet-mapping>
servlet-name>MyServlet</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
this is how the servlet look like:
public class MyServlet extends HttpServlet{
String showPage = "/pages/show.jsp";
public void doGet(HttpServletRequest request, HttpServletResponse response){
System.out.println("servlet initiated... ~> "+request.getRequestURI());
...
request.getRequestDispatcher(showPage).forward(request, response);
}
}
As soon as I try to forward the page, the servlet starts again and again; it tries to also handle the request /page/show.jsp.
So I get such an ouput when I try to access example.com/us:
servlet initiated... ~> /us
servlet initiated... ~> /page/show.jsp
Exception...
servlet initiated... ~> /page/show.jsp
Exception...
servlet initiated... ~> /page/show.jsp
...
It throws an exception because my servlet is not expecting such a url-pattern /page/show.jsp but it triggers because I have define /* url-pattern in my web.xml file.
Any idea? how can I skip or exclude the unwanted requests like the one above? Thanks.
I could not find a specific reference but I believe that "/*" root url pattern conflicts with the default mapping in the the global web.xml which could be contributing to your problem.
<servlet>
<servlet-name>default</servlet-name>
<servlet-class>org.apache.catalina.servlets.DefaultServlet</servlet-class>
<init-param>
<param-name>debug</param-name>
<param-value>0</param-value>
</init-param>
<init-param>
<param-name>listings</param-name>
<param-value>false</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<!-- The mapping for the default servlet -->
<servlet-mapping>
<servlet-name>default</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
try adding explicit jsp servlet tag and servlet mapping to avoid processing the jsp through the default mapping which is created with the "/" root url pattern. I'm not sure that this will solve your problem.
<servlet>
<servlet-name>showpage</servlet-name>
<jsp-file>/pages/show.jsp</jsp-file>
</servlet>
<servlet-mapping>
<servlet-name>showpage</servlet-name>
<url-pattern>/show</url-pattern>
</servlet-mapping>
Another more explicit solution would be to create a url pattern that differentiates all of the country geo requests.
<servlet-mapping>
<servlet-name>MyServlet</servlet-name>
<url-pattern>/geo/*</url-pattern>
</servlet-mapping>
So example.com/geo/us etc will map explicitly
I attempted the same global setting and had a similar problem where it recursively attempted the request and threw an exception over and over until I stopped the Tomcat server. The problem was resolved when used more specific url pattern.
Bart answer gave me the clue. Actually there are many ways to handle this, one is to use Filters and the other one is to define all the static routes in web.xml and instead of the /* I have used /.
So to resolve the issue I change the url-pattern as below:
<!-- static assets -->
<servlet-mapping>
<servlet-name>default</servlet-name>
<url-pattern>*.js</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>default</servlet-name>
<url-pattern>*.css</url-pattern>
</servlet-mapping>
<!-- my servlet -->
<servlet-mapping>
servlet-name>MyServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
You also don't need to define the pattern for org.apache.catalina.servlets.DefaultServlet its already there by default.
So After above changes everything works fine.
When resolving pages/show.jsp the container will match on the longest path first then look at the file extension (.jsp) afterwards. So pages/show.jsp matches /* and therefore the container loads the Servlet again and doesn't initiate the JSP engine servlet.
Are all your jsps in a pages directory? Maybe you can add that mapping to your web.xml
<servlet-mapping>
<servlet-name>jsp</servlet-name>
<url-pattern>/pages/*</url-pattern>
</servlet-mapping>
Per the servlet specification (2.5 here, but it should be the smae for newer version) :
The container will try to find an exact match of the path of the request to the
path of the servlet. A successful match selects the servlet.
The container will recursively try to match the longest path-prefix. This is done
by stepping down the path tree a directory at a time, using the ’/’ character as
a path separator. The longest match determines the servlet selected.
If the last segment in the URL path contains an extension (e.g. .jsp), the servlet
container will try to match a servlet that handles requests for the extension.
An extension is defined as the part of the last segment after the last ’.’ character.
If neither of the previous three rules result in a servlet match, the container will
attempt to serve content appropriate for the resource requested. If a "default"
servlet is defined for the application, it will be used.
(source : servlet-spec-2.5)
So for your case, it should be sufficient to add a more precise mapping (as said by Si Kelly) :
<servlet-mapping>
<servlet-name>jsp</servlet-name>
<url-pattern>/pages/show.jsp</url-pattern>
</servlet-mapping>

how to detect popup call in java?

i am making the call to my servlet from javascript with window.open
window.open('myServlet','window','window Params')
i want to detect in myservlet whether call is coming from popup or not without passing any paramater alongwith servlet. Can we detect it in servlet?
You can with a query parameter
window.open('myServlet?from=popup','window','window Params');
Use that from parameter in your servlet to detect.
Edit:
Since you Don't want to use a query param, It's not possible on server side to know from where(click) this is getting called .
A query parameter would be best (as described by Suresh Atta). One possible alternative - since you can't use a parameter - might be to have two servlet mappings for your servlet - with one of the mappings for just the popup.
<servlet>
<servlet-name>myServlet</servlet-name>
<servlet-class>foo.bar.MyServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>myServlet</servlet-name>
<url-pattern>/myServlet</url-pattern>
</servlet-mapping>
<!-- Popup-specific mapping -->
<servlet-mapping>
<servlet-name>myServlet</servlet-name>
<url-pattern>/myServlet-popup</url-pattern>
</servlet-mapping>
Your popup could reference the popup-specific mapping:
window.open('myServlet-popup','window','window Params');
Then inside your servlet you could inspect the HttpServletRequest to determine the path that was used - and thus whether the servlet was called via the popup or not.
As already said, the parameter method is better. But this might be a possible alternative.

Servlet mapping: url-pattern for URLs with trailing slash

I have a problem related to the servlet mapping. I have the following in web.xml:
<servlet>
<servlet-name>HelloWorldServlet</servlet-name>
<servlet-class>test.HelloWorldServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>HelloWorldServlet</servlet-name>
<url-pattern>/HelloWorld</url-pattern>
</servlet-mapping>
If I access to http://localhost:<port>/MyApp/HelloWorld the servlet HelloWorldServlet is called.
I also want my servelet to respond to http://localhost:<port>/MyApp/HelloWorld/. How can I achieve this effect? I'm developing with NetBeans but it does not allow me to put a pattern ended with /.
After you've added your wildcard on your <url-pattern>
<url-pattern>/HelloWorld/*</url-pattern>
You can get the extra path associated with the URL by using HttpServletRequest.getPathInfo().
E.g.
http://localhost:<port>/MyApp/HelloWorld/one/
The result will be
/one/
From the JavaDoc:
Returns any extra path information
associated with the URL the client
sent when it made this request. The
extra path information follows the
servlet path but precedes the query
string and will start with a "/"
character.
Use a wildcard. You can redirect all the traffic going to a specific URL to the same servlet. For example, you can add the following:
<servlet-mapping>
<servlet-name>HelloWorldServlet</servlet-name>
<url-pattern>/HelloWorld/*</url-pattern>
</servlet-mapping>
This will redirect the URL with a slash to your original servlet.
One thought - this would redirect anything to this URL pattern to the servlet. If you want to have other URL's past this URL, you should create a servlet that will redirect to the correct URL (by looking at the URL specified). Alternatively, you could use a framework that provides mapping for you.

Call a servlet on click of hyperlink

Is there a way to call a Java Servlet on click of hyperlink without using JavaScript?
Make the hyperlink have a URL that you have a servlet mapping defined for in the web.xml file.
The servlet-mapping element defines a mapping between a servlet and a URL pattern. The example below maps the servlet named myservlet to any URL that starts with /foo:
<servlet>
<servlet-name>myservlet</servlet-name>
<servlet-class>com.stackoverflow.examples.MyServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>myservlet</servlet-name>
<url-pattern>/foo/*</url-pattern>
</servlet-mapping>
For this example, a hyperlink such as Click Me would invoke the servlet.
you declare your servlet in web.xml by setting its name, class and url-pattern
(let's say your url-pattern is /myServlet)
write mylink
override the doGet(..) method of the servlet to do whatever you want
Think that you've defined a servlet "callme" and web.xml has been configured for this servlet. Use the following syntax to call it using hyperlink
web.xml
<servlet>
<description>callme Functions</description>
<display-name>callme</display-name>
<servlet-name>callme</servlet-name> <servlet-class>com.test.Projects.callme</servlet-
class>
</servlet>
<servlet-mapping>
<servlet-name>callme</servlet-name>
<url-pattern>/callme</url-pattern>
</servlet-mapping>
in JSP:
Call the servlet
What exactly do you mean with "call a Java Servlet? The most normal (i.e. without any JavaScript magic) browser behaviour for clicking on a link is to send a HTTP request to fetch the document at the URL specified in the link and display it - and Servlets exist to respond to HTTP requests.
So you don't have to do anything special at all. Just have a regular HTML link and make sure that the servlet you want to "call" corresponds to that link's URL. Of course the next question is what that Servlet returns and what you want the browser to do with it.

Categories