404 Error from REST Endpoint in SpringMVC for DispatcherServlet - spring

RESOLVED PER THIS ANSWER
Spring invokes wrong controller mapping
Spring #Controllers URLs are always interpreted relative the the Spring Dispatcher Servlet that handles them. So if you map the dispatcher servlet to /api/ in web.xml then the URL to your controller above is /api/api/choice
The double string service/service/1234 was working.
ORIGINAL POST
Accessing a REST resource endpoint gives me a 404 error although everything seems to be defined correctly:
Log output:
DEBUG DispatcherServlet with name 'mvc-dispatcher' processing GET request for [/myapp/service/1234]
DEBUG Looking up handler method for path /1234
DEBUG Did not find handler method for [/1234]
WARN No mapping found for HTTP request with URI [/myapp/service/1234] in DispatcherServlet with name 'mvc-dispatcher'
web.xml
<servlet>
<servlet-name>mvc-dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextClass</param-name>
<param-value>org.springframework.web.context.support.AnnotationConfigWebApplicationContext</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>mvc-dispatcher</servlet-name>
<url-pattern>/service/*</url-pattern>
</servlet-mapping>
SpringMVC Controller
#RestController
#RequestMapping("/service")
public class RESTController {
#RequestMapping(value="/{id}", method=RequestMethod.GET)
public String getResult ( #PathVariable String id )
{
//... get JSON result
}
}
Expected invocation: myapp/service/1234
Also tried these options:
1) Don't define a class RequestMapping, just do a Method Request Mapping
#RequestMapping("/service/{id}")
2) as well as
#RequestMapping("/service*/{id}")
#RequestMapping("/service**/{id}")
Keep getting a 404 with the log above.

update your web.xml file :
<servlet-mapping>
<servlet-name>mvc-dispatcher</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>

Related

Using DispatcherServlet for RestController

I'm currently trying to understand how the Dispatcher Servlet works with the Rest Controller ,but Postman returns 404 on everything I tried thus far.
The rest controller
#RestController
#RequestMapping(value = "/applications")
public class ApplicationController {
private static final Logger logger = LoggerFactory.getLogger(ApplicationController.class);
#Autowired
#Qualifier("ApplDAO")
private ApplDAO applDAO;
#Autowired
ApplicationService objServices;
#RequestMapping(value = "for_user\\{username:\\d+}", method = RequestMethod.GET)
public Application getApp(#PathVariable("username") String username){
Application app = applDAO.getByUsername(username);
return app;
}
}
My web.xml
<!-- The definition of the Root Spring Container shared by all Servlets and Filters -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring4-servlet.xml</param-value>
</context-param>
<!-- Creates the Spring Container shared by all Servlets and Filters -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!-- Processes application requests -->
<servlet>
<servlet-name>springDispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet
</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring/appServlet/servlet-context.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>springDispatcher</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
I tried using url-pattern /* but with no results.
This is the url I was trying to access http://localhost:8080/project/applications/for_user/username:acid
Is there something wrong with the URL I'm using or have I used the dispatcher wrong.
Here is the spring error
No mapping found for HTTP request with URI [/project/applications/for_user/username:acid
Answered by JB Nizet
Why do you use backslashes instead of slashes in your RequestMapping?
Why do you use the regex \d+ if you want to send username:acid (or
acid?) as user name. Just use value = "/for_user/{username}", and use
http://localhost:8080/project/applications/for_user/acid.

Request Mapping returning error 404

This is my controller that maps a request to this url http://localhost:8080/SpringMVCJSON/rest/kfc/brands
contoller file
#Controller
#RequestMapping("/kfc/brands")
public class JSONController {
#RequestMapping(value = "{name}", method = RequestMethod.GET)
public #ResponseBody
Shop getShopInJSON(#PathVariable String name) {
Shop shop = new Shop();
shop.setName(name);
shop.setStaffName(new String[] { "name1", "name2" });
return shop;
}
this is the web.xml with the servlet request that dispatches the request/response along with the url
<display-name>Spring Web MVC Application</display-name>
<servlet>
<servlet-name>mvc-dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>mvc-dispatcher</servlet-name>
<url-pattern>/rest/*</url-pattern>
</servlet-mapping>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/mvc-dispatcher-servlet.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
Assuming that everything is alright, when I launch my app on this url it returns error 404 http://localhost:8080/SpringMVCJSON/rest/kfc/brands
My server console returns this warning
Apr 26, 2016 12:14:47 PM org.springframework.web.servlet.DispatcherServlet noHandlerFound
WARNING: No mapping found for HTTP request with URI [/SpringMVCJSON/rest/kfc/brands] in DispatcherServlet with name 'mvc-dispatcher'
Please why is tomcat not mapping request to the server?
You configured your controller to be available on /kfc/brands/{name} URL but trying to access it on /kfc/brands.
Here you can find more information about using #RequestMapping: http://docs.spring.io/autorepo/docs/spring/3.2.x/spring-framework-reference/html/mvc.html#mvc-ann-requestmapping

springmvc cannot call controller's method

Currently I got a problem when I configure my springmvc web project.
Below is my web.xml
<servlet>
<servlet-name>dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>0</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<url-pattern>/api/*</url-pattern>
</servlet-mapping>
And I defined my dispatcher-servlet.xml like this
<context:component-scan base-package="xxx.controller"
<mvc:annotation-driven />
And in package xxx.controller I define a class TestController
#Controller
#RequestMapping(value="/api")
public class TestController {
#RequestMapping(value = "/hello")
#ResponseBody
public String hello(){
System.out.println("comming hello");
return "hello world";
}
}
Now when I start tomcat, and want to access to localhost:8080/testproject/api/hello, The spring informs me
[10:10:58|WARN |(org.springframework.web.servlet.PageNotFound)]=[No mapping found for HTTP request with URI [/testproject/api/hello] in DispatcherServlet with name 'dispatcher']
But if I modify the url-pattern in web.xml to
<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
It is ok to access to localhost:8080/testproject/api/hello. I do not know why this happens. I do want to use /api/* rather than /.
Could anyone helps me configure the controller path mapping? Many thanks!
You are telling your application to run in /api context when you define the following:
<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<url-pattern>/api/*</url-pattern>
</servlet-mapping>
so to access your controller the URL would have to be localhost:8080/api/api/hello
Just get rid of the /api from your dispatcher as you have and then your mapping should automatically default to localhost:8080/api/hello and work.
<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
Otherwise if you want to run your application in /api context always you have the option of removing #RequestMapping(value="/api") from your controller.
That way it only recognises the mapping on method.

Spring request mapping: Matching with url pattern

I have a web application with Spring MVC.
web.xml
<servlet>
<servlet-name>spring</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>spring</servlet-name>
<url-pattern>*.do</url-pattern>
<url-pattern>/companies/*</url-pattern>
</servlet-mapping>
spring controller method:
class RealmInfoController{
#ResponseBody
#RequestMapping(value = {"/companies/{companyId}/realms/{realmName}"})
public RealmInfo realmInfo(#PathVariable long companyId, #PathVariable String realmName)
Handler match:
http://localhost:6122/context/companies/15877/realms/firstRealm
When the server gets this url, the spring servlet gets called. but it cannot match the controller method.
But if I change the request mapping to "/{companyId}/realms/{realmName}" then it matches the controller method. But it is not nice to define the url mapping without '/companies'. Can Spring be instructed in some way to look for match including the url pattern specified in the servlet?
Thanks.
if you want to use "companies" in request mapping you should map your dispatcher servlet to the root:
<url-pattern>/*</url-pattern>

SpringMVC: DispatcherServlet makes extra requests to view

I'm having a strange problem with Spring MVC. I have a simple controller like this:
#Controller
#RequestMapping("admin")
public class AdminController {
#RequestMapping(value = "", method = RequestMethod.GET)
public String home() {
return "home";
}
When I run my server and access the url: localhost/admin I get a 404 error. The view home.jsp exists and should be rendered. When I check my spring event log this is what shows up:
DEBUG: org.springframework.web.servlet.DispatcherServlet - DispatcherServlet with name 'appServlet' processing GET request for [/admin]
DEBUG: org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping - Looking up handler method for path /admin
DEBUG: org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping - Returning handler method [public java.lang.String be.roots.buildinginspector.web.controller.AdminController.home()]
DEBUG: org.springframework.beans.factory.support.DefaultListableBeanFactory - Returning cached instance of singleton bean 'adminController'
DEBUG: org.springframework.web.servlet.DispatcherServlet - Last-Modified value for [/admin] is: -1
DEBUG: org.springframework.web.servlet.DispatcherServlet - Rendering view [org.springframework.web.servlet.view.JstlView: name 'home'; URL [home]] in DispatcherServlet with name 'appServlet'
DEBUG: org.springframework.web.servlet.view.JstlView - Added model object 'domainOfExpertise' of type [be.roots.buildinginspector.business.model.DomainOfExpertise] to request in view with name 'home'
DEBUG: org.springframework.web.servlet.view.JstlView - Added model object 'org.springframework.validation.BindingResult.domainOfExpertise' of type [org.springframework.validation.BeanPropertyBindingResult] to request in view with name 'home'
DEBUG: org.springframework.web.servlet.view.JstlView - Forwarding to resource [home] in InternalResourceView 'home'
DEBUG: org.springframework.web.servlet.DispatcherServlet - DispatcherServlet with name 'appServlet' processing GET request for [/home]
DEBUG: org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping - Looking up handler method for path /home
DEBUG: org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping - Did not find handler method for [/home]
WARN : org.springframework.web.servlet.PageNotFound - No mapping found for HTTP request with URI [/home] in DispatcherServlet with name 'appServlet'
Everything is handled correctly but instead of just showing the view, the DispatcherServlet makes a new GET request to the url of the requested view name.
My web.xml:
<?xml version="1.0" encoding="UTF-8"?>
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
<!-- The definition of the Root Spring Container shared by all Servlets and Filters -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath*:/spring/config-core-business.xml
classpath*:/spring/config-app-security.xml
</param-value>
</context-param>
<!-- Spring Security filter -->
<filter>
<filter-name>springSecurityFilterChain</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
<filter-name>springSecurityFilterChain</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!-- Creates the Spring Container shared by all Servlets and Filters -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<listener>
<listener-class>org.springframework.web.util.Log4jConfigListener</listener-class>
</listener>
<!-- Processes application requests -->
<servlet>
<servlet-name>appServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath*:/spring/appServlet/config-core-web.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>appServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<filter>
<filter-name>hiddenHttpMethodFilter</filter-name>
<filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>hiddenHttpMethodFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
Relevant spring context parts (config-core-web.xml):
<resources mapping="/resources/**" location="../../../resources" />
<!-- Resolves views selected for rendering by #Controllers to .jsp resources
in the /WEB-INF/views directory -->
<beans:bean
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<beans:property name="prefix" value="/WEB-INF/views/"/>
<beans:property name="suffix" value=".jsp"/>
</beans:bean>
#Controller
#RequestMapping("admin")
public class AdminController {
#RequestMapping(method = RequestMethod.GET)
public String home() {
return "home";
}
remove 'value' property of #RequestMapping for home() function.
After all it turned out this was a tomcat-related issue. For some reason when I recreated the configuration in my IDE the error was resolved. Thanks for your help.
I think this is servlet mapping problem in web.xml. Change it in web.xml to /admin addreses only. Perhaps now you have:
<url-pattern>*</url-pattern>
change it to:
<url-pattern>/admin/*</url-pattern>
The request mapping annotation defined over your methode restrict your controller to responds to requests starting with "/admin/home".
I would apply the following modifications :
#Controller
#RequestMapping("/admin")
public class AdminController {
#RequestMapping(method = RequestMethod.GET)
public String home() {
return "home";
}
}
Try this:
#RequestMapping(value = "admin",
method = {RequestMethod.GET, RequestMethod.POST })

Resources