提问人:Alireza Fattahi 提问时间:3/17/2023 最后编辑:Alireza Fattahi 更新时间:4/5/2023 访问量:413
如何将 URL 中的路径参数映射到 Struts 2 中的操作
How to map a path parameters in URL to the action in Struts 2
问:
我们在 Tomcat 9 上使用 Struts 6.2,并将所有扩展映射到操作,例如正确映射到操作。.action
save-user.action
Web 应用程序需要处理此路径参数(路径变量),例如:.如您所见,参数是通过 URL 路径发送的。调用方不是浏览器。save-user.action/name/joe/age/20
有什么方法可以配置 Struts 来处理此 URL 并将其映射到正确的操作?
答:
我们正在使用 convention-plugin,似乎我们应该在 Struts 过滤器之前获取 URL。将其更改为 Valid,然后让 Struts 完成其余工作。
/my.action/param1/value1
url/my.action?param1=value1
自己做起来并不容易,幸运的是,有一个解决方案可以在 struts 过滤器前面使用 urlrewrite 过滤器。请参阅为什么 URL 重写在 Struts 2 中不起作用:
如果将 Tuckey URL 重写筛选器放在 Web 应用程序部署描述符中的 Struts2 筛选器之前,则可以重写任何 URL。使用本指南:Tuckey URLRewrite How-To。
然后,添加一个规则来重写 URL,如下所示:
<rule match-type="regex">
<from>/my.action/param1/(\w+)</from>
<to>/my.action?param1=$1</to>
</rule>
评论
我更喜欢@RomanC解决方案,因为它不需要代码:)
如果您想自己开发它,这里是另一种解决方案。
这个想法是使用和更改并使 url 成为有效的 struts 操作。同时实现以生成有效的查询字符串HttpServletRequestWrapper
getRequestURI
getServletPath
getParameterMap
@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;
}
}
}
在: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>
评论
/my.action/param1/value1
/my.action?param1=value1
callinf my.action/param1/value1