In the topics application I wanted to be able to map URLs like:
http://www.arevalos.org/topics/twitter/opencode.html
http://www.arevalos.org/topics/twitter/t_ajax.html
I wanted to map those URLs to the same struts 2 action and use the same view, since the view can be re-utilized for all the different accounts. After an initial research on the Struts 2 Guides, I thought I might be able to utilize the “Parameters in namespaces”, but they rely on the deprecated (version as of this writing 2.1.6) Codebehind Plugin, and I didn’t really want to use deprecated stuff.
So I continued looking through the documentation, Google did not help me much, maybe I was not searching right. Anyway what I found was that maybe an implementation of an Action Mapper.
For my application, where the root context is /topics I came up with the following code:
/**
*
*/
package org.arevalos.topics.struts2.dispatcher.mapper;
import java.util.ArrayList;
import java.util.Map;
import java.util.TreeMap;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.servlet.http.HttpServletRequest;
import org.apache.struts2.dispatcher.mapper.ActionMapping;
import org.apache.struts2.dispatcher.mapper.DefaultActionMapper;
import com.opensymphony.xwork2.config.ConfigurationManager;
/**
* @author Cesar Arevalo
* @since 0.0.1
*/
public class TwitterActionMapper extends DefaultActionMapper {
public TwitterActionMapper() {
super();
extensions = new ArrayList();
extensions.add("html");
extensions.add("");
}
private static String getAccountFromUrl(String s, String regex) {
Matcher m = Pattern.compile(regex).matcher(s);
return m.find() ? m.group(1) : null;
}
@Override
public ActionMapping getMapping(HttpServletRequest request,
ConfigurationManager configManager) {
String uri = getUri(request);
String regex = "/twitter/(\\w+).html";
String id = getAccountFromUrl(uri, regex);
if (id != null) {
ActionMapping m = new ActionMapping();
m.setExtension("");
m.setMethod("execute");
m.setNamespace("/twitter");
m.setName("account");
Map params = new TreeMap();
params.put("twitterAccount", id);
m.setParams(params);
return m;
}
return super.getMapping(request, configManager);
}
}
There are probably some more optimizations I can apply to the code, but right now it works!
Pingback: The prettifier I use in my blog « Arevalos Blog