Question

I am running Tomcat 5.5.4 and have a servlet running with no problems. However, I'd like to set up a mapping to only launch the servlet when a URL containing a particular query string is submitted.

Right now in web.xml I have: <servlet-mapping> <servlet-name>MyServer</servlet-name> <url-pattern>/go/*</url-pattern> </servlet-mapping>

If a browser submits http://localhost/MyServer/go?P=123 the servlet is launched and all is well. However, I'd like to only launch that servlet if the URL is exactly as just shown. Unfortunately, right now if the URL is http://localhost/MyServer/go?P=AnyDarnThing the servlet still launches. I have tried setting up the following: <url-pattern>/go?P=123</url-pattern> but this results in The requested resource (/MyServer/go) is not available.

I've tried numerous variations (quoting the string, ...) on the above URL pattern but I always get the above error. I notice that if I (for debugging purposes) drop the "?" as in <url-pattern>/goP=123</url-pattern> I no longer get the error message and the server launches (but, of course, it doesn't respond to the "query string" because it's not properly formed.) This suggest to me that the "?" is causing a problem in the mapping. I've tried replacing it with its URL special character equivalent as follows: <url-pattern>/go%3FP=123</url-pattern> but this gives the same result just described above when I tried dropping the "?" altogether.

I realize I can let the servlet get launched when any query string is submitted and then "ignore" the request for all but the one I care about but there is a reason I'd prefer to not have the servlet launched to begin with. So, my question is, how can I configure the servlet so that it is only launched when a specific query string is included?

Thank you.

Was it helpful?

Solution

You can't do that using URL patterns.

You can achive this using filters. Implement a filter which will forward to the Servlet only if the query params exists.

Here is the how the filter will look like:

public class ServletAcessFilter implements Filter
{
  public void init(FilterConfig filterConfig) throws ServletException
  {

  }

  public void doFilter(ServletRequest request, ServletResponse response,
  FilterChain filterChain) throws IOException, ServletException
  {
    //validate the request, check if the request can be forwarded to servlet.
    if(request.getParameter("P").equalsIgnoreCase("123")){
        filterChain.doFilter(request, response);
    } else {
        //write what you want to do if the request has no access
        //below code will write 404 not found, you can do based on your requirement
        HttpServletResponse httpResponse = (HttpServletResponse) response;
        httpResponse.setStatus(404);
    }
  }

  public void destroy()
  {

  }
}

Define the filter in the web.xml like this:

<filter>
    <filter-name>ServletAccessFilter</filter-name>
    <filter-class>com.ServletAcessFilter</filter-class>
</filter>
<filter-mapping>
    <filter-name>ServletAccessFilter</filter-name>
    <url-pattern>/go/*</url-pattern>
</filter-mapping>

OTHER TIPS

You can't do that. The url-pattern is pretty limited.

If you want to have distinct actions taken based on a GET parameter, you can do that manually. In the doGet() method of the servlet have a simple if-clause and invoke different methods depending on the query string / get param.

To add to Bozho response, you may also try to move to Clean URLs

This will greatly increase your options in terms of URL pattern matching, and, in particular, may significantly ease configuration of a fronting reverse proxy if you ever need one.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top