9

Ok, I know there are like 20 posts here with the same problem, but none of them seem to help me, so this will probably be a duplicate, but I've gone over all the other posts and none of them solved my problem, so there must be something that I'm doing wrong or I'm not doing the right modifications from the answers of the previous mentioned questions.

I'm trying to make a small application using Spring, and I'm still experimenting with it, but I've spent like 4 days trying to figure what's wrong and I just can't. I still get a HTTP Status 404 whenever I try to get a jsp back from the controller. Nothing but 404 status through Tomcat, nothing else...

WebAppController:

@Controller
public class WebAppController {

    @RequestMapping(value="/login", method = RequestMethod.GET)
    public String login() {
        System.out.println("You have entered the login maprequest");
        return "test1";
    }

}

web.xml:

    <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns="http://java.sun.com/xml/ns/javaee"
    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>Hotel Application</display-name>
    <servlet>
        <servlet-name>WebApp</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>WebApp</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>
    <welcome-file-list>
        <welcome-file>login.jsp</welcome-file>
    </welcome-file-list>
</web-app>

webApp.xml:

   <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.1.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd">
    <context:component-scan base-package="com.iquestgroup" />

    <bean
        class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix">
            <value>/jsp/</value>
        </property>
        <property name="suffix">
            <value>.jsp</value>
        </property>
    </bean>
</beans>

This configuration works in a simple maven project with only the above mentioned in it. The problem is, the exact same thing isn't working in a maven project with 3 modules(persistence, service and webapp). In the webapp i've copied the exact same thing and when I run it on server I get 404 http status... even though the modules are building with success.

L.E. The first part of the accepted answer refers to a common servlet mapping mistake made by those who are starting with Spring. My problem was not related to it and I ended up removing it after initial answer. In order to not become confusing for readers, the first part of the accepted answer refers to the following code:

<servlet-mapping>
     <servlet-name>dispatcher</servlet-name>
     <url-pattern>/*</url-pattern>
</servlet-mapping>
Dragos Geornoiu
  • 527
  • 2
  • 8
  • 17
  • You edited the problem `/*` out of the question! Now the answer makes no sense. It says to change the `/*` but _that ***doesn't appear*** in the question_ any more. – Stephen P May 16 '16 at 22:26
  • @StephenP The question was edited after initial response and I announced that in the answer's comment. It seemed pointless to keep the /* even though that wasn't my problem and there are many more questions on Stack Overflow which refer to exactly that. I understand your point of view and I think you are right, it can be confusing, so I will add a mention of that at the end of the question. – Dragos Geornoiu May 16 '16 at 22:59

2 Answers2

6

Change

<url-pattern>/*</url-pattern>

to

<url-pattern>/</url-pattern>

Currently, your mapped DispatcherServlet is marked as handling all requests because of /*. This means that it will also attempt to handle a request dispatched to /WEB-INF/jsp/test1.jsp. It obviously doesn't have a handler for that and will fail.

The pattern / is special in that it is the default fallback if no other pattern matches. If there's a Servlet that maps to the request path, that Servlet will be chosen before your mapped DispatcherServlet.

Most (probably all) Servlet containers come mapped with a Servlet to handle rendering JSPs with the url-pattern of *.jsp. That will take precedence over your DispatcherServlet mapped to /.

If you're still getting 404 after these changes, then there are a few possibilities.

Spring logs at the INFO level any handler methods (@RequestMapping annotated methods within @Controller beans) it registers. If you don't see any of those in your logs, then your web application hasn't been deployed correctly/successfully.

If your Servlet container is embedded in your IDE, check the appropriate tab/view on the apps that are deployed. If it's standalone, check that your generated .war file is in the appropriate directory and expanded correctly.

Sotirios Delimanolis
  • 274,122
  • 60
  • 696
  • 724
  • I changed / to /* from an answer to another question similar to mine, I previously had it like you said, but it still didn't work. – Dragos Geornoiu Dec 01 '14 at 15:53
  • @drag Then we will need more details. Turn your Spring logs to DEBUG, send a request and post the results as an edit to your question. – Sotirios Delimanolis Dec 01 '14 at 15:57
  • @drag Also please clarify which URL you're sending the request to. – Sotirios Delimanolis Dec 01 '14 at 16:04
  • I'm trying to send to "http://localhost:8080/HotelApplication/" or "http://localhost:8080/HotelApplication/test1" and nothing happens. (HotelApplication is the name of the project). I'm still trying to figure out how to turn the spring logs to Debug, I didn't use them nor did I set them up before in Spring, so that might take a little time... – Dragos Geornoiu Dec 01 '14 at 16:12
  • @DragosGeornoiu Describe _nothing happens_. Look at your Servlet container logs. What do they log when you start the app? What package is your `UserController` in? – Sotirios Delimanolis Dec 01 '14 at 16:13
  • By nothing happens I mean i get the HTTP Status 404 (description - The requested resource is not available). The UserController is in package package com.iquestgroup.webapp. – Dragos Geornoiu Dec 01 '14 at 16:22
  • @DragosGeornoiu Also, get rid of your `ContextLoaderListener` and the corresponding `context-param`. It's pointlessly creating duplicate beans right now. – Sotirios Delimanolis Dec 01 '14 at 16:45
  • I've edited the question. I've tried the above thing (after I've edited it a little) and in a simple maven project it works, but when I put the exact same thing in the webapp module of my project, I get only 404 http status. Still no idea what to do – Dragos Geornoiu Dec 01 '14 at 18:49
  • @DragosGeornoiu When Spring starts up, if you've configured logging correctly with slf4j and logback or log4j, it will tell you at INFO level if it registers a handler method for the path `/login`. Do you see anything like that? If not, you may be deploying your app incorrectly. – Sotirios Delimanolis Dec 02 '14 at 01:12
  • That's the problem I guess. It doesn't. In the single model version it does, in the tri-module one it doesn't. I just can't figure out why. The code is the same and the modules are build succesfully, the dependency between them seems to be also good, judging by the maven tree.. – Dragos Geornoiu Dec 02 '14 at 06:49
  • That was the problem, the deployment wasn't done correctly, just 2 minutes in "Deployment Assembly" and it's fixed now! Thank you very much, can't believe I ended up wasting 4 days on this. Could you edit a little your answer with the check for /login handler so I can accept it? – Dragos Geornoiu Dec 02 '14 at 07:43
  • @DragosGeornoiu I've edited with those suggestions. Note that you'd still have the 404 had you stayed with the `/*`. That should be the most important part of the answer. – Sotirios Delimanolis Dec 02 '14 at 15:21
1

First of all, you can listen / request with any root controller like below.

@Controller
@RequestMapping ("/")
public class RootCtrl {

Logger logger = Logger.getLogger(RootCtrl.class);

@RequestMapping (value = "/", method = {RequestMethod.GET, RequestMethod.POST})
public String index(ModelMap model) {

    // redirect to login page
    return "redirect:admin/index";
}}

With that controller, you will map all requests to root. Than you may redirect request to your login controller.

It's all about request mapping. Your loginController or webController shold listen a request which should be specified before. In my application, login controller listens /admin request paths. Than, my login controller is like this:

@Controller
@RequestMapping ("/admin")
public class LoginCtrl {

@RequestMapping (value = "/index", method = {RequestMethod.GET, RequestMethod.POST})
public String index(@RequestParam (value = "captchaId", defaultValue = "") String captchaId, ModelMap model, HttpServletRequest request, HttpServletResponse response) {

    if(StringUtils.isNullOrEmpty(captchaId)){
        captchaId = RandomGUID.getRandomGUID();
    }

    model.addAttribute("captchaId", captchaId);

    // redirect to login page
    return "login";
}

When you will get request from this path : localhost/SampleProject/admin/index. Mappings will work.

Ziac
  • 21
  • 6
  • Thank you for your answer, but the controller was ok, it wasn't something very complex, just a test one to see if everything is working fine (and this time it wasn't). The problem was that I didn't deploy correctly the application, as sugested by @Sotirios Delimanolis – Dragos Geornoiu Dec 02 '14 at 16:17