NewUser
NewUser

Reputation: 3819

Getting No mapping found for HTTP request with URI

I am trying to handle Requests in Spring dispatcher servlet.

My web.xml is having the servlet:

<servlet>
    <servlet-name>ApplicationDispatcher</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>/WEB-INF/SpringConfig/WebApplication.xml</param-value>
    </init-param>
    <load-on-startup>2</load-on-startup>
</servlet>

<servlet-mapping>
    <servlet-name>ApplicationDispatcher</servlet-name>
    <url-pattern>*.json</url-pattern>
    <url-pattern>*.do</url-pattern>
    <url-pattern>/entities/*</url-pattern>
</servlet-mapping>

My controller looks :

@Controller(value="entities")
public class EntitiesController {
    private static final Logger LOGGER = Logger.getLogger(EntitiesController.class);

    @Autowired
    private IEntityDataService iEntityDataService;

    @RequestMapping("/list")
    public String displayAllEntities() {
        LOGGER.info("Displaying entity dashboard");
        return "entity_landing";
    }

    @RequestMapping("/display")
    public String displayCheckpointDashboard(Integer id) {
        LOGGER.info("Displaying checkpoint dashboard for id " + id);
        return "entity";
    }

    @RequestMapping("/update")
    public String displayUpdateEntity(Integer id) {
        System.out.println("Update id " + id);
        return "new_entity";
    }

    @RequestMapping("/add")
    public String displayNewEntity() {
        LOGGER.info("Displaying new entity page");
        return "new_entity";
    }
}

I am seeing the following logs in my application log:

2016-01-13 16:15:12 INFO  RequestMappingHandlerMapping:180 - Mapped "{[/entity/add/entityDetails.do],methods=[GET],params=[],headers=[],consumes=[],produces=[],custom=[]}" onto public java.lang.String com.test.EntityController.saveEntityDetails(com.test.vo.EntityCheckpointsVo)
2016-01-13 16:15:12 INFO  RequestMappingHandlerMapping:180 - Mapped "{[/entities/list],methods=[],params=[],headers=[],consumes=[],produces=[],custom=[]}" onto public java.lang.String com.test.EntitiesController.displayAllEntities()
2016-01-13 16:15:12 INFO  RequestMappingHandlerMapping:180 - Mapped "{[/entities/add],methods=[],params=[],headers=[],consumes=[],produces=[],custom=[]}" onto public java.lang.String com.test.EntitiesController.displayNewEntity()
2016-01-13 16:15:12 INFO  DispatcherServlet:476 - FrameworkServlet 'ApplicationDispatcher': initialization completed in 950 ms
2016-01-13 16:15:12 WARN  PageNotFound:1116 - No mapping found for HTTP request with URI [/TestProject/entities/add] in DispatcherServlet with name 'ApplicationDispatcher'
2016-01-13 16:15:17 WARN  PageNotFound:1116 - No mapping found for HTTP request with URI [/TestProject/entities/add] in DispatcherServlet with name 'ApplicationDispatcher'
2016-01-13 16:17:04 WARN  PageNotFound:1116 - No mapping found for HTTP request with URI [/TestProject/entities/add] in DispatcherServlet with name 'ApplicationDispatcher'

I am not having any clue as the log says there is /entities/add is registered. I am able to access other URL such as localhost:8080/TestProject/entity/add/entityDetails.do but I am not able to access localhost:8080/TestProject/entities/add.

Please help me out here.

Thanks

Update :

Snippet from EntityController

@Controller
@RequestMapping(value = "/entity")
public class EntityController {
    @RequestMapping(value = "/add/entityDetails.do", method = RequestMethod.GET)
    public String saveEntityDetails(EntityCheckpointsVo entityCheckpointsVo) {
        return "success";
    }
}

Upvotes: 1

Views: 5123

Answers (2)

prem kumar
prem kumar

Reputation: 5877

If you try hitting following url, it will work.

localhost:8080/TestProject/entities/entities/add

This is because the first "entities" in the url is getting consumed because of /entities/* pattern in web.xml . After consuming this string then remaining path uri goes to dispatcher. In this case, entities/add goes to dispatcher and it works fine.


localhost:8080/TestProject/entities/add 

Whereas for the url mentioned by you "entities" gets consumed and only "add" is left for which dispatcher does not have mapping.

If you have a servlet mapping like following:

<url-pattern>/abc/def/*</url-pattern>

then in general for any spring request mapping with this pattern, url will be like:

localhost:8080/TestProject/abc/def/{custom request mapping}

For the url /entities/add request mapping, it will be:

localhost:8080/TestProject/abc/def/entities/add



Relevant class,method names and code snippets to show where consumptions happens from spring source code.

I could not find links. Therefore I went straight into the code. If you traverse these mentioned classes and methods in order you can see as to why it is consuming from path uri:

Snippets from Dispatcher Servlet and related classes:
1. org.springframework.web.servlet.DispatcherServlet getHandler(HttpServletRequest request)
2. org.springframework.web.servlet.handler.AbstractHandlerMapping getHandler(HttpServletRequest request)
3. org.springframework.web.servlet.handler.AbstractHandlerMapping getHandlerExecutionChain(Object handler, HttpServletRequest request) String lookupPath = this.urlPathHelper.getLookupPathForRequest(request);
4. org.springframework.web.util.UrlPathHelper getLookupPathForRequest(HttpServletRequest request) . Default value of this.alwaysUseFullPath=false is false. There consuming from path uri happens. You can the variable "rest" which will contain our spring request mapping like /entities/add in this post.
5. org.springframework.web.util.UrlPathHelper getPathWithinServletMapping(HttpServletRequest request) String path = getRemainingPath(pathWithinApp, servletPath, false);

public String getLookupPathForRequest(HttpServletRequest request) {
    // Always use full path within current servlet context?
    if (this.alwaysUseFullPath) {  // default this.alwaysUseFullPath=false
        return getPathWithinApplication(request);
    }
    // Else, use path within current servlet mapping if applicable
    String rest = getPathWithinServletMapping(request);
    if (!"".equals(rest)) {
        return rest;
    }
    else {
        return getPathWithinApplication(request);
    }
}

From here you can easily go deeper to find how it is consuming from path uri.

Upvotes: 1

Betlista
Betlista

Reputation: 10547

I can see the difference now...

@Controller(value="entities")
public class EntitiesController {

vs

@Controller
@RequestMapping(value = "/entity")
public class EntityController {

You do not have RequestMapping in EntitiesController... As you know probably, value in @Controller is logical name of the component...

Note: Based on prem kumar's answer I'm not sure whether this is a mistake or a design...

Upvotes: 1

Related Questions