如何在URI中提取路径参数值?

时间:2016-02-19 08:48:32

标签: java spring-mvc servlet-filters

我想在HttpServletRequest中提取路径参数值

  

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

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

我尝试通过拆分URI路径来提取section id,但是时间这个URI可以改变任何人作为这个的可靠解决方案。 感谢

3 个答案:

答案 0 :(得分:0)

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

答案 1 :(得分:0)

这是一个解决方案

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

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;

    }

}

答案 2 :(得分:0)

假设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个正则表达式

中执行此操作