这是问题的延续 Spring MVC @PathVariable被截断

Spring论坛声明它已经固定(3.2版本)作为ContentNegotiationManager的一部分。请看下面的链接。 https://jira.springsource.org/browse/SPR-6164 https://jira.springsource.org/browse/SPR-7632

在我的应用程序中,带有。com的requestParameter被截断了。

谁能告诉我如何使用这个新功能?如何在xml中配置它?

注:春季论坛- #1 Spring MVC @PathVariable带点(.)会被截断


当前回答

Spring 5.2.4 (Spring Boot v2.2.6.RELEASE) PathMatchConfigurer。setUseSuffixPatternMatch和ContentNegotiationConfigurer。favorPathExtension已弃用(https://spring.io/blog/2020/03/24/spring-framework-5-2-5-available-now和https://github.com/spring-projects/spring-framework/issues/24179)。

真正的问题是客户端请求特定的媒体类型(比如。com),而Spring默认添加了所有这些媒体类型。在大多数情况下,您的REST控制器只会生成JSON,因此它不支持所请求的输出格式(.com)。 为了克服这个问题,你应该通过更新你的rest控制器(或特定的方法)来支持“输出”格式(@RequestMapping(produces = mediattype . all_value)),当然也允许像点({username:.+})这样的字符。

例子:

@RequestMapping(value = USERNAME, consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
public class UsernameAPI {

    private final UsernameService service;

    @GetMapping(value = "/{username:.+}", consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.ALL_VALUE)
    public ResponseEntity isUsernameAlreadyInUse(@PathVariable(value = "username") @Valid @Size(max = 255) String username) {
        log.debug("Check if username already exists");
        if (service.doesUsernameExist(username)) {
            return ResponseEntity.status(HttpStatus.NO_CONTENT).build();
        }
        return ResponseEntity.notFound().build();
    }
}

Spring 5.3及以上版本将只匹配已注册的后缀(媒体类型)。

其他回答

在Spring Boot中,正则表达式解决了这样的问题

@GetMapping("/path/{param1:.+}")

最后,我在Spring Docs中找到了解决方案:

要完全禁用文件扩展名,您必须同时设置以下两项: useSuffixPatternMatching(false),参见PathMatchConfigurer favorpatheextension (false),参见ContentNegotiationConfigurer

将此添加到我的WebMvcConfigurerAdapter实现解决了这个问题:

@Override
public void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
    configurer.favorPathExtension(false);
}

@Override
public void configurePathMatch(PathMatchConfigurer matcher) {
    matcher.setUseSuffixPatternMatch(false);
}

如果你同时写后面和前面,另一个简单的解决方案是在前面的URL末尾附加一个“/”。如果是这样,你不需要改变你的后端…

somepath/myemail@gmail.com/

是快乐!

据我所知,这个问题只出现在请求映射结束时的路径变量。

我们可以通过在requestmapping中定义regex插件来解决这个问题。

 /somepath/{variable:.+}

如果您正在使用Spring 3.2。x和<mvc:annotation-driven />,创建这个小BeanPostProcessor:

package spring;

public final class DoNotTruncateMyUrls implements BeanPostProcessor {
    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        if (bean instanceof RequestMappingHandlerMapping) {
            ((RequestMappingHandlerMapping)bean).setUseSuffixPatternMatch(false);
        }
        return bean;
    }
    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        return bean;
    }
}

然后把这个放在你的MVC配置xml中:

<bean class="spring.DoNotTruncateMyUrls" />