1

I am new to spring webmvc plz bear with me and I am not able to post exactly what to ask due to my lack of understanding on this subject. All I can say is spring mvc file extentions.

  • inherited maven + spring webmvc 5.1.2.RELEASE project
  • deployed mvn built fooapp.war to tomcat 8.5.58 on linux platform

The question I have is when I fire rest api call in a browser for the /mail/{address} endpoint.

Case 1)

Without / at the end of uri, it returns http status 406 - The target resource does not have a current representation that would be acceptable to the user agent, according to the proactive negotiation header fields received in the request, and the server is unwilling to supply a default representation.

http://localhost:<port>/fooapp/mail/john@bar.com

Case 2)

However with / at the end of uri, it returns proper response in json format.

http://localhost:<port>/fooapp/mail/john@bar.com/

I was not able to formulate a proper question to start with not understanding its cause but I did my best searching for a clue from www. I came to many threads but these caught my eyes:

This is what I tried.

Frist replaced / with /* for url-pattern in the web.xml.

<servlet>
    <servlet-name>fooapp</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>
            classpath:fooapp.xml
        </param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
</servlet>

<servlet-mapping>
    <servlet-name>fooapp</servlet-name>        
    <url-pattern>/*</url-pattern>
</servlet-mapping>

From the fooapp.xml, <mvc:path-matching suffix-pattern="false"/> is added.

<mvc:annotation-driven>
    <mvc:path-matching suffix-pattern="false"/>
</mvc:annotation-driven>

And the watered down version of FooController.java.

@RestController
@RequestMapping("/mail/{address}")
public final class FooController {
    
@RequestMapping(method = RequestMethod.GET, produces = "application/json")
public String doSomething(
    @PathVariable("address") String address, HttpServletResponse response) {         
    // execute code...
    return josnData;
}

Not knowing what I am doing my attempts didn't change the outcome. Why .com vs .com/ is treated differently? And how to get a proper response back with .com?

update

I may found a clue: Spring does not ignore file extension will give a try what it says.

With ^ suggestion, I was able to avoid http status 406 however when the FooController consume email address, it chops off .com so that data associated with the eamil address is not returned.

The suggestion I tried was adding following content to fooapp.xml.

<mvc:annotation-driven content-negotiation-manager="contentNegotiationManager" />

<bean id="contentNegotiationManager" class="org.springframework.web.accept.ContentNegotiationManagerFactoryBean">
<property name="favorPathExtension" value="false" />
</bean>

Found a solution

With this article: https://www.baeldung.com/spring-mvc-pathvariable-dot

By adding mail/{address:.+} in the controller along with ^ solution together fixed the problem.

DaeYoung
  • 1,161
  • 6
  • 27
  • 59
  • I would try moving the endpoint specification, `"/mail/{address}"` from the class annotation to the method annotation. I think what's happening is that it expects the method to add something to the url's path, hence the need to see the `/` at the end. – CryptoFool Oct 30 '20 at 16:10
  • Ty @Steve for your time and advice on this. I've tried moving `/mail/{address}` to the method but unfortunately I am seeing same outcome in where `.com` is chopped off when the `FooController` consums full email address from a log file... I appreciate your advice though I am gradually understanding the cause of this problem.. – DaeYoung Oct 30 '20 at 16:14

0 Answers0