I have a Spring REST Controller:
@RestController
@RequestMapping(value = "/myresource")
public class MyResourceController {
...
}
With a GET request method:
@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) {
//...
}
I would expect this method to be callable with:
http://myserver:8080/myresource/value1/value2/value3
But it is only reachable with a trailing slash:
http://myserver:8080/myresource/value1/value2/value3/
Why is that so or what is causing this?
Swagger assumes there are no trailing slashes and I can't send a request with swagger now.
What can I do to only make the first URL work but not the second?
Thanks a lot in advance for your comments and answers.
Edited 2:
I found out that without the slash the information of value3 is incomplete. value3 must be an email address but everything from the final dot is cut off. So instead of "[email protected]" I am getting "myemail@something".
This explains why I can't get a proper result (no content and HTTP status code 404). But I still don't understand why this happens. Further than that, if I have an email address with three letters in the top level domain (like .com) the request never reaches the GET method "getMyResource" ....
Edited 1: My web.xml looks like that:
<?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>
And my spring-mvc-servlet.xml looks like that:
<?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 does not contain much:
swagger.include-pattern=/(?!api-docs|version).*
Always use trailing slashes for any resource that may contain children. Just consider "GET" on a public_html directory with files. So if "hello. html" can ever have children then it is always and forevermore "/hello.
@RestController is not meant to be used to return views to be resolved. It is supposed to return data which will be written to the body of the response, hence the inclusion of @ResponseBody .
@Controller annotation indicates that the class is a “controller” like a web controller. @RestController annotation indicates that class is a controller where @RequestMapping methods assume @ResponseBody semantics by default. In @Controller, we need to use @ResponseBody on every handler method.
I have a lot of applications using Spring Rest annotations and my APIs works with or without the trailing slashes.
It may be a problem with your Spring MVC configuration or with the http server you are using.
Could you post some code snippets with you Spring MVC configurations. It would be good to known which Spring version you are using and how are you serving the webapp.
Edit 1:
As I read in your second edit you are having problems with email parameters right?
Can you try using something like that and let me known if it resolves the issue?
@RequestMapping(method = GET, value = "/{value1}/{value2}/{value3:.+}"...
The problem seems to be with the dot in the url.
Reference: Spring MVC @PathVariable with dot (.) is getting truncated
I found the answer here:
Spring MVC @PathVariable getting truncated
This seems to happen only with the last parameter and the solution is to use a regex for the last value:
@RequestMapping(method = GET, value = "/{value1}/{value2}/{value3:.+}"
This works for me.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With