SpringBoot中的@PathVariable,带有URL中的斜杠

时间:2017-04-18 11:04:08

标签: java rest url spring-boot path-variables

我必须在SpringBoot应用程序中使用@PathValiable从URL获取params。这些参数通常有斜杠。我无法控制用户在URL中输入的内容,因此我希望得到他输入的内容然后我可以处理它。

我已经在这里查看了材料和答案,我不认为对我来说好的解决方案是要求用户以某种方式编码输入参数。

SpringBoot代码很简单:

@RequestMapping("/modules/{moduleName}")
@ResponseBody
public String moduleStrings (@PathVariable("moduleName") String moduleName) throws Exception {

  ...

}

因此,例如URL如下:

http://localhost:3000/modules/...

问题是param moduleName 经常有斜杠。 例如,

metadata-api\cb-metadata-services OR
app-customization-service-impl\\modules\\expand-link-schemes\\common\\app-customization-service-api

因此用户可以定义输入:

http://localhost:3000/modules/metadata-api\cb-metadata-services

是否可以在 / modules / 之后获取用户在网址中输入的所有内容?

如果有人告诉我处理此类问题的好方法是什么。

5 个答案:

答案 0 :(得分:11)

此代码获取完整路径:

@RequestMapping(value = "/modules/{moduleBaseName}/**", method = RequestMethod.GET)
@ResponseBody
public String moduleStrings(@PathVariable String moduleBaseName, HttpServletRequest request) {
    final String path =
            request.getAttribute(HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE).toString();
    final String bestMatchingPattern =
            request.getAttribute(HandlerMapping.BEST_MATCHING_PATTERN_ATTRIBUTE).toString();

    String arguments = new AntPathMatcher().extractPathWithinPattern(bestMatchingPattern, path);

    String moduleName;
    if (null != arguments && !arguments.isEmpty()) {
        moduleName = moduleBaseName + '/' + arguments;
    } else {
        moduleName = moduleBaseName;
    }

    return "module name is: " + moduleName;
}

答案 1 :(得分:3)

基于P.J.Meisch的回答,我已经找到了针对我案例的简单解决方案。它还允许在URL参数中考虑几个斜杠。它也不允许像前面的答案那样使用反斜杠。

@RequestMapping(value = "/modules/**", method = RequestMethod.GET)
@ResponseBody
public String moduleStrings(HttpServletRequest request) {

    String requestURL = request.getRequestURL().toString();

    String moduleName = requestURL.split("/modules/")[1];

    return "module name is: " + moduleName;

}

答案 2 :(得分:0)

这是学校作业吗?您为什么要在路径中放置自由文本?相反,为什么不使用参数变量呢?

我不确定让用户输入包含自由文本的复杂URL是个好主意。首先,用户很难记住复杂的网址,因此它对用户不友好。其次,他们可以做一些奇怪的事情。

他们转到的主页可能会带有链接(或类似的内容),将其带到下一页。如果他们需要输入自由文本,请给他们一个文本框以向其中添加数据,然后单击按钮以进行类似于包含数据的ajax调用的操作。该路径将包含除自由文本之外的所有内容。你可以这样...

@RequestMapping(value = "/modules/{moduleBaseName}", method = RequestMethod.GET)
@ResponseBody
public String moduleStrings(@PathVariable String moduleBaseName,
                            @RequestParam(value = "moduleName", required = false) String moduleName 
                            HttpServletRequest request) 
{
    return "module name is: " + moduleName;
}

然后在客户端,您只需要在ajax调用中将data属性设置为包含“ moduleName”属性的json。像这样的东西。

var params = {};
params.moduleName = userEnteredText;
jQuery.ajax({
    type: "GET",
    url: 'http://localhost:3000/modules'.json'),
    dataType: "json",
    data: params,
    async: true,
    success: function(data) { callback(data); },
    error: function() { alert("Error!!!"); }
});

答案 3 :(得分:0)

import org.springframework.web.util.UriUtils;

@RequestMapping(value = "/modules/**", method = RequestMethod.GET)
@ResponseBody
public String moduleStrings(HttpServletRequest request) {
    final String url = request.getRequestURL().toString();
    final String modules = url.split("/modules")[1];
    final String safeModules = UriUtils.decode(modules, StandardCharsets.UTF_8);
        
    return "replaces %20 with space";
}

答案 4 :(得分:-2)

 @RequestMapping("/modules/**")