SpringMVC: DispatcherServlet makes extra requests to view - spring

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 })

Related

Spring controllers not found

I am unable to call spring MVC controller. Everytime I hit it, it says not found.
My files are as following.
Web.xml
<servlet>
<servlet-name>spring</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet
</servlet-class>
<load-on-startup>1</load-on-startup>
<async-supported>true</async-supported>
</servlet>
<servlet-mapping>
<servlet-name>spring</servlet-name>
<url-pattern>/gk1</url-pattern>
</servlet-mapping>
spring-servlet.xml
<mvc:annotation-driven />
<context:component-scan base-package="com.gkool" />
<bean
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix">
<value>/WEB-INF/views/</value>
</property>
<property name="suffix">
<value>.jsp</value>
</property>
<property name="viewClass"
value="org.springframework.web.servlet.view.JstlView" />
</bean>
<mvc:resources mapping="/resources/**" location="/resources/" />
</beans>
My controller file
package com.gkool;
#Controller
#RequestMapping("/score")
public class ScoreController {
Logger log = Logger.getLogger(ScoreController.class);
#RequestMapping(value = "", method = RequestMethod.GET)
public String printWelcome(ModelMap model) {
model.addAttribute("message", "Spring 3 MVC Hello World");
return "hello";
}
#RequestMapping(value = "/hello/{name}", method = RequestMethod.GET)
public ModelAndView hello(#PathVariable("name") String name) {
ModelAndView model = new ModelAndView();
model.setViewName("hello");
model.addObject("msg", name);
return model;
}
}
when I start sever and hit URL http://localhost:8080/gk1/score or http://localhost:8080/gk1/score/hello/anoop It gives error code 404 not found.
P.S. /gk1 is module name in tomcat.
When I start the tomcat server it gives following logs
org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping registerHandlerMethod
INFO: Mapped "{[/score/hello/{name}],methods=[GET],params=[],headers=[],consumes=[],produces=[],custom=[]}" onto public org.springframework.web.servlet.ModelAndView com.gkool.ScoreController.hello(java.lang.String)
Feb 07, 2017 10:37:11 PM org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping registerHandlerMethod
INFO: Mapped "{[/score],methods=[GET],params=[],headers=[],consumes=[],produces=[],custom=[]}" onto public java.lang.String com.gkool.ScoreController.printWelcome(org.springframework.ui.ModelMap)
Feb 07, 2017 10:37:12 PM org.springframework.web.servlet.handler.SimpleUrlHandlerMapping registerHandler
INFO: Mapped URL path [/resources/**] onto handler 'org.springframework.web.servlet.resource.ResourceHttpRequestHandler#0'
That means it identifies a mapped URL as /score/hello/{name} but when I start my server in debug and put a debugger breakpoint in the controller method, the debug control doesn't come there.
can anyone please help?
Check if you've defined the context web within the tomcat configuration of your application:
<Context docBase="/path/to/myapp.war" path="/myContext" reloadable="true"/>
Now execute the request like this:
http://localhost:8080/myContext/gk1/score/hello/anoop
But if you've defined like:
<Context docBase="/path/to/myapp.war" path="/gk1" reloadable="true"/>
Then in the web.xml servlet configuration you just have to define the servlet mapping like this:
<servlet-mapping>
<servlet-name>spring</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
Fix your Spring configuration.
<mvc:annotation-driven />
is a configuration element.
This is required for Spring to "find" your controllers:
<context:component-scan base-package="your.controller.package"/>
Per the Sotirios Delimanolis comment, the following configuration
<servlet-mapping>
<servlet-name>spring</servlet-name>
<url-pattern>/gk1</url-pattern>
</servlet-mapping>
Tells tomcat to send requests with exactly match this URL: http://localhost:8080/gk1 to the spring servlet.
<servlet-mapping>
<servlet-name>spring</servlet-name>
<url-pattern>/gk1/*</url-pattern>
</servlet-mapping>
Which tells tomcat to send any request that starts with the URL http://localhost:8080/gk1 to spring.
The * is the difference between: "exactly match" and "starts with".

404 Error from REST Endpoint in SpringMVC for DispatcherServlet

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>

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

Custom HTTP Error 404 - Annotation based setting Spring 3.2

Is it possible to implement annotation based custom HTTP 404 error page using Spring 3.2.1?
I looked for ways in various forums but couldn't find any clear answer.
I also tried configuring using web.xml but it is not working when I access unmapped URL.
Any help please?
Log output
7259 [DEBUG] org.springframework.web.servlet.DispatcherServlet - DispatcherServlet with name 'spring-test' processing GET request for [/spring-test/ss]
7261 [DEBUG] org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping - Looking up handler method for path /ss
7262 [DEBUG] org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping - Did not find handler method for [/ss]
7262 [WARN ] org.springframework.web.servlet.PageNotFound - No mapping found for HTTP request with URI [/spring-test/ss] in DispatcherServlet with name 'spring-test'
7262 [DEBUG] org.springframework.web.servlet.DispatcherServlet - Successfully completed request
web.xml
<web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
id="rest" version="3.0" metadata-complete="true">
<!-- The definition of the Spring Container shared by all Servlets and Filters -->
<context-param>
<param-name>contextClass</param-name>
<param-value>org.springframework.web.context.support.AnnotationConfigWebApplicationContext</param-value>
</context-param>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>main.java.net.bornil.config</param-value>
</context-param>
<!-- Processes application requests -->
<servlet>
<servlet-name>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>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>main.java.net.bornil.config</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<!-- Creates the Spring Container shared by all Servlets and Filters -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<welcome-file-list>
<welcome-file />
</welcome-file-list>
<error-page>
<error-code>404</error-code>
<location>/errors/404</location>
</error-page>
</web-app>
Controller
#Controller
#RequestMapping(value = "/errors")
public class CommonExceptionHandler {
private static Logger log = Logger.getLogger(CommonExceptionHandler.class.getName());
#RequestMapping(method = RequestMethod.GET, value = "/{code}")
public ModelAndView handleException(#PathVariable int code) {
if (log.isDebugEnabled()) {
log.debug("ERROR CODE IS: " + code);
}
return new ModelAndView("errors/404");
}
}
I had the same issue. I've a simple webapp, single page and, after spending a morning on the Spring forum (so nice you cannot search '404' there because it's just 3 chars long) and Google this is the best solution I found.
Assuming you have a index.jsp and a 404.jsp, my #Configuration' has:
#Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/").setViewName("index");
registry.addViewController("/*").setViewName("404");
}

How do I map this URL to a Spring controller method?

I'm using Spring 3.1.1.RELEASE. I'm having fits mapping URLs to controller methods. I would like to map the URL "/my-context-path/organizations/add" to the controller method below. In my controller, I have
#Controller
#RequestMapping("/organizations")
public class OrganizationController
{
…
#RequestMapping(value = "/add", method = RequestMethod.GET)
public ModelAndView doGetadd()
{
… do some stuff …
return new ModelAndView("organizations/add");
} // doGetadd
In my web.xml I have
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
version="2.5">
<display-name>SB Admin</display-name>
<servlet>
<servlet-name>dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>2</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<url-pattern>/organizations/*</url-pattern>
</servlet-mapping>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/dispatcher-servlet.xml</param-value>
</context-param>
and in my dispathcer-servlet.xml I have
...
<!-- Enable annotation driven controllers, validation etc... -->
<mvc:annotation-driven />
<context:component-scan base-package="org.myco.subco" />
<bean id="viewResolver"
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix">
<value>/WEB-INF/views/</value>
</property>
<property name="suffix">
<value>.jsp</value>
</property>
</bean>
but requests for my desired context-path result in "No mapping found for HTTP request with URI [/myproject-1.0-SNAPSHOT/organizations/add] in DispatcherServlet with name 'dispatcher" errors (using JBoss 7). How do I map this thing properly? Note that I have multiple methods in my controller that I want to different URLs within the "/organizations" space.
Try this.
Change the dispatcher servlet mapping to :
<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
And for the OrganizationController the mapping would be
#Controller
#RequestMapping("/organizations")
public class OrganizationController
And for the ContractsController the mapping would be
#Controller
#RequestMapping("/contracts")
public class OrganizationController
According to the Spring Doc the ModelAndView constructor parameter is the name of the view file.
So that file could be addView.jsp .
As well as the fact that you're (as far as my Spring knowledge goes) actually mapping it to /Application-Name/organizations/organizations/add due to :
<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<url-pattern>/organizations/</url-pattern>
</servlet-mapping>
And
#Controller
#RequestMapping("/organizations")
public class OrganizationController
I'd recommend changing the requestmapping from the controller to
#Controller
#RequestMapping("/")
public class OrganizationController
The <url-pattern>/organizations/</url-pattern> basiccally defines the 'virtual path' on which your site will be accessible.
Al mappings you do on controllers will append to it, makeing it /organizations/whateverpagecomeshere.jsp
And make sure that View file exists !

Resources