You need Advanced Wildcard Mappings.
From the documentation: Struts2's Advanced Wildcard Mappings:
Advanced Wildcards
From 2.1.9+ regular expressions can be defined defined in the action
name. To use this form of wild card, the following constants must be
set:
<constant name="struts.enable.SlashesInActionNames" value="true"/>
<constant name="struts.mapper.alwaysSelectFullNamespace" value="false"/>
<constant name="struts.patternMatcher" value="regex" />
The regular expressions can be in two forms, the simplest one is
{FIELD_NAME}, in which case the field with the FIELD_NAME in the
action will be populated with the matched text, for example:
<package name="books" extends="struts-default" namespace="/">
<action name="/{type}/content/{title}" class="example.BookAction">
<result>/books/content.jsp</result>
</action>
</package>
In this example, if the url /fiction/content/Frankenstein is
requested, BookAction's field "type" will be set to "fiction", and the
field "title" will be set to "Frankenstein".
If using Struts2-Convention-Plugin, your example would be:
@Action(value="/books/{author}/{year}")
public class Books extends ActionSupport {
private String author;
private Integer year;
/* ...GETTERS AND SETTERS HERE... */
public String execute(){
/* ...LOAD DATA HERE... */
if (noDataFound)
return NONE;
return SUCCESS
}
}
If you need to work with those parameters in prepare() method, read this question.