【问题标题】:How to extract path parameter value in URI?如何提取URI中的路径参数值?
【发布时间】:2016-05-31 18:28:49
【问题描述】:

我要提取HttpServletRequest中的路径参数值

示例网址: abc.api.com/learn/sections/{sectionId}/assignments/{assignmentId}

sectionString = Optional.ofNullable(request.getServletPath().split("/")[3]);

我尝试通过拆分 URI 路径来提取节 id,但这个 URI 可以更改。有人对此有可靠的解决方案吗? 谢谢

【问题讨论】:

  • 也许sectionId有一个特定的、唯一的模式可以用来提取它?
  • @mnille sectionId 是动态 UUID
  • 是的,但问题是 UUID 本身是否具有特殊模式,即 AAA-BBBB-CCCC-DDD 行。在您的 URL 中唯一的模式。
  • 查看这个答案:stackoverflow.com/a/3686956/316343

标签: java spring-mvc servlet-filters


【解决方案1】:

假设sectionId 总是在sections 之后,您可以使用简单的正则表达式,例如

String uri = "abc.api.com/learn/sections/asdf-987/assignments/dsfwq98r7sdfg";
Matcher m = Pattern.compile(".*\\/sections\\/([a-zA-Z0-9-]+)(\\/?).*").matcher(uri);
if (m.matches()) {
    System.out.println(m.group(1)); //asdf-987
}

(假设 UUID 的格式为 aaa-AAAA-9999

您可以对assignmentId 进行类似的操作,甚至可以在 1 个正则表达式中进行操作

【讨论】:

  • 如果 URI 如下所示,解决方案是什么:没有 sectionID 或信息? “abc.api.com/learn/sections/assignments/dsfwq98r7sdfg”
  • 查看这个答案:stackoverflow.com/a/3686956/316343
【解决方案2】:

这里有一个解决方案

单元测试看看它是如何工作的:

public class ParameterResolverTest {

    @Test
    public void testParameterExtraction() {
        final ParameterResolver parameterResolver = new ParameterResolver("abc.api.com/learn/sections/{sectionId}/assignments/{assignmentId}");
        final Map<String, String> resultMap = parameterResolver.parametersByName("abc.api.com/learn/sections/0000-0000/assignments/1111-1111");
        Assert.assertEquals("0000-0000", resultMap.get("sectionId"));
        Assert.assertEquals("1111-1111", resultMap.get("assignmentId"));
    }

}

ParameterResolver 类:

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * Created by dkis on 2016.02.19..
 */
public class ParameterResolver {

    private static final Pattern PARAMETER_PATTERN = Pattern.compile("(\\{[a-zA-Z]+\\})");
    private final List<String> parameterNames = new ArrayList<>();
    private final Pattern pattern;

    public ParameterResolver(final String parameterTemplate) {

        final Matcher matcher = PARAMETER_PATTERN.matcher(parameterTemplate);

        while (matcher.find()) {
            if(matcher.groupCount()==1) {
                final String group = matcher.group(1);
                if(group.length()>2) {
                    parameterNames.add(group.substring(1, group.length() - 1));
                } else {
                    parameterNames.add(group);
                }
            }
        }
        pattern = Pattern.compile(Pattern.quote(matcher.replaceAll("_____PARAM_____")).replace("_____PARAM_____", "\\E([^/]*)\\Q"));

    }

    public Map<String, String> parametersByName(final String uriString) {
        final Matcher matcher = pattern.matcher(uriString);
        if(!matcher.matches()) {
            throw new IllegalArgumentException("Uri not matches!");
        }
        final Map<String, String> map = new HashMap<>();
        for(int i = 1;i<=matcher.groupCount();i++) {
            map.put(parameterNames.get(i-1), matcher.group(i));
        }
        return map;

    }

}

【讨论】:

    【解决方案3】:

    据我所知,Java SDK 没有默认的解决方案。如果您使用 Spring MVC/Apache CXF 等框架。它应该有解决方案

    【讨论】:

    • 是的,你是对的,这就是为什么我正在为我的问题寻找替代途径,tnx
    猜你喜欢
    • 1970-01-01
    • 2019-09-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-10-05
    相关资源
    最近更新 更多