1

I am trying to create a simple Spring MVC to view main-menu.jsp but I have problem and I do not how to fix it. I am using Intellij and create project by Maven.

Here is my structure of my project

src
  - main 
      - java 
        - com.example.mvc
           - HomeController.java
      -resources
  - webapp
      - WEB-INF
        - view 
            - main-menu.jsp
        - applicationContext.xml
        - web.xml

My pom.xml

<?xml version="1.0" encoding="UTF-8"?>

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">

  <modelVersion>4.0.0</modelVersion>
  <packaging>war</packaging>

  <name>Demo</name>
  <properties>
    <maven.compiler.source>18</maven.compiler.source>
    <maven.compiler.target>18</maven.compiler.target>
  </properties>
  <groupId>org.example</groupId>
  <artifactId>Demo</artifactId>
  <version>1.0-SNAPSHOT</version>

  <build>
    <plugins>
      <plugin>
        <groupId>org.mortbay.jetty</groupId>
        <artifactId>maven-jetty-plugin</artifactId>
        <version>6.1.7</version>
        <configuration>
          <connectors>
            <connector implementation="org.mortbay.jetty.nio.SelectChannelConnector">
              <port>8888</port>
              <maxIdleTime>30000</maxIdleTime>
            </connector>
          </connectors>
          <webAppSourceDirectory>${project.build.directory}/${pom.artifactId}-${pom.version}</webAppSourceDirectory>
          <contextPath>/</contextPath>
        </configuration>
      </plugin>
    </plugins>
  </build>

  <dependencies>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-webmvc</artifactId>
      <version>5.3.20</version>
    </dependency>

    <!-- https://mvnrepository.com/artifact/org.springframework/spring-context -->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-context</artifactId>
      <version>5.3.20</version>
    </dependency>

    <!-- https://mvnrepository.com/artifact/org.springframework/spring-core -->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-core</artifactId>
      <version>5.3.20</version>
    </dependency>

    <!-- https://mvnrepository.com/artifact/javax.servlet/javax.servlet-api -->
    <dependency>
      <groupId>javax.servlet</groupId>
      <artifactId>javax.servlet-api</artifactId>
      <version>4.0.1</version>
      <scope>provided</scope>
    </dependency>

  </dependencies>

</project>

My web.xml

<?xml version="1.0" encoding="UTF-8"?>

<web-app version="2.4"
         xmlns="http://java.sun.com/xml/ns/j2ee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">

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

  <context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>/WEB-INF/applicationContext.xml</param-value>
  </context-param>

  <listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
  </listener>

  <servlet-mapping>
    <servlet-name>DispatcherServlet</servlet-name>
    <url-pattern>/</url-pattern>
  </servlet-mapping>

</web-app>

My 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:util="http://www.springframework.org/schema/util"
       xmlns:configurator="http://cocoon.apache.org/schema/configurator"
       xmlns:avalon="http://cocoon.apache.org/schema/avalon" xmlns:mvc="http://www.springframework.org/schema/cache"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
                           http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-2.0.xsd
                           http://cocoon.apache.org/schema/configurator http://cocoon.apache.org/schema/configurator/cocoon-configurator-1.0.1.xsd
                           http://cocoon.apache.org/schema/avalon http://cocoon.apache.org/schema/avalon/cocoon-avalon-1.0.xsd http://www.springframework.org/schema/cache http://www.springframework.org/schema/cache/spring-cache.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">


    <context:component-scan base-package="com.example.mvc"></context:component-scan>
    <mvc:annotation-driven />
    <bean id="handlerMapping" class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"/>
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/WEB-INF/view/" />
        <property name="suffix" value=".jsp" />
    </bean>
</beans>

My HomeController.java

package com.example.mvc;


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


@Controller
public class HomeController {

    @RequestMapping(value = "/hello")
    public String getPage(){
        return "main-menu";
    }
}

Finally, My main-menu.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
    <h2>Spring MVC demo</h2>
</body>
</html>

I try to run in Tomcat server in Intellij , And It give me 404 error like this

Error Image

Thank you for helping me fix this

4 Answers 4

5

Tomcat 10 does not work with Spring 5 due to the fact that Tomcat 10 is working with jakarta packages, which were renamed from javax.

Spring 5 does not work with jakarta packages, Spring 6 will support that. So with that in mind:

  1. Spring 5 + Tomcat 9
  2. Spring 6 + Tomcat 10

Also from the picture that you provided your url should be

localhost:8080/spring_war_exploaded/hello

not

localhost:8080/hello

To be sure which URL can be you can go to your Tomcat configuration > Edit > and check "After Launch" and select Google Chrome for an example, that will launch the app with the correct URL.

"Why _war_exploded" That is mainly how IntelliJ likes to call artifact when creating Artifact > Web Exploaded, so if it is spring it will add _war_exploded, it is a default setting

Sign up to request clarification or add additional context in comments.

5 Comments

Why do you think, that the rootcontext should be set to spring_war_exploded?
That is mainly how intellij likes to call artifact when deploying it, so if it is spring it will add _war_exploded, it is a default setting
it will be a great addition to your answer. Optimally you could add the property which needs to be set to override the default generated rootcontext.
But to be sure, he can set "After Launch" and Intellij will pop the window with the URL of server and artifact
Spring 6 + Tomcat 10 worked in my case. I was using Spring 5 with Tomcat 9. Now that I have updated the Tomcat version everything works. I can also see the servlet being initialized in the logs org.springframework.web.servlet.FrameworkServlet.initServletBean Initializing Servlet 'HelloWeb'. Thumbs up
1

The directory webapp should be inside main, not in the same parent directory.

As per convention, we place our JSP files in the ${project.basedir}/main/webapp/WEB-INF/jsp/ directory.

https://www.baeldung.com/spring-boot-jsp#view-resolver-configuration

1 Comment

Oh, sr my bad. Actually, webapp is inside the main :-). It still inside and it still have a problem
0

Try to add this dependency first. It will automatically configure your web application and DispatcherServlet. You do not need your web.xml file anymore. Also, you can delete your webapp package. Everything will be done by Spring Boot.

<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-web</artifactId>
  <version>2.7.0</version>
</dependency>

Then, create a class annotated with @SpringBootApplication. It will start your application, and your @RestController class will be detected and scanned.

@SpringBootApplication
public class RunApp {
    
    public static void main(String[] args) {
        SpringApplication.run(RunApp.class, args);
    }
}

Also, you do not need your applicationContext.xml file anymore. Spring Boot takes responsibility for this. Spring Boot creates its own ApplicationContext and contains all the controllers and other beans.

Here, you can learn everything in more detail: https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/

Good luck!

2 Comments

Thank you about this solution. It is a good solution but I want to create it from scratch to understand more about Spring MVC so I try to do this. Do you have any idea to fix my problem ?
You're trying to run the application by using Tomcat, but you're using Jetty Plugin in pom.xml. Try to configure a Tomcat server. Install the Smart Tomcat plugin if you're using Intellij IDEA (go to settings -> plugins -> Smart Tomcat). If you use another IDE, then download Tomcat from the Apache web page and import it into your project. tomcat.apache.org/download-90.cgi
0

if you are working with Spring MVC structure using the eclipse link and facing this error then please make sure that you add @Singleton annotation in your controller bcoz @singleton is used to define the scope of an object of your class and when you use singleton it means that you are defining a scope to use the same object everywhere no need to create a new object for all the time.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.