I prefer the @RomanC solution as it will needs no code :)
Just if you want to develop it yourself here is another solution.
The idea is to use HttpServletRequestWrapper
and change getRequestURI
and getServletPath
to make url a valid struts action. Also implement getParameterMap
to make valid query string
@WebFilter(filterName = "UrlToActionMapperFilter")
public class UrlToActionMapperFilter implements Filter {
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
HttpServletRequest httpRequest = (HttpServletRequest) request;
ChangedURIRequestWarpper warpperdRequest = new ChangedURIRequestWarpper(httpRequest);
chain.doFilter(warpperdRequest, response);
}
public class ChangedURIRequestWarpper extends HttpServletRequestWrapper {
private final Logger LOG = LoggerFactory.getLogger(ChangedURIRequestWarpper.class);
private static final String CALLBACKURI = "foo/bar.action";
private static final String URL_PARAMETERS_REGEX = "(\\w+\\/\\w+)";
private final Pattern URL_PARAMETERS_PATTERN = Pattern.compile(URL_PARAMETERS_REGEX);
public ChangedURIRequestWarpper(HttpServletRequest request) {
// So that other request method behave just like before
super(request);
}
/**
* read the parameters from url which is defined as /param1/value1/param2/value2
* and set them to parameter map
*
*/
@Override
public Map<String, String[]> getParameterMap() {
LOG.debug("get the parameters from {}, and set them in parameters map", super.getRequestURI());
Map<String, String[]> parameters = new HashMap<>();
//The queryString is /param1/value1/param2/value2
String queryString = StringUtils.substringAfter(super.getRequestURI(), CALLBACKURI);
Matcher matcher = URL_PARAMETERS_PATTERN.matcher(queryString);
while (matcher.find()) {
String[] keyValue = matcher.group(1).split("/");
LOG.debug("Set {} in parameters map " , (Object)keyValue);
parameters.put( keyValue[0], new String[] { keyValue[1] });
}
return parameters;
}
/**
* struts use getRequestURI and getServletPath to determine if it should handle request ot not
* As this url is fixed we can hardcode it.
*/
@Override
public String getRequestURI() {
return "/"+CALLBACKURI;
}
@Override
public String getServletPath() {
return "/"+CALLBACKURI;
}
}
}
in web.xml
:
<filter-mapping>
<filter-name>UrlToActionMapperFilter</filter-name>
<!-- if you want to change it remember to change ChangedURIRequestWarpper -->
<url-pattern>/foo/bar.action/*</url-pattern>
</filter-mapping>