获取请求仅适用于斜杠(spring REST 注释)

Posted

技术标签:

【中文标题】获取请求仅适用于斜杠(spring REST 注释)【英文标题】:Get request only works with trailing slash (spring REST annotations) 【发布时间】:2015-09-15 23:52:34 【问题描述】:

我有一个 Spring REST 控制器:

@RestController
@RequestMapping(value = "/myresource")
public class MyResourceController 
  ...

使用 GET 请求方法:

@RequestMapping(method = GET, value = "/value1/value2/value3", produces = MediaType.APPLICATION_JSON_VALUE + ";charset=UTF-8")    
public ResponseEntity<MyResponseType> getMyResource(
  @ApiParam(value = "...",...)
  @PathVariable("value1") String value1,
  @ApiParam(value = "...",...)
  @PathVariable("value2") String value2,
  @ApiParam(value = "...",...)
  @PathVariable("value3") String value3) 
//...

我希望这个方法可以调用:

http://myserver:8080/myresource/value1/value2/value3

但它只能通过斜杠到达:

http://myserver:8080/myresource/value1/value2/value3/

为什么会这样或者是什么原因造成的?

Swagger 假设没有尾部斜杠,我现在无法使用 swagger 发送请求。

我该怎么做才能只使第一个 URL 工作而不是第二个?

非常感谢您的 cmets 和回答。


编辑 2:

我发现没有斜线 value3 的信息是不完整的。 value3 必须是一个电子邮件地址,但从最后一个点开始的所有内容都会被截断。 所以我得到的不是“myemail@something.de”,而是“myemail@something”。

这解释了为什么我无法获得正确的结果(无内容和 HTTP 状态代码 404)。但我仍然不明白为什么会这样。此外,如果我在***域(如 .com)中有一个包含三个字母的电子邮件地址,则请求永远不会到达 GET 方法“getMyResource” ....


编辑 1: 我的 web.xml 看起来像这样:

<?xml version="1.0" encoding="UTF-8"?>

<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/j2ee"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"
version="2.4">
<display-name>(my) Services</display-name>
<filter>
    <filter-name>SetCharacterEncodingFilter</filter-name>
    <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
    <init-param>
        <param-name>encoding</param-name>
        <param-value>UTF-8</param-value>
    </init-param>
    <init-param>
        <param-name>forceEncoding</param-name>
        <param-value>true</param-value>
    </init-param>
</filter>
<filter-mapping>
    <filter-name>SetCharacterEncodingFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

<!-- Provide ServletContext -->
<listener>
    <listener-class>my.ServletContextUtils</listener-class>
</listener>

<!-- Expose request to current thread (required for session and request-scoping) -->
<listener>
    <listener-class>org.springframework.web.context.request.RequestContextListener</listener-class>
</listener>

<servlet>
    <servlet-name>spring-mvc</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>
            WEB-INF/config/spring-mvc-servlet.xml
        </param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
    <servlet-name>spring-mvc</servlet-name>
    <url-pattern>/*</url-pattern>
</servlet-mapping>

</web-app>

我的 spring-mvc-servlet.xml 看起来像这样:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"   xmlns:util="http://www.springframework.org/schema/util"
xmlns:env="http://my/schema"
xsi:schemaLocation="
    http://www.springframework.org/schema/mvc 
    http://www.springframework.org/schema/mvc/spring-mvc-3.1.xsd
    http://www.springframework.org/schema/beans 
    http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
    http://www.springframework.org/schema/context 
    http://www.springframework.org/schema/context/spring-context-3.1.xsd
    http://www.springframework.org/schema/aop 
    http://www.springframework.org/schema/aop/spring-aop-3.1.xsd
    http://www.springframework.org/schema/tx 
    http://www.springframework.org/schema/tx/spring-tx-3.1.xsd
    http://www.springframework.org/schema/util
    http://www.springframework.org/schema/util/spring-util-3.1.xsd
    http://my/schema
    http://my/schema/env-0.3.xsd">

<env:initialization />
<context:annotation-config />
<mvc:annotation-driven />
<mvc:default-servlet-handler/>
<context:component-scan base-package="my.myresource.restapi" />

<context:property-placeholder
    ignore-unresolvable="true"
    location="
        WEB-INF/config/$my.environment/webapp.properties" />

<!-- Swagger -->

<!-- swagger config -->
<bean class="my.restapi.swagger.SwaggerConfig"/>

webapp.properties 包含的内容不多:

swagger.include-pattern=/(?!api-docs|version).*

【问题讨论】:

【参考方案1】:

我在这里找到了答案:

Spring MVC @PathVariable getting truncated

这似乎只发生在最后一个参数上,解决方案是对最后一个值使用正则表达式:

@RequestMapping(method = GET, value = "/value1/value2/value3:.+"

这对我有用。

【讨论】:

【参考方案2】:

我有很多使用 Spring Rest 注释的应用程序,我的 API 可以使用或不使用尾部斜杠。

这可能是您的 Spring MVC 配置或您正在使用的 http 服务器的问题。

您能否在 Spring MVC 配置中发布一些代码 sn-ps。最好知道您使用的是哪个 Spring 版本以及您如何为 webapp 提供服务。

编辑 1:

正如我在您的第二次编辑中看到的,您的电子邮件参数有问题吗?

您可以尝试使用类似的方法并告诉我是否可以解决问题吗?

@RequestMapping(method = GET, value = "/value1/value2/value3:.+"...

问题似乎与网址中的点有关。

参考:Spring MVC @PathVariable with dot (.) is getting truncated

【讨论】:

感谢您的提问。我刚刚添加了我的配置。不过,我对 POST 请求没有问题。 Swagger 正确发布并收到回复。 哦,是的,没有看到您的编辑,是的,我现在自己也找到了。它确实有效!【参考方案3】:

在您的 web.xml 文件中

<servlet-mapping>
<servlet-name>spring-mvc</servlet-name>
<url-pattern>/*</url-pattern>

如果你尝试不带 * 只是 /(如图所示),你会得到什么结果?

<servlet-mapping>
<servlet-name>spring-mvc</servlet-name>
<url-pattern>/</url-pattern>

【讨论】:

@pathvariable 与电子邮件地址类似已知问题。你可以看看这里。 link .. 1 和这里 link .. 2

以上是关于获取请求仅适用于斜杠(spring REST 注释)的主要内容,如果未能解决你的问题,请参考以下文章

Spring Boot - REST POST 请求时仅保存 ID,但 GET 请求时获取对象

Intellij:在行注释中的双斜杠后添加空格

如何将 Spring MVC 控制器映射到带有和不带有斜杠的 uri?

@@ Transactional交易仅适用于少数例外情况

注释仅适用于接口的方法

Spring Boot REST·@Constraint 删除?