1

I have created a spring application (Spring version 3.2.8). The application is working fine but the issue which I am facing is that when I try to consume the controller service through url I am getting 404 error

The url which I try to consume through browser url is given below, which I expect to return a test string

http://localhost/Spring3Sample/user/getPersonDetails

My code is as given below

dispatcher-servlet.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:p="http://www.springframework.org/schema/p" 
    xsi:schemaLocation="http://www.springframework.org/schema/beans 
            http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
    <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver" 
          p:prefix="/" p:suffix=".jsp" />
</beans>

applicationContext.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="http://www.springframework.org/schema/beans 
            http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
            http://www.springframework.org/schema/context
            http://www.springframework.org/schema/context/spring-context-3.0.xsd">

    <context:component-scan base-package="com.controllers" />

</beans>

UserController.java

package com.controllers;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

@Controller
@RequestMapping("/user")
public class UserController {

    private static final String APP_JSON = "application/json";

    @RequestMapping(value = "/getPersonDetails", method = RequestMethod.GET, produces = APP_JSON)
    public String getPersonDetails() {
        return "test";
    }
}

web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
    id="WebApp_ID" version="2.5">
    <display-name>Spring3Sample</display-name>

    <welcome-file-list>
        <welcome-file>index.jsp</welcome-file>
    </welcome-file-list>

    <servlet>
        <servlet-name>dispatcher</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>

    <servlet-mapping>
        <servlet-name>dispatcher</servlet-name>
        <url-pattern>*.do</url-pattern>
    </servlet-mapping>

    <session-config>
        <session-timeout>1</session-timeout>
    </session-config>

    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>/WEB-INF/applicationContext.xml</param-value>
    </context-param>
</web-app>

Can anyone please tell me some solution for this

UPDATE 1

web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" version="3.0">
    <display-name>Spring3Sample</display-name>
:
:
:
Alex Man
  • 4,746
  • 17
  • 93
  • 178
  • Do u want this to be return as *Text in response body* ? If yes then add `@ResponseBody` on ur controller's method. – OO7 May 06 '15 at 12:03
  • @OO7 That's not going to help if the request is already 404ing... – beerbajay May 06 '15 at 12:03
  • I'm not sure if it's related, but you should look into using the servlet 3 spec and therefore also update your `web.xml` to use `xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" version="3.0"` – beerbajay May 06 '15 at 12:05
  • 1
    See u have mapped servlet with `*.do`. Access the page again by adding `.do` URL pattern like `http://localhost/Spring3Sample/user/getPersonDetails.do`. Since, u haven't mentioned `.do` the mapping of resources is not done & hence u get `HTTP Status 404`. – OO7 May 06 '15 at 12:07
  • @beerbajay I have updated my web.xml, check my update still getting 404 – Alex Man May 06 '15 at 12:21
  • @OO7 I have updated my web.xml like what beerbajay said, also tried tried with.do like `http://localhost/Spring3Sample/user/getPersonDetails.do` but still the same 404 error – Alex Man May 06 '15 at 12:23
  • @AlexMan Can you provide your client side code from where you called this REST call – Ranjeet May 06 '15 at 12:24
  • Do u missed to add port number in the URL ? – OO7 May 06 '15 at 12:24
  • @OO7 I am using apache server and port number is 8080 – Alex Man May 06 '15 at 12:25
  • Thats what I want. Please add `8080` port after localhost like `http://localhost:8080/Spring3Sample/user/getPersonDetails.do` – OO7 May 06 '15 at 12:26

5 Answers5

2

You have mapped the DispatcherServlet with URL pattern as

 <servlet-mapping>
    <servlet-name>dispatcher</servlet-name>
    <url-pattern>*.do</url-pattern>
</servlet-mapping>

Whenever you want t request a controller method you must have to add this URL pattern to the request. So that Spring will find the correct mapping this.

So change your request URL to following:-

http://localhost:8080/Spring3Sample/user/getPersonDetails.do

As you expect to return a test string:

Add the

@ResponseBody

annotation to ur controller's method. So that Spring wouldn't look for the JSP page with name test, instead return test as String.

EDIT:

From the discussion in chat:

Also u are missing <mvc:annotation-driven /> in applicationContext.xml.

To remove *.do from the request URL:

<servlet-mapping>
    <servlet-name>dispatcher</servlet-name>
    <url-pattern>/</url-pattern>
</servlet-mapping>
OO7
  • 2,785
  • 1
  • 21
  • 33
  • I am getting `Unable to connect` when I tried with `http://localhost:8080/Spring3Sample/user/getPersonDetails.do` but when I tried with `http://localhost/Spring3Sample/user/getPersonDetails.do` atleast I am getting 404 – Alex Man May 06 '15 at 12:28
  • Restart the `Apache Server` & try again & check whether u get the same error. – OO7 May 06 '15 at 12:31
  • restarted and tried.....I don't know what is the problem behind this, do I need to do any other modifications – Alex Man May 06 '15 at 12:35
  • Can u show the complete `HTTP Status 404` which u get while accessing this page ? – OO7 May 06 '15 at 12:36
  • How did call this method ? Is it `GET` or `POST` ? – OO7 May 06 '15 at 12:41
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/77089/discussion-between-oo7-and-alex-man). – OO7 May 06 '15 at 12:44
2

After observing your applicationContext.xml , I can see you are missing <mvc:annotation-driven/> Your Updated code will look like below

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:mvc="http://www.springframework.org/schema/mvc"
    xsi:schemaLocation="http://www.springframework.org/schema/beans 
            http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
            http://www.springframework.org/schema/context
            http://www.springframework.org/schema/context/spring-context-3.0.xsd"
               http://www.springframework.org/schema/mvc   http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd">                                            

    <context:component-scan base-package="com.controllers" />
    <mvc:annotation-driven/>  

</beans>

Explanation

<annotation-driven /> means that you can define spring beans dependencies without actually having to specify a bunch of elements in xml or implement an interface or extend a base class.Means @Controller tells spring that the the class specified contains methods that will handle http requests without you having to implement the Controller interface or extend a subclass that implements controller.

<context:component-scan base-package="com.controllers" /> tells spring that it should search the class path for all the classes under com.controllers and look at each class to see if it has a @Controller, or @Repository, or @Service, or @Component and if it does then Spring will register the class with the bean factory as if you have defined in in the xml configuration files

As per user comment

do we need both applicationContext.xml and dispatcher-servlet.xml

Actually Spring lets you define multiple contexts in a parent-child hierarchy.

applicationContext.xml defines the beans for the root webapp context means the context associated with the webapp.

dispatcher-servlet.xml defines the beans for one servlet's application context. There can be many dispatcher-servlet.xml in a webapp i.e servlet1-servlet.xml for servlet spring1, spring2-servlet.xml for servlet spring2

note:: Beans in spring-servlet.xml can reference beans in applicationContext.xml, but not vice versa.

Dev
  • 2,326
  • 24
  • 45
  • do we need both applicationContext.xml and dispatcher-servlet.xml – Alex Man May 06 '15 at 13:16
  • normally the applicationContext.xml context is unnecessary. It is generally used to contain beans that are shared between all servlets in a webapp. If you only have one servlet, then there's not really much point, unless you have a specific use for it. see my updated answer for more explanation – Dev May 06 '15 at 13:30
  • can we remove that.do extension – Alex Man May 06 '15 at 13:32
  • yes , but then your browser url with any extension like /getPersonDetails.do or /getPersonDetails.htm or /getPersonDetails.123 can access same controller see http://stackoverflow.com/questions/29778130/spring-controller-request-mapping-issue-for-dot-in-resource/29779554#29779554 for more detail – Dev May 06 '15 at 13:40
1
Ranjeet
  • 636
  • 6
  • 12
  • Check whether your server is running or not?? – Ranjeet May 06 '15 at 12:28
  • I am getting Unable to connect when I tried with http://localhost:8080/Spring3Sample/user/getPersonDetails but when I tried with http://localhost/Spring3Sample/user/getPersonDetails.do atleast I am getting 404 – Alex Man May 06 '15 at 12:29
  • server is running fine – Alex Man May 06 '15 at 12:29
  • Restart server or fresh install Tomcat and check – Ranjeet May 06 '15 at 12:33
  • restarted and tried.....I don't know what is the problem behind this, do I need to do any other modifications – Alex Man May 06 '15 at 12:35
  • Make sure Tomcat is running on a port that is not being used in that moment by another program or service. It may be necessary to change Tomcat’s port which is 8080 by default. Skype and many other programs also attempt to use port 8080. If you are having problems, change Tomcat’s port to be safe. – Ranjeet May 06 '15 at 12:38
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/77088/discussion-between-ranjeet-and-alex-man). – Ranjeet May 06 '15 at 12:39
1

First in Spring MVC manual

The @Controller annotation acts as a stereotype for the annotated class, indicating its role. The dispatcher scans such annotated classes for mapped methods and detects @RequestMapping annotations (see the next section).

So delete this

@RequestMapping("/user")

Because it makes no sense next

@RequestMapping("/user/getPersonDetails")

you should note I add "/user" to url. Also you are not return any jSon. First if I were you I change second request mapping (on the method getUserDetails) with string I put in this answer.

And looks like you miss with config files... Check this string in web.xml

<url-pattern>*.do</url-pattern>

it will dispatch only urls with ".do" at their end.

P_M
  • 2,723
  • 4
  • 29
  • 62
1

I added this to my config class that extends WebMvcConfigurer:

  @Bean
    public ViewResolver viewResolver() {
        final InternalResourceViewResolver bean = new InternalResourceViewResolver();

        bean.setViewClass(JstlView.class);
        bean.setPrefix("/WEB-INF/view/pages/");
        bean.setSuffix(".jsp");

        return bean;
    }

You'll have to add this dependency for it to work:

<dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>jstl</artifactId>
            <version>1.2</version>
</dependency>
parsecer
  • 4,758
  • 13
  • 71
  • 140