Spring MVC Missing URI template variable

133,186

Solution 1

@PathVariable is used to tell Spring that part of the URI path is a value you want passed to your method. Is this what you want, or are the variables supposed to be form data posted to the URI?

If you want form data, use @RequestParam instead of @PathVariable.

If you want @PathVariable, you need to specify placeholders in the @RequestMapping entry to tell Spring where the path variables fit in the URI. For example, if you want to extract a path variable called contentId, you would use:

@RequestMapping(value = "/whatever/{contentId}", method = RequestMethod.POST)

Edit: Additionally, if your path variable could contain a '.' and you want that part of the data, then you will need to tell Spring to grab everything, not just the stuff before the '.':

@RequestMapping(value = "/whatever/{contentId:.*}", method = RequestMethod.POST)

This is because the default behaviour of Spring is to treat that part of the URL as if it is a file extension, and excludes it from variable extraction.

Solution 2

I got this error for a stupid mistake, the variable name in the @PathVariable wasn't matching the one in the @RequestMapping

For example

@RequestMapping(value = "/whatever/{**contentId**}", method = RequestMethod.POST)
public … method(@PathVariable Integer **contentID**){
}

It may help others

Share:
133,186
devdar
Author by

devdar

Updated on January 25, 2021

Comments

  • devdar
    devdar over 3 years

    I have a Controller class with a function that saves a record to the Database. I am passing several parameters to the Controller function however i think i may be writing the @RequestMapping incorrectly. Under is the code

    Controller

     @RequestMapping(value="createRoadBlock.htm", method = RequestMethod.POST)
     public @ResponseBody Integer createRoadBlock(@RequestParam String purpose, @RequestParam String userName,
                                                  @RequestParam  int status, @RequestParam double latAdd,
                                                  @RequestParam double longAdd, HttpServletRequest request,  
                                                  HttpServletResponse response) {
    
             int roadBlockId = 0;
            try{
    
                roadBlockId = roadBlockManager.saveRoadBlock(purpose, userName, status,latAdd,longAdd);
                logger.info("Create Road Block Successful roadBlockId "+ roadBlockId);
    
                return roadBlockId;
    
            }catch(Exception e){
                logger.error("Exception Occured In Road Block Controller "+e.getMessage());
                return roadBlockId;
    
            } 
    
         }
    

    Ajax Request

    $.ajax({
        type:'POST',
        url:'createRoadBlock.htm',
        contentType:"application/json",
        async:false,
        cache:false,
            data:{purpose:f_purpose, userName:f_userName,status: f_status,latAdd: f_latAdd, longAdd:f_lngAdd},
        dataType:'json'
    
        }).success(function(recordId){ 
                    console.log('Road Block created with id ' + recordId);
        });
    

    Error Log

    Controller [com.crimetrack.web.RoadBlockController]
    Method [public java.lang.Integer com.crimetrack.web.RoadBlockController.createRoadBlock(java.lang.String,java.lang.String,int,double,double,javax.servlet.http.HttpServletRequest,javax.servlet.http.HttpServletResponse)]
    
    org.springframework.web.bind.MissingServletRequestParameterException: Required String parameter 'purpose' is not present
        at org.springframework.web.method.annotation.RequestParamMethodArgumentResolver.handleMissingValue(RequestParamMethodArgumentResolver.java:201)
        at org.springframework.web.method.annotation.AbstractNamedValueMethodArgumentResolver.resolveArgument(AbstractNamedValueMethodArgumentResolver.java:90)
        at org.springframework.web.method.support.HandlerMethodArgumentResolverComposite.resolveArgument(HandlerMethodArgumentResolverComposite.java:75)
        at org.springframework.web.method.support.InvocableHandlerMethod.getMethodArgumentValues(InvocableHandlerMethod.java:156)
        at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:117)
        at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:96)
        at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:617)
        at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:578)
        at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:80)
        at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:923)
        at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:852)
        at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:882)
        at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:789)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:647)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:728)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
        at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:222)
        at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:123)
        at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472)
        at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:171)
        at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:99)