I'm going through this online course about Spring MVC.
During the course the instructor is adding a simple controller, and a simple jsp page.
In addition the application class is extending SpringBootServletInitializer.
my index.html file is found in src/main/webapp and my jsp file is found in src/main/webapp/WEB-INF/jsp
I've also added spring.mvc.view.prefix/suffix accordingly.
for some reason when i get to this point at the course, extending the SpringBootServletInitializer is causing whitelabel error to my main view (index.html) but the path to jsp file is working just fine.
I've tried some suggestions as changing #Controller to #RestController or removing the SpringBootServletInitializer but it didn't work (removing the SpringBootServletInitializer caused 404 when looking for the jsp page).
here is my code:
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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.4.5</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.pluralSight</groupId>
<artifactId>conference</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>war</packaging>
<name>conference</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>11</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
controller:
package com.pluralSight.conference.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import java.util.Map;
#Controller
public class GreetingController {
#GetMapping("greeting")
public String greeting(Map<String, Object> model){
model.put("message","Hello Daniel");
return "greeting";
}
}
application class:
package com.pluralSight.conference;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
#SpringBootApplication
public class ConferenceApplication extends SpringBootServletInitializer{
public static void main(String[] args) {
SpringApplication.run(ConferenceApplication.class, args);
}
}
application.properties:
spring.mvc.view.prefix=/WEB-INF/jsp/
spring.mvc.view.suffix=.jsp
Related
I'm new to spring boot and trying to learn how to implement graphql. #GetMapping and #PostMapping work as normal but when I try to use #QueryMapping or #SchemaMapping, following the Spring documentation I get the whitelabel error page. Playing around I'm able to guess that it's not recognizing these two as mapping. I've checked my dependencies but I'll include them below in case, I've verified the project structure, and I've also tried changing from #Controller to #RestController to no avail.
Controller file
package com.example.GraphQLBooks.controller;
import com.example.GraphQLBooks.model.Book;
import com.example.GraphQLBooks.repository.BookRepository;
import org.springframework.graphql.data.method.annotation.QueryMapping;
import org.springframework.graphql.data.method.annotation.SchemaMapping;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
#RestController
public class BookController {
private final BookRepository bookRepository;
public BookController(BookRepository bookRepository) {
this.bookRepository = bookRepository;
}
//This works with #RestController but breaks with #Controller
#GetMapping("/test")
public String controllerTest(){
return "Hello";
}
//#SchemaMapping(typeName = "Query",value = "allBooks")
#QueryMapping
public List<Book> findAll() {
return bookRepository.findAll();
}
}
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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.7.2</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.example</groupId>
<artifactId>GraphQL-Books</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>GraphQL-Books</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>17</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-graphql</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webflux</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.graphql</groupId>
<artifactId>spring-graphql-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.graphql-java</groupId>
<artifactId>graphql-java</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
application.properties
spring.graphql.graphiql.enabled=true
I tested the repositories using #GetMapping and they output as expected and when I got to my "/test" mapping it outputs Hello as expected. Any insight and tips are appreciated, and let me know if more info is needed.
Figured it out. My schema had a typo had schema.graphql instead of schema.graphqls and it should be localhost:8080/graphiql not localhost:8080/graphql dumb mistakes I know. And you can't use #RestController with graphql has to be #Controller which makes sense because we're not using a Rest Api.
Had similar issue. The problem was graphqls file wasn't placed in the right folder.
Spring boot graphQL looks for the graphqls file in the following directory by default: ~/src/main/resources/graphql/schema.graphqls
I started learning Spring Framework and get this kind of error while running localhost:8080
Whitelabel Error Page
This application has no explicit mapping for /error, so you are seeing this as a fallback.
Controller.java
package com.springFramework.helloGame.controller;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
#RestController
public class Controller {
#GetMapping("/sum")
public long displaySum(){
return 100;
}
}
HelloGameApplication.java
package com.springFramework.helloGame;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.ComponentScan;
#SpringBootApplication
public class HelloGameApplication {
public static void main(String[] args) {
ConfigurableApplicationContext context =
SpringApplication.run(HelloGameApplication.class, args);
}
}
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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.5.4</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.springFramework</groupId>
<artifactId>helloGame</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>helloGame</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>11</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
my project structure looks fine, but don't know why I got error!
Please help me!
The Whitelabel page is a spring error handling method and it tries to hint to you that you do have a mapping for /error.
Now coming to the issue you need to write #RequestMapping("/") above your get mapping in the controller so that the spring knows the base URI.
It's an entry point for the spring application for the browser.
Now you have written /sum get URI and in the browser, you are trying for http://localhost:8080
So for the above Uri to work you need to provide #RequestMapping("/")
or you can use http://localhost:8080/sum with you current code.
It seems your controller only have a mapping for "/sum" path. Try querying localhost:8080/sum.
new to spring boot application development. I ran the application as java application and got the below error. THe application is deployed successfully , I don't know why this error is rendered ... beating my head.. thank you for your help in advance.
Whitelabel Error Page This application has no explicit mapping for
/error, so you are seeing this as a fallback. Sat Jul 13 21:37:31 IST
2019 There was an unexpected error (type=Not Found, status=404). No
message available
tried solutions given on stack overflow but no help. could you please help me if anywhere I do wrong here.
package com.cpi.poc.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.cpi.poc.service.IService;
#RestController
#RequestMapping(value ="/test")
#ComponentScan(basePackages = "com.cgi.poc")
public class TestController {
#Autowired
IService service;
#RequestMapping(value = "/greet" , method = RequestMethod.GET)
public String testService(){
String result = service.greet();
return result;
}
}
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/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.21.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.cgi.poc</groupId>
<artifactId>test</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>test</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
Check whether you have class :
#SpringBootApplication
#ComponentScan("com.cgi.poc")
#ComponentScan
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
No need to put component scan on controller if you have the above class.
Verify by using lsof command that your java service is running on the port on not.
Parent POM
<?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/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.sit</groupId>
<artifactId>multi-module</artifactId>
<version>0.0.1-SNAPSHOT</version>
<modules>
<module>one</module>
<module>app</module>
</modules>
<packaging>pom</packaging>
<name>multi-module</name>
<description>Demo project for Spring Boot</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.4.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
app module POM
spring boot main class resides on this module
<?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/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>multi-module</artifactId>
<groupId>com.sit</groupId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>app</artifactId>
<dependencies>
</dependencies>
</project>
One module (child module) POM
<?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/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>multi-module</artifactId>
<groupId>com.sit</groupId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>one</artifactId>
<packaging>jar</packaging>
<dependencies>
</dependencies>
</project>
Spring Boot Main Class from app module
package com.sit.app;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.domain.EntityScan;
import org.springframework.context.annotation.ComponentScan;
#SpringBootApplication
#ComponentScan(basePackages = {"com.sit"})
#EntityScan(basePackages = {"com.sit"})
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class,args);
}
}
AppController from app module
package com.sit.app.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
#Controller
public class AppController {
#GetMapping(value = "/app")
public String getPage(){
return "app";
}
}
OneController class from one module
package com.sit.one.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
#Controller
public class OneController {
#GetMapping(value = "/one")
public String getPage(){
return "one";
}
}
When I run the project AppController.java is working fine by "/app" url.But when I try to access "/one" url of OneController.java ,I got the error page.No #Controller or #RestController is working from child (one) module.To solve this issue I added #ComponentScan(basePackages = {"com.sit"}) in Application.java, but still I am getting the error page.Can any help please.Thanks in advance.
The issue is that com.sit:one is not on the classpath of com.sit:app. Due to this, none of the classes of the one module can be found when you start the application module.
The solution is to make sure that the com.sit:one module is a dependency of com.sit:app by adding the following to pom.xml of the application module:
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>one</artifactId>
<version>${project.version}</version>
</dependency>
However, this is not enough, since the spring-boot-maven-plugin will create a fat JAR of both modules, while you only need a fat JAR of your application module (the runnable module).
I suggest that you move the <plugin> to the pom.xml of the application module:
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
And then you should remove the plugin from the parent pom.xml.
This is the whole 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/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>war</packaging>
<name>demo</name>
<description>Demo project for Spring Boot</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.4.0.RELEASE</version>
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
<start-class>com.example.Application</start-class>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
The Application class should be like this
Application.java
package com.example;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.stereotype.Controller;
import org.springframework.boot.web.support.SpringBootServletInitializer;
#SpringBootApplication
#Controller
public class Application extends SpringBootServletInitializer {
/**
* Used when run as JAR
*/
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
#RequestMapping("/")
public #ResponseBody String hello(){
return "hello world!";
}
/**
* Used when run as WAR
*/
#Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {
return builder.sources(Application.class);
}
}
The whole project is as you can see as above.However,the main method can not run if I set the scope
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
</dependency>
to provided.But if I remove the scope,the main method can run normally.The question is what should I do to run the main method without removing the scope.
In maven, when you omit the scope it defaults to compile.
When you are running outside a servlet container (i.e as a java
application) you need to provide the scope of compile (or remove scope as compile is the default). This is done so that these jars are added as dependency.
When you run within a servlet container (tomcat or jetty), then the scope could be set as provided as these jars are provided at runtime by the servlet container and should not be included within the packaged application.
Now, in order to solve the problem at hand you could use maven profiles. When executing maven tasks you could activate the profile by using the -P switch.