Spring REST service: GET path variable gets truncated after dot '.' and HTTP Error 406 'Not acceptable' solution
Imagine you have following Spring REST controler (please note that I use Spring 4, so I don’t need to use @ResponseBody annotation anymore) which gets an email address and return JSON response:
1 @RestController
2 public class EmailCheckInfoController {
3
4 private static final Logger log = Logger.getLogger(EmailCheckInfoController.class);
5
6 @RequestMapping(value = "/{userEmail}", method = RequestMethod.GET, produces = "application/json")
7 public EmailCheckInfoResponse responseEmailCheckInfo(@PathVariable("userEmail") String userEmail) {
8 if (log.isDebugEnabled()) {
9 log.debug("responseEmailCheckInfo():: Entry");
10 }
11
12 EmailCheckInfoResponse resp = new EmailCheckInfoResponse();
13
14 // rest of code ommited
15
16 return resp;
17 }
18 }
you could encounter two problems (after fixing first one then the second one comes out).
Path variable gets truncated
Path variable userEmail eg. ‘johndoe@domain.com’ gets truncated to just ‘johndoe@domain’. Solution is easy just add:
.+
to request value, so request mapping would be the following:
@RequestMapping(value = "/{userEmail:.+}", method = RequestMethod.GET, produces = "application/json")
‘HTTP Status 406 Not acceptable’ error
After fixing that suffix truncation you may get and HTTP 406 error. I’m using Tomcat 7 and I get following error description:
HTTP Status 406 The resource identified by this request is only capable of generating responses with characteristics not acceptable according to the request “accept” headers.
The problem is caused due to Spring Framework’s ContentNegotiationManager settings.
My servlet settings are in file called emailcheck-servlet.xml where you could find Spring configuration for this servlet.
1 <?xml version="1.0" encoding="UTF-8"?>
2 <beans xmlns="http://www.springframework.org/schema/beans"
3 xmlns:context="http://www.springframework.org/schema/context"
4 xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
5 xsi:schemaLocation="
6 http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
7 http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
8 http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd">
9
10 <context:component-scan base-package="com.lukasgrygar.testapp.service" />
11
12 <mvc:annotation-driven />
13
14 </beans>
So to configure ContentNegotiationManager to favor parameter over path extension I did following (look at lines 12-15 and 17):
1 <?xml version="1.0" encoding="UTF-8"?>
2 <beans xmlns="http://www.springframework.org/schema/beans"
3 xmlns:context="http://www.springframework.org/schema/context"
4 xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
5 xsi:schemaLocation="
6 http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
7 http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
8 http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd">
9
10 <context:component-scan base-package="com.lukasgrygar.testapp.service" />
11
12 <bean id="contentNegotiationManager" class="org.springframework.web.accept.ContentNegotiationManagerFactoryBean">
13 <property name="favorPathExtension" value="false" />
14 <property name="favorParameter" value="true" />
15 </bean>
16
17 <mvc:annotation-driven content-negotiation-manager="contentNegotiationManager" />
18
19 </beans>
And that’s it Spring Rest service which takes email and produces JSON response works!
References:
- http://docs.spring.io/spring/docs/current/spring-framework-reference/html/mvc.html#mvc-ann-requestmapping
- http://docs.spring.io/spring/docs/current/spring-framework-reference/html/mvc.html#mvc-config-content-negotiation
- http://docs.spring.io/spring/docs/current/spring-framework-reference/html/mvc.html#mvc-config-path-matching