Spring Boot JSP 404
Asked Answered
S

16

63

I'm trying to add a jsp page in my Spring Boot service. My problem is that every time I try to go to that page I have this:

Whitelabel Error Page

This application has no explicit mapping for /error, so you are seeing this as a fallback.

Tue Apr 21 23:16:00 EEST 2015 There was an unexpected error (type=Not Found, status=404). No message available

I have added the prefix and sufix into my application.properties:

spring.view.prefix: /WEB-INF/jsp/
spring.view.suffix: .jsp

This is my controller class:

@Controller
public class MarkerController {
    @RequestMapping(value="/map")
    public String trafficSpy() {
        return "index";
    }
}

My Application class:

@SpringBootApplication
public class Application extends SpringBootServletInitializer {
    private static Logger logger = Logger.getLogger(Application.class.getName());

    public static void main(String[] args) {
            logger.info("SPRING VERSION: " + SpringVersion.getVersion());
            SpringApplication.run(Application.class, args);
        }
}

And the index.jsp:

<!DOCTYPE html>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<html lang="en">

<body>
    <h1>Hello, World!!!</h1>


    <p>JSTL URL: ${url}</p>
</body>

</html>

And this is the src file structure:

├── src
│   ├── main
│   │   ├── java
│   │   │   └── com
│   │   │       └── example
│   │   │           └── internetprogramming
│   │   │               └── myserver
│   │   │                   └── server
│   │   │                       ├── Application.java
│   │   │                       ├── config
│   │   │                       │   └── DatabaseConfig.java
│   │   │                       ├── controller
│   │   │                       │   └── MarkerController.java
│   │   │                       ├── dao
│   │   │                       │   ├── MarkerDaoImplementation.java
│   │   │                       │   └── MarkerDaoInterface.java
│   │   │                       ├── Marker.java
│   │   │                       └── service
│   │   │                           ├── MarkerServiceImplementation.java
│   │   │                           └── MarkerServiceInterface.java
│   │   ├── resources
│   │   │   └── application.properties
│   │   └── webapp
│   │       └── WEB-INF
│   │           └── jsp
│   │               └── index.jsp
Sirup answered 21/4, 2015 at 20:53 Comment(3)
What is the URL you are trying to access?Marie
localhost:8080/map I added a debug print in the method and it prints the message so the method is called.Sirup
To anyone having 404 Whitelabel Error Page when running from IntelliJ IDEA on multi-module build (i.e. you're running one of subproject apps having these JSPs). Open run configuration and make sure that working directory points to subproject dir, not the root one! I've spent two hours trying to figure out why it still producing 404 even on a minimal sample project perfectly working from maven mvn spring-boot:run. Hope this will help to someone ;)Catlee
S
82

Ensure that you have jasper and jstl in the list of dependencies:

    <dependency>
        <groupId>org.apache.tomcat.embed</groupId>
        <artifactId>tomcat-embed-jasper</artifactId>
        <scope>provided</scope>
    </dependency>
    <dependency>
        <groupId>javax.servlet</groupId>
        <artifactId>jstl</artifactId>
    </dependency>

Here is a working starter project - https://github.com/spring-projects/spring-boot/tree/master/spring-boot-samples/spring-boot-sample-web-jsp

Schaffel answered 21/4, 2015 at 22:11 Comment(10)
That was it! I had the jstl dependency but not the jasper. It worked after adding it. Thank you!Sirup
Also! For others with similar problems when using Spring Boot 1.3.0 you have likely missed that spring.view.prefix and spring.view.suffix properties have changed name to spring.mvc.view.prefix and spring.mvc.view.prefix respectively. More info here.Ausgleich
I had the same problem. In my case, I also had to remove the provided scope from the tomcat-embed-jasper dependency before it worked!Tonjatonjes
I had the same problem too,But it doesn't work for me.here is my project github.com/Ryanqy/learn-java .What can I doPusillanimity
@Tonjatonjes the provided scope may cause issues in production tomcat environments as tomcat provides those libraries already. I fixed this using a profile embedded-tomcat with the custom property tomcat-embed-jasper.scope and setting it as runtime. by default this is provided when not running embedded mode. i.e. <dependency><groupId>..</..><artifactId>embed-tomcat-jasper</..><scope>${tomcat-embed-jasper.scope}</..></..>Goulden
If you are using intellij change scope of tomcat-embed-jasper dependency from <scope>provided</scope> to <scope>compile</scope>. Works for me!Semicolon
How exactly does this solve the 404 error? Would really like to know.Flintshire
Adding these 2 dependencies worked for me.However, we did not need to add these dependencies before spring-boot. So, why is it necessary now?Reprobate
The working starter project link is broken.Develop
I already had this dependency, and it still doesn't work. Why? 🤔 Here's the repo: github.com/NadChel/CRUD_user_bootCareful
H
30

In newer versions of Spring, following needs to be put in application.properties file:

spring.mvc.view.prefix=/WEB-INF/jsp/
spring.mvc.view.suffix=.jsp

Also, JSP files need to be put under src/main/resources/META-INF/resources/WEB-INF/jsp

Hothouse answered 22/2, 2017 at 6:7 Comment(6)
That fixed it for meKeratosis
sure, however this is merely configuration and whilst effective in most common scenarios, it only reflects the desired location of your jsps. I could set these to spring.mvc.view.prefix=/WEB-INF/foo/bar/jsp and place all my jsps there if i wanted.Goulden
@Goulden actually trying arbitrary folders within the resources folder did NOT work for me in springboot 2.0 application, I had to put the exact folder structure as Ajitesh used for it to finally work. I wish your solution would work as it's more flexible.Borage
Thanks, @Ajitesh. I searched many related answers / documents and spent many times on stackoverflow and Spring website. This is the only workable solution for me😭 My workable Spring Boot example commit is here: github.com/MrMYHuang/SpringBootExample/commit/… Does anyone have a way to debug this problem? For example, making Spring Boot print all view search paths? I think it's worthless for human spending so much time and electricity on this problem? 😥Winer
I use IntelliJ IDEA debugger and a JSP with a syntax error (for getting the file parsing exception stacktrace and then use debugger to find the JSP search paths) to find out the logic used by Spring Boot to locate JSP resources! The logic is written in this file: github.com/spring-projects/spring-boot/blob/…Winer
Thank you much! This part was the key I was missing Also, JSP files need to be put under src/main/resources/META-INF/resources/WEB-INF/jsp. I wish they didn't make so many breaking changes. I have yet to find a tutorial on this that isn't broken and I always try to start with the newest one I can find :-( I suppose JSP isn't exactly top priority anymore though.Goblet
D
14

This is working solution for me about White label error page : Cannot find view page(jsp)

At POM.xml, Make sure packaging is "war" and add tomcat/jasper dependencies

<packaging>war</packaging>
<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-tomcat</artifactId>
            <scope>provided</scope>
        </dependency>

    <dependency>
        <groupId>org.apache.tomcat.embed</groupId>
        <artifactId>tomcat-embed-jasper</artifactId>
        <scope>provided</scope>
    </dependency>

Add prefix/suffix at application.properties

spring.mvc.view.prefix=/WEB-INF/views/
spring.mvc.view.suffix=.jsp

** If you use Intellij, you must set Web Resource directories. At Project Structure (ctrl+alt+shift+ S) > Facets > Select Web(your application) > Add(+) Web Resource Directories ( mine is ......\src\main\webapp)

** If you have multiple modules(At intellij), Run> Edit configuration> Select springboot your application > Configuration tab> Working directory as $MODULE_WORKING_DIR$

Disenthrall answered 19/5, 2019 at 6:16 Comment(3)
Setting the %MODULE_WORKING_DIR% configuration value fixed it for me. Thanks!Muniments
Me too, after a lot of wasted time the $MODULE_WORKING_DIR$ conf in Idea fixed it. Many thanksKyat
5 years later, this ended our odyssey. Thanks, this fixed everything.Deannedeans
P
12

Here is simple project with the minimum config: java 17 + spring boot 3.0.5 + JSP - https://github.com/uamaxua/spring-boot-jsp-sample

We were adding Spring Boot to our system in order to run it as executable application without standalone tomcat and also faces the 404 status during JSP initialization.
What should be done for fixing it:

a) Add dependencies to your pom file (WARNING: tomcat-embed-jasper must have compile scope not provided):

<parent>
 <groupId>org.springframework.boot</groupId>
     <artifactId>spring-boot-starter-parent</artifactId>
     <version>2.3.3.RELEASE</version>
     <relativePath/>
 </parent>
 <dependencies>
   <dependency>
     <groupId>org.springframework.boot</groupId>
     <artifactId>spring-boot-starter-web</artifactId>
   </dependency>
   <dependency>
     <groupId>javax.servlet</groupId>
     <artifactId>jstl</artifactId>
   </dependency>
   <dependency>
     <groupId>org.apache.tomcat.embed</groupId>
     <artifactId>tomcat-embed-jasper</artifactId>
   </dependency>
 <dependencies>

b) Add spring boot maven plugin for building your application:

<build>
    <plugins>
      <plugin>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-maven-plugin</artifactId>
      </plugin>
    </plugins>
</build>

c) Check that you are using *.war file for your artifact, not jar (because of JSP support limitation):

<packaging>war</packaging>

e) Now you should be able to run your spring boot application using maven plugin or with command line - java -jar /you/path/application-name.war: enter image description here

f) But if you are using multi-module maven project and want to run spring boot application using IntelliJ Idea it is important to change "Working directory" -> $MODULE_DIR$:
enter image description here

UPDATE 24.02.2023: If you are spring boot >= 2.4.0 then you need some extra configuration:

  1. The DefaultServlet provided by the embedded Servlet container is no longer registered by default (more information - here). But for JSP we need to register it again (with spring properties or java config):
server.servlet.register-default-servlet=true

OR


@Bean WebServerFactoryCustomizer
enableDefaultServlet() {
    return factory -> factory.setRegisterDefaultServlet(true);
}
  1. Default Spring MVC no longer performs .* suffix pattern matching where a controller mapped to /person is also implicitly mapped to /person.*. As a consequence path extensions are no longer used to interpret the requested content type for the response — for example, /person.pdf, /person.xml, and so on (more information - here and here).
    It is not recommended to use an extension in URL now. But if you need to use URL with suffix something like: http://localhost:8080/home.jsp then you need to add such configuration:

import org.springframework.context.annotation.Configuration;
import org.springframework.http.MediaType;
import org.springframework.web.servlet.config.annotation.ContentNegotiationConfigurer;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@EnableWebMvc
@Configuration
public class WebMvcConfig implements WebMvcConfigurer {
    
        @Override
        public void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
            configurer.ignoreAcceptHeader(false)
                    .useRegisteredExtensionsOnly(true)
                    .defaultContentType(MediaType.TEXT_HTML)
                    .mediaType("jsp", MediaType.TEXT_HTML);
        }
}

And specify extension in your controller mapping:

@GetMapping("/home.jsp")
Piper answered 14/9, 2020 at 14:17 Comment(9)
Perfect. This setting did the trick and saved me. I wish I could have seen this thread and the reply a few hours ago, than even on the JetBrains Website in their documentation and manual.Acey
After 2 days of googling! Finally! Thankyou sir!Publicness
what ever you have said i have added in my project in intellij , still same error. Could you please helpBenediction
user2949241, yes after updating spring boot to the latest version this approach does not help((( Add your answer if tou find the solution.Piper
@Benediction I have updated configs for the new spring boot.Piper
Unfortunately, it didn't help me: github.com/NadChel/CRUD_user_bootCareful
@SergeyZolotarev I guess you fixed it, because JSP is working fine - ibb.co/WKCLsxy?Piper
@Piper yes, I did. I even wrote an answer about it: https://mcmap.net/q/301753/-spring-boot-jsp-404. I can't say I understand why the form is dead in the center of the page on your screenshot, but other than that it's expected behaviorCareful
@Maksym, I followed all the steps mentioned above, but didn't help. Exported the project to eclipse and tried. Works good. Here I posted the question https://mcmap.net/q/303501/-jsp-not-found-status-404-whitelabel-error-page-resourcehttprequesthandler-quot-path-with-quot-web-inf-quot-or-quot-meta-inf-quot-web-inf-jsps-createlocation-jsp-quot/11962586Dawson
E
8

If you are using IDEA development tools, then you can try specifying

Configurations -> Configuration -> environment -> Working directory

The value in $MODULE_DIR$

Essayistic answered 2/8, 2019 at 3:57 Comment(2)
It seems that in IntelliJ 2019.X the $MODULE_DIR$ is replaced with $MODULE_WORKING_DIR$Onrush
You are a lifesaver. Thank you!Disarm
S
5

My issue was that I was using @RestController instead of @Controller as the annotation in my controller class. Hope this can help someone out.

Shanan answered 2/8, 2016 at 21:12 Comment(0)
G
4

my issue was Spring vesrion : I found that since 1.4.3 version and above stops supporting the embedded JSPs . So I change version to 1.4.1 , it's worked for me.

an other thing take off :

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>

it will not work with it .

Gwalior answered 2/4, 2017 at 14:38 Comment(0)
S
2

In addition to the answers above the application needs to be deployed as war instead jar

<groupId>com.igt</groupId>
<artifactId>customer</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>war</packaging>

to run

java -jar customer-0.0.1-SNAPSHOT.war

Also If you intend to start your application as a war or as an executable application, you need to share the customizations of the builder in a method that is both available to the SpringBootServletInitializer callback and the main method, something like

package com.igt.customer;

import java.util.Arrays;

import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;



@SpringBootApplication
public class CustomerApplication extends org.springframework.boot.web.support.SpringBootServletInitializer {


    @Override
    protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
        return application.sources(CustomerApplication.class);
    }

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



     @Bean
        public CommandLineRunner commandLineRunner(ApplicationContext ctx) {
            return args -> {

                System.out.println("Let's inspect the beans provided by Spring Boot:");

                String[] beanNames = ctx.getBeanDefinitionNames();
                Arrays.sort(beanNames);
                for (String beanName : beanNames) {
                    System.out.println(beanName);
                }

            };
        }


}

Please see

this

Sloatman answered 20/8, 2017 at 11:45 Comment(0)
I
1

To have this in pom.xml

<!-- JSP -->
<dependency>
    <groupId>org.apache.tomcat.embed</groupId>
    <artifactId>tomcat-embed-jasper</artifactId>
    <scope>provided</scope>
</dependency>
<!-- jstl for jsp -->
<dependency>
    <groupId>javax.servlet</groupId>
    <artifactId>jstl</artifactId>
</dependency>

It may be not enough.

You must not miss this.

<packaging>war</packaging>

Otherwise when you build the package, you will get as a jar file and that does not have JSP nor the embedded tomcat.

See runable example and its explanation here https://www.surasint.com/spring-boot-jsp/

Inshrine answered 13/12, 2017 at 20:31 Comment(0)
C
1

In case you've been struggling with this for a while and nothing helps, hear me out! I may help you! I've been there: I searched through the internet and was growing pretty desperate, but then I did this, and the problem vanished 🙌

  1. You must have this Tomcat dependency
        <dependency>
            <groupId>org.apache.tomcat.embed</groupId>
            <artifactId>tomcat-embed-jasper</artifactId>
        </dependency>

Notice that it has a default scope. The default scope is compile. It is important that you have this scope!

  1. You should have these JSP/JSTL dependencies, both of them (at least, if you use something like a forEach tag)!
        <dependency>
            <groupId>jakarta.servlet.jsp.jstl</groupId>
            <artifactId>jakarta.servlet.jsp.jstl-api</artifactId>
            <version>3.0.0</version>
            <scope>provided</scope>
        </dependency>

        <dependency>
            <groupId>org.glassfish.web</groupId>
            <artifactId>jakarta.servlet.jsp.jstl</artifactId>
            <version>3.0.1</version>
            <scope>provided</scope>
        </dependency>

Notice that they belong to the jakarta package. In my case, it was important! Maybe, it may be important in your case too. Before I migrated my project to Spring Boot, I used javax dependencies, specifically these two

        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>3.1.0</version>
            <scope>provided</scope>
        </dependency>
    
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>jstl</artifactId>
            <version>1.2</version>
        </dependency>

When trying to open my home page with those dependencies, I received error 500

java.lang.ClassNotFoundException: javax.servlet.jsp.tagext.TagLibraryValidator

I added some more javax dependencies to appease Spring a little

        <dependency>
            <groupId>javax.servlet.jsp.jstl</groupId>
            <artifactId>jstl-api</artifactId>
            <version>1.2</version>
        </dependency>

        <dependency>
            <groupId>javax.servlet.jsp</groupId>
            <artifactId>jsp-api</artifactId>
            <version>2.2</version>
            <scope>provided</scope>
        </dependency>

and it still didn't work in Spring Boot! This time, I received ClassCastException because apparently Spring needed something specifically from the jakarta package

java.lang.ClassCastException: class org.apache.taglibs.standard.tlv.JstlCoreTLV cannot be cast to class jakarta.servlet.jsp.tagext.TagLibraryValidator (org.apache.taglibs.standard.tlv.JstlCoreTLV and jakarta.servlet.jsp.tagext.TagLibraryValidator are in unnamed module of loader 'app')
  1. MOST IMPORTANTLY! It appears you do need a webapp package when working with JSP views! I thought that since it's Spring Boot, I don't need that directory and may place my views in the resources/templates folder as HTML/Thymeleaf folks do. BIG MISTAKE! Even when my properties looked like this
spring.mvc.view.prefix=/templates/
spring.mvc.view.suffix= .jsp

or like this

spring.mvc.view.prefix=classpath:/templates/
spring.mvc.view.suffix= .jsp

in fact, any way you could imagine (I tried to describe the directory in all possible ways), I still got that pesky 404! Not before I created a webapp directory had I managed to get rid of that problem

enter image description here

Notice that tiny bluish circle on the webapp folder icon. I have a suspicion that it's important. As a matter of fact, I did try to create such a directory before, but it didn't have that little circle and moving my JSPs there had no effect on my 404. Why it didn't have that circle the first time? I don't know! But at any rate I suspect that the webapp package should be in the same directory as your source root. In this case, it's the java package. So since it's in the main folder, your webapp directory should be in the main folder too

Fun fact! My favicon and CSS stylesheet are still in the resources directory (that is, in the resources/static directory)! Despite that, Spring has no problem figuring out where they are. So the webapp package is necessary only for your JSPs (perhaps, you can store CSSs and favicons there too, I didn't try it, but at least you don't have to)

enter image description here

enter image description here

Why it works this way with JSP? Search me! I have no idea at all! But it's what helped me and what you should apparently do too if you experience the same issue

You can get in touch with me and request the project's repo if that's something you need 👌

UPD: A quick note. Some folks maintain that you need to have a WAR package for JSP projects. It doesn't appear so! But keep it in mind anyway. If you did every thing I listed and it still doesn't work, tweaking that property may be a good thing to try 🤷‍♂️

enter image description here

UPD2: After I removed the WAR packaging setting, the little circle on the webapp icon disappeared. But the page still opens! So since you apparently don't need WAR packaging, you also shouldn't be concerned about the blue circle. I take that back! Or maybe, the circle has nothing to do with WAR at all as I briefly returned that property and clean-installed the project, and it didn't appear again 🤷‍♂️

enter image description here

UPD3: By the way, that underlining never went away. But it's okay! It works nonetheless

enter image description here

Careful answered 23/3, 2023 at 12:8 Comment(0)
G
0

Spring MVC offers no default (fall-back) error page out-of-the-box. The most common way to set a default error page has always been the SimpleMappingExceptionResolver (since Spring V1 in fact). However Spring Boot also provides for a fallback error-handling page.

At start-up, Spring Boot tries to find a mapping for /error. By convention, a URL ending in /error maps to a logical view of the same name: error. Generally this view maps in turn to the error.html Thymeleaf template. (If using JSP, it would map to error.jsp according to the setup of your InternalResourceViewResolver).


Spring Boot will automatically use and configure Thymeleaf as the view rendering engine, as long as it's on the classpath.

Thymeleaf with Maven:

Make sure you have Maven 3 installed with the following command: mvn --version. Navigate to the directory you want to create your project in and execute Maven archtetype:

mvn archetype:generate -DarchetypeArtifactId=maven-archetype-quickstart -DgroupId=pl.codeleak.demos.sbt -DartifactId=spring-boot-thymeleaf -interactiveMode=false

The above command will create a new directory spring-boot-thymeleaf. Now you can import it to your IDE. The next step is to configure the application. Open pom.xml and add a parent project:

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>1.1.8.RELEASE</version>
</parent>

Values from the parent project will be the default for this project if they are left unspecified. The next step is to add web dependencies. In order to do so, I firstly removed all previous dependencies (junit 3.8.1 actually) and added the below dependencies:

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-thymeleaf</artifactId>
    </dependency>
</dependencies>

Now, wait a second until Maven downloads the dependencies and run mvn dependency:tree to see what dependencies are included. The next thing is a packaging configuration. Let's add Spring Boot Maven Plugin:

<build>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
        </plugin>
    </plugins>
</build>

Thymeleaf with Gradle:

To put Thymeleaf on the classpath use

compile("org.springframework.boot:spring-boot-starter-thymeleaf")

in the gradle build file (using the relevant maven dependency is straightforward).

In your case in order to display the index.jsp view (in accordance to the controller you are using), you need to place it under src/main/resources/templates/.


If no mapping from /error to a View can be found, Spring Boot defines its own fall-back error page - the so-called Whitelabel Error Page (a minimal page with just the HTTP status information and any error details, such as the message from an uncaught exception).

Garin answered 21/4, 2015 at 22:7 Comment(1)
Thank you for your detailed answer but I don't want to map from /error. I want index.jsp to be returned and rendered when go to <whatever my adress is>/mapSirup
S
0

You can use thymeleaf with jsp but you have to write:

spring.thymeleaf.excluded-view-names=#jsp file without extension

in application.properties file

Steinway answered 8/11, 2017 at 19:19 Comment(0)
D
0

For me, it seemed to be an eclipse issue. I was able to start the springboot app using java -jar outside the IDE.

Delirious answered 4/12, 2019 at 6:49 Comment(0)
E
0

Make sure your .jsp page is under WebContent:

WebContent|-
          |-Jsp
             |-home.jsp
Epinephrine answered 1/8, 2020 at 13:38 Comment(0)
F
0

For spring-boot, Jsp templates or Thymeleaf templates mapping of spring MVC mapping prefix into classpath.

Ex. /views/some_path needs to be located in the project src/main/resources/META-INF/resources/views/some_path

  • Thymeleaf templates work also in URL-based path file:///some_path
  • Jsp templates don't work in URL-based path file:///some_path
Fulminate answered 22/9, 2022 at 18:38 Comment(0)
P
-3

Try and add your error jsp files under error folder.

application.properties
spring.mvc.view.prefix=/views/jsp/
spring.mvc.view.suffix=.jsp

jsp files :
/views/jsp/error/401.jsp
/views/jsp/error/404.jsp - to display 404 instead of default whitelabel page
Pasley answered 24/10, 2017 at 12:1 Comment(1)
And where is the answer for the problem related above?Marienthal

© 2022 - 2024 — McMap. All rights reserved.