40

Does servlet support urls as follows:

/xyz/{value}/test

where value could be replaced by text or number.

How to map that in the web.xml?

BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
BlackEagle
  • 814
  • 2
  • 12
  • 13
  • Related to: http://stackoverflow.com/questions/8252442/servlet-mappings-with-variablestomcat-7-0 (possible duplicate). – shelley Jan 03 '12 at 19:54

7 Answers7

53

It's not supported by Servlet API to have the URL pattern wildcard * in middle of the mapping. It only allows the wildcard * in the end of the mapping like so /prefix/* or in the start of the mapping like so *.suffix.

With the standard allowed URL pattern syntax your best bet is to map it on /xyz/* and extract the path information using HttpServletRequest#getPathInfo().

So, given an <url-pattern>/xyz/*</url-pattern>, here's a basic kickoff example how to extract the path information, null checks and array index out of bounds checks omitted:

String pathInfo = request.getPathInfo(); // /{value}/test
String[] pathParts = pathInfo.split("/");
String part1 = pathParts[1]; // {value}
String part2 = pathParts[2]; // test
// ...

If you want more finer grained control like as possible with Apache HTTPD's mod_rewrite, then you could look at Tuckey's URL rewrite filter or homegrow your own URL rewrite filter.

BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
  • 2
    Is this really *the way* one needs to extract url parameters which are not GET-parameters? This seems quite bloated, hard to maintain, prone to offset-bugs and 1995 in general. – Herbert May 13 '16 at 17:16
  • 3
    @Herbert: just use a framework on top of Servlet API which supports path parameters, such as JAX-RS or MVC. – BalusC May 14 '16 at 09:08
  • Another option is getRequestURI(), in my case getPathInfo() was empty. – leventunver Dec 17 '16 at 19:34
  • @leventunver: it will be empty in a filter, or when a badly implemented request wrapper is being used somewhere in the request, or due to a bug in the servletcontainer. – BalusC Dec 17 '16 at 21:16
  • I modified a class that extends GenericFilterBean. Uses ServletRequest as input. – leventunver Dec 17 '16 at 21:50
  • @leventunver: well, a filter is clearly not a servlet. – BalusC Dec 17 '16 at 21:51
10

As others have indicated, the servlet specification does not allow such patterns; however, you might consider JAX-RS which does allow such patterns, if this is appropriate for your use case.

@Path("/xyz/{value}/test")
public class User { 

    public String doSomething(@PathParam("value") final String value) { ... }

}

Or:

@Path("/xyz/{value}")
public class User { 

    @Path("test")
    public String doTest(@PathParam("value") final String value) { ... }

}

(Related to: https://stackoverflow.com/a/8303767/843093.)

Community
  • 1
  • 1
shelley
  • 7,206
  • 4
  • 36
  • 63
3

It does support mapping that url; but doesn't offer any validation.

In your web xml, you could do this....

/xyz/*

But that won't guarantee that the trailing test is present and that it is the last item. If you're looking for something more sophisticated, you should try urlrewritefilter.

http://code.google.com/p/urlrewritefilter/

Dave
  • 6,141
  • 2
  • 38
  • 65
1

No Servlet doesn't support patterns like that, possible approach as mentioned by other folks as well is to use /* after xyz but that doesn't check for {value} or /test. Better you go for Spring or JAX-RS. However if you plan to stick with Servlet a better way to write it:

@WebServlet(urlPatterns = {"/xyz/*"})

Saurabh Talreja
  • 335
  • 2
  • 6
1

You shouldn't be doing that in web.xml rather you can point every request to your filter (Patternfilter) and can check for URL

package com.inventwheel.filter;

import java.io.IOException;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;

/**
 * Servlet Filter implementation class PatternFilter
 */
@WebFilter("/*")
public class PatternFilter implements Filter {

    /**
     * Default constructor. 
     */
    public PatternFilter() {
        // TODO Auto-generated constructor stub
    }

    /**
     * @see Filter#destroy()
     */
    public void destroy() {
        // TODO Auto-generated method stub
    }

    /**
     * @see Filter#doFilter(ServletRequest, ServletResponse, FilterChain)
     */
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
            String servletPath = ((HttpServletRequest)request).getServletPath();
            String requestURI = ((HttpServletRequest)request).getRequestURI();
            Pattern pattern = Pattern.compile(".*"+servletPath+"/(.*)");
            Matcher matcher = pattern.matcher(requestURI);
            if (matcher.matches())
            {
            String param = matcher.group(1);
            // do stuff with param here..
            }

        chain.doFilter(request, response);
    }

    /**
     * @see Filter#init(FilterConfig)
     */
    public void init(FilterConfig fConfig) throws ServletException {
        // TODO Auto-generated method stub
    }

}
Sanjay Kumar
  • 1,474
  • 14
  • 22
0

An answer from the year 2022.

  1. Servlets do still not allow wildcards, so we can't do things like:
    /xyz/{value}/test

  2. Paul Tuckeys urlrewritefilter is still in version 4.0.3, and not compatible with the new jakarta namespace [1] (Version 5 is in development).

I found a solution in Tomcat itself, with its feature RewriteValve.
See https://rmannibucau.metawerx.net/post/tomcat-rewrite-url for a step-by-step manual. This is a convenient solution for allowing wildcards in the middle of a URL.

[1] https://github.com/paultuckey/urlrewritefilter/issues/239

0

As stated above, base servlets does not support patterns like you specified in your question. Spring MVC does support patterns. Here is a link to the pertinent section in the Spring Reference Document.

DwB
  • 37,124
  • 11
  • 56
  • 82