Unable to Hit Rest Controller Spring Boot - java

I have below pom.xml in the SpringBoot application. While running the application, I am not facing any errors. But when I am hitting the URL through postman or browser, then my java code present inside controller is not getting executed.
pom.xml:
<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>
<groupId>com.example</groupId>
<artifactId>MENU-RIGHT</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.1.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>
<maven-jar-plugin.version>3.1.1</maven-jar-plugin.version>
</properties>
<dependencies>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.26</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
</project>
Controller:
package com.example.controller;
import java.util.logging.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import com.example.model.MenuRightModel;
import com.example.service.MenuRightService;
#RestController
public class MenuRightController {
Logger logger = Logger.getAnonymousLogger();
#Autowired
private MenuRightService menuRightService;
#RequestMapping(value = "/getRightByUser/{id}", method=RequestMethod.GET)
public MenuRightModel findRightByUser(#PathVariable("id") int id) {
logger.info("Request Received for User Id : "+id);
return menuRightService.findRightByUser(id);
}
#RequestMapping(value = "/getRightAll", method=RequestMethod.GET)
public MenuRightModel findAllRight() {
return new MenuRightModel();
}
}
Project Execution Screenshot:
Postman Execution Screenshot:
Spring Boot Application Class:
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.context.annotation.ComponentScan;
#SpringBootApplication(exclude = {DataSourceAutoConfiguration.class })
#ComponentScan("src/main/java")
public class MenuRightApplication {
public static void main(String[] args) {
SpringApplication.run(MenuRightApplication.class, args);
}
}
Spring Boot Repository Class:
package com.dbs.repository;
import org.springframework.stereotype.Repository;
import com.example.model.MenuRightModel;
import org.springframework.data.jpa.repository.JpaRepository;
#Repository
public interface MenuRightRepository extends JpaRepository<MenuRightModel, Integer>{
MenuRightModel findByUserId(int id);
}
After Adding BasePackage as com.example facing below Exception:
2022-03-21 09:51:35.169 WARN 20560 --- [ restartedMain] ConfigServletWebServerApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'menuRightController': Unsatisfied dependency expressed through field 'menuRightService'; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'menuRightServiceImpl': Unsatisfied dependency expressed through field 'menuRightRepository'; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'com.example.repository.MenuRightRepository' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {#org.springframework.beans.factory.annotation.Autowired(required=true)}
2022-03-21 09:51:35.172 INFO 20560 --- [ restartedMain] o.apache.catalina.core.StandardService : Stopping service [Tomcat]
2022-03-21 09:51:35.189 INFO 20560 --- [ restartedMain] ConditionEvaluationReportLoggingListener :
Error starting ApplicationContext. To display the conditions report re-run your application with 'debug' enabled.
2022-03-21 09:51:35.312 ERROR 20560 --- [ restartedMain] o.s.b.d.LoggingFailureAnalysisReporter :
APPLICATION FAILED TO START
Description:
Field menuRightRepository in com.example.service.impl.MenuRightServiceImpl required a bean of type 'com.example.repository.MenuRightRepository' that could not be found.
The injection point has the following annotations:
- #org.springframework.beans.factory.annotation.Autowired(required=true)
Action:
Consider defining a bean of type 'com.example.repository.MenuRightRepository' in your configuration.

I am sure it is your main class configuration issue. By default, framework will scan beans in same package as of main class and sub-packages. e.g. below will not work
com/example/controller/FooController.java
com/example/main/MainClass.java
as applciation will scan for beans in com.example.main package and its subpackages only.
If that is case, you will need to update 'scanBasePackages' attribute of #SpringBootApplication annotation.

You need to add a package name in the component scan, in your case, it is #ComponentScan("com.example.controller"), Standard way to create other packages is
under the main root package

Related

Package not found when create data source using camel

I tried to replicate the same example given in the following question.
import javax.sql.DataSource;
import org.apache.camel.main.Main;
import org.apache.camel.builder.RouteBuilder;
import org.apache.commons.dbcp.BasicDataSource;
public class JDBCExample {
private Main main;
public static void main(String[] args) throws Exception {
JDBCExample example = new JDBCExample();
example.boot();
}
public void boot() throws Exception {
// create a Main instance
main = new Main();
// enable hangup support so you can press ctrl + c to terminate the JVM
main.enableHangupSupport();
String url = "jdbc:oracle:thin:#MYSERVER:1521:myDB";
DataSource dataSource = setupDataSource(url);
// bind dataSource into the registery
main.bind("myDataSource", dataSource);
// add routes
main.addRouteBuilder(new MyRouteBuilder());
// run until you terminate the JVM
System.out.println("Starting Camel. Use ctrl + c to terminate the JVM.\n");
main.run();
}
class MyRouteBuilder extends RouteBuilder {
public void configure() {
String dst = "C:/Local Disk E/TestData/Destination";
from("direct:myTable")
.setBody(constant("select * from myTable"))
.to("jdbc:myDataSource")
.to("file:" + dst);
}
}
private DataSource setupDataSource(String connectURI) {
BasicDataSource ds = new BasicDataSource();
ds.setDriverClassName("oracle.jdbc.driver.OracleDriver");
ds.setUsername("sa");
ds.setPassword("devon1");
ds.setUrl(connectURI);
return ds;
}
}
I have included the camel-jdbc-3.0.1.jar and my db specific jar file in my class path.
When I try to compile the code using the following command
javac -cp .;D:\Code\bin JDBCExample.java
I am getting the following error.
JDBCExample.java:2: error: package org.apache.camel.main does not exist
import org.apache.camel.main.Main;
^
JDBCExample.java:3: error: package org.apache.camel.builder does not exist
import org.apache.camel.builder.RouteBuilder;
^
JDBCExample.java:4: error: package org.apache.commons.dbcp does not exist
import org.apache.commons.dbcp.BasicDataSource;
Where am I going wrong? I tried adding camel-core to the classpath, but it didn't help.
Kindly let me know your thoughts, thanks in advance.
You did well by adding camel-core to your classpath, but camel-core and camel-jdbc do not suffice, you should also add the following dependencies:
JDBCExample.java:2: error: package org.apache.camel.main does not exist
import org.apache.camel.main.Main;
Add camel-main dependency
JDBCExample.java:4: error: package org.apache.commons.dbcp does not exist
import org.apache.commons.dbcp.BasicDataSource;
Add commons-dbcp dependency
JDBCExample.java:3: error: package org.apache.camel.builder does not exist
import org.apache.camel.builder.RouteBuilder;
Add camel-core dependency
With these and the camel-jdbc dependency, you are good to go.
I suggest that you use maven to handle your dependencies (and much more) if you can... If you have not used it before this five minutes quickstart will gently introduce you to it.
Here is a sample pom.xml that resolves all these dependencies correctly
<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>
<groupId>demo</groupId>
<artifactId>camel-jdbc-demo</artifactId>
<packaging>jar</packaging>
<version>1.0-SNAPSHOT</version>
<name>camel-jdbc-demo</name>
<url>http://maven.apache.org</url>
<dependencies>
<!-- https://mvnrepository.com/artifact/commons-dbcp/commons-dbcp -->
<dependency>
<groupId>commons-dbcp</groupId>
<artifactId>commons-dbcp</artifactId>
<version>1.4</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.camel/camel-main -->
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-main</artifactId>
<version>3.0.1</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.camel/camel-core -->
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-core</artifactId>
<version>3.0.1</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.camel/camel-jdbc -->
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-jdbc</artifactId>
<version>3.0.1</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>

Error when implementing springboot with H2db

I am new to coding. I am getting below error when trying to run java application in springboot with H2db.
[ERROR] Tests run: 1, Failures: 0, Errors: 1, Skipped: 0, Time elapsed: 8.777 s <<< FAILURE! - in com.example.demo.DemoApplicationTests
[ERROR] contextLoads(com.example.demo.DemoApplicationTests) Time elapsed: 0.002 s <<< ERROR!
java.lang.IllegalStateException: Failed to load ApplicationContext
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'entityManagerFactory' defined in class path resource [org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaConfiguration.class]: Invocation of init method failed; nested exception is org.hibernate.service.spi.ServiceException: Unable to create requested service [org.hibernate.engine.jdbc.env.spi.JdbcEnvironment]
Caused by: org.hibernate.service.spi.ServiceException: Unable to create requested service [org.hibernate.engine.jdbc.env.spi.JdbcEnvironment]
Caused by: org.hibernate.HibernateException: Access to DialectResolutionInfo cannot be null when 'hibernate.dialect' not set
[INFO]
[INFO] Results:
[INFO]
[ERROR] Errors:
[ERROR] DemoApplicationTests.contextLoads ยป IllegalState Failed to load ApplicationCon...
[INFO]
[ERROR] Tests run: 1, Failures: 0, Errors: 1, Skipped: 0
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] BUILD FAILURE
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 13.028 s
[INFO] Finished at: 2019-05-26T22:46:54+05:30
[INFO] ------------------------------------------------------------------------
[ERROR] Failed to execute goal org.apache.maven.plugins:maven-surefire-plugin:2.22.2:test (default-test) on project demo: There are test failures.
[ERROR]
[ERROR] Please refer to C:\Users\v\Desktop\demo\target\surefire-reports for the individual test results.
[ERROR] Please refer to dump files (if any exist) [date].dump, [date]-jvmRun[N].dump and [date].dumpstream.
[ERROR] -> [Help 1]
[ERROR]
[ERROR] To see the full stack trace of the errors, re-run Maven with the -e switch.
[ERROR] Re-run Maven using the -X switch to enable full debug logging.
[ERROR]
[ERROR] For more information about the errors and possible solutions, please read the following articles:
[ERROR] [Help 1] http://cwiki.apache.org/confluence/display/MAVEN/MojoFailureException
Here is my 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>2.1.5.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.example</groupId>
<artifactId>demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>demo</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-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>runtime</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>
Application :
package com.example.demo;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.domain.EntityScan;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import com.example.demo.StudentRepository;
#SpringBootApplication
#EntityScan("com.example.demo.Student")
#EnableJpaRepositories("com.example.demo.StudentRepository")
public class H2demoApplication implements CommandLineRunner {
// mvn spring-boot:run
private Logger LOG = LoggerFactory.getLogger("H2demoApplication");
StudentRepository studentRepository;
#Autowired
public H2demoApplication(StudentRepository studentRepository) {
this.studentRepository = studentRepository;
}
public static void main(String[] args) {
SpringApplication.run(H2demoApplication.class, args);
}
#Override
public void run(String... args) throws Exception {
LOG.info("Student count in DB: {}", studentRepository.count());
}
}
Entity:
package com.example.demo;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
#Entity
public class Student {
#Id
#GeneratedValue
private Long ID;
private String NAME;
private String SECTION;
public Student() {
}
public Student(Long ID, String NAME, String SECTION) {
this.ID = ID;
this.NAME = NAME;
this.SECTION = SECTION;
}
public Long getId() {
return ID;
}
public void setId(Long ID) {
this.ID = ID;
}
public String getName() {
return NAME;
}
public void setName(String NAME) {
this.NAME = NAME;
}
public String getSection() {
return SECTION;
}
public void setSection(String SECTION) {
this.SECTION = SECTION;
}
}
Repository:
package com.example.demo;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
import com.example.demo.Student;
#Repository
public interface StudentRepository extends JpaRepository<Student, Long> {
}
O/p should have "Student count in DB: 2"
my java version is :
java version "1.8.0_102"
Java(TM) SE Runtime Environment (build 1.8.0_102-b14)
Java HotSpot(TM) 64-Bit Server VM (build 25.102-b14, mixed mode)
Getting above error when running mvn clean install in command line.
I defined h2db configurations in application.properties file as below
H2 configurarion
spring.h2.console.enabled=true
spring.h2.console.path=/h2
Datasource
spring.datasource.url=jdbc:h2:~/test
spring.datasource.username=
spring.datasource.password=
spring.datasource.driver-class-name=org.h2.Driver
in data.sql file kept data to be inserted :
insert into STUDENT
values(10001,'Ajay', 'AAA1');
insert into STUDENT
values(10002,'Ajit', 'AAA2');
You need to provide the hibernate dialect to configure hibernate befor connecting
use
spring.jpa.database-platform=org.hibernate.dialect.H2Dialect
The error looks like, it can't figure out the dialect to be used with H2.
The dialect specifies the type of database used in hibernate so that hibernate generate appropriate type of SQL statements.
The dialect to be used for h2 is this:
spring.jpa.database-platform=org.hibernate.dialect.H2Dialect
Also being new to programming might confuse you to write optimal code. It looks like, you are mixing up things from older versions of spring boot and spring. Please use,
https://start.spring.io
to generate your initial spring boot project with the required dependencies. You can follow the below tutorial which explains nicely to get started with spring boot and h2.
https://www.springboottutorial.com/spring-boot-and-h2-in-memory-database

Spring boot MVC: RequestMapping isn't recognized in Spring boot 2.1.4

Can someone answer this silly question - How to configure Thymeleaf in Spring boot release 2.1.4?
I have declared the right dependencies:
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.4.RELEASE</version>
</parent>
<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>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
Also the config:
#SpringBootApplication
#ComponentScan("org.mystuff.myproj")
#EnableAutoConfiguration
public class Init extends SpringBootServletInitializer{
And the controller looks regular:
#Controller
#RequestMapping("/a")
public class IndexController {
private static final Logger logger = LoggerFactory.getLogger(IndexController.class);
#PostConstruct
private void test() {
logger.info("********************************************************************");
}
#RequestMapping("/")
private String index() {
return "index2";
}
I do see that the #Controller bean gets initiated (the "*****..."), but when I try to locate in the logs the "mapped" or atleast something related, the only thing I find is:
2019-04-23 15:55:15 WARN [localhost-startStop-1] JpaBaseConfiguration$JpaWebConfiguration$JpaWebMvcConfiguration.openEntityManagerInViewInterceptor: spring.jpa.open-in-view is enabled by default. Therefore, database queries may be performed during view rendering. Explicitly configure spring.jpa.open-in-view to disable this warning
2019-04-23 15:55:16 INFO [localhost-startStop-1] WelcomePageHandlerMapping.<init>: Adding welcome page: ServletContext resource [/index.html]
And I'm failing to find an answer to the "What has changed" question.
After a while I realized that Spring Boot 2.1.4 requires TomCat 9, while I was using 8.5.
After this I started to get progress, but still the Thymeleaf isn't working, and if /templates has a index.html, the default Resolver is used, which ignores Thymeleaf's "fragments" and stuff (loads like a regular html page).

Spring boot web app not running on tomcat 9

My web App works fine on Eclipse Photon STS, java 8 and Spring Boot 2.02 with the embeded tomcat using endpoint:
http://localhost:8081/DataViewer/tspsPatentSearch
But when I compile the code into DataViewer.war file (using mvn package) and run it on Tomcat 9 on Linux
with endpoint:
http://myserver.com:8081/DataViewer/tspsPatentSearch
I get the infamous:
Whitelabel Error Page
There was an unexpected error (type=Not Found, status=404).
/DataViewer/tspsPatentSearch
My pom.xml file is:
`<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.clarivate</groupId>
<artifactId>dataviewer</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>war</packaging>
<name>dataviewer</name>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.2.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>
<start-class>com.clarivate.dataviewer.DvMain</start-class>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</exclusion>
</exclusions>
</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>
<!-- DS may need to remove for tomcat installation -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-log4j2</artifactId>
<exclusions>
<exclusion>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-slf4j-impl</artifactId>
</exclusion>
</exclusions>
</dependency>
<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>
<dependency>
<groupId>com.oracle</groupId>
<artifactId>ojdbc6</artifactId>
<version>11.2.0.1.0</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<!-- Required to find ojdbc6, because Oracle don't make it available to maven-->
<repositories>
<repository>
<id>codelds</id>
<url>https://code.lds.org/nexus/content/groups/main-repo</url>
</repository>
</repositories>
<build>
<finalName>DataViewer</finalName>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<mainClass>com.clarivate.dataviewer.DvMain</mainClass>
</configuration>
</plugin>
</plugins>
</build>
<description>TSPS data viewer</description>
In application.properties I have:
spring.mvc.view.prefix=/WEB-INF/jsp/
spring.mvc.view.suffix=.jsp
server.servlet.path=/DataViewer
My main class is:
package com.clarivate.dataviewer;
import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.LogManager;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
#SpringBootApplication
public class DvMain extends SpringBootServletInitializer {
static Logger logger = LogManager.getRootLogger();
public static void main(String[] args) {
logger.debug("DS1A in main()");
SpringApplication.run(DvMain.class, args);
logger.info("DS1C finished.");
}
//#Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {
return builder.sources(DvMain.class);
}
}
My MainController.java has:
#GetMapping("/tspsPatentSearch")
public String tspsPatentSearch(Model model) {
model.addAttribute("tspsPatent", new TspsPatent());
return "tspsPatentSearch";
}
The war file unpacks fine and there are no errors. In catalina.out we have:
2018-10-04 12:09:09.954 INFO 12950 --- [ main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/tspsPatentSearch],methods=[POST]}" onto public java.lang.String com.clarivate.dataviewer.controller.MainController.tspsPatentSearch(com.clarivate.dataviewer.model.TspsPatent,org.springframework.ui.Model,org.springframework.validation.BindingResult)
and no errors. I've tried this ie my package structure is correct and this ie my jsp's are in the correct location (data_viewer\src\main\webapp\WEB-INF\jsp)
and i'm now running short of ideas. Any help much appreciated
Edit: If I copy tspsPatentSearch.jsp into the war file top directory then tomcat finds it. So it looks like tomcat is ignoring:
spring.mvc.view.prefix=/WEB-INF/jsp/
or not finding application.properties at all.
Add this to your application.properties:
server.servlet.contextPath=/
I've taken your sample code and, assuming you annotated your MainController simply as #Controller, put a deployment together. I changed a few things around, but I believe this was the bit that did it. I haven't been able to find any references explaining why it might be required by Tomcat, but I intend to keep looking. I'll update you if I find anything.
Edit:
I noticed some duplicate logging in Spring 2.0.2 related to this issue: https://github.com/spring-projects/spring-boot/issues/13470
The problem appeared fixed in 2.0.4 therefore I upgraded.
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.4.RELEASE</version>
<relativePath /> <!-- lookup parent from repository -->
</parent>
Additionally, I removed the server.servlet.contextPath=/ entry and tada I still can reach the Hello World jsp I set up. If upgrading is possible for you, maybe you could try that before adding something to application.properties which could be considered duplicated functionality. At least I can promise you a better logging experience.
Edit #2:
No smoking gun, so far, but these (from 2.0.4) could be related:
Provide a consistent way to discover the primary DispatcherServlet's path
Dispatcher servlets with a custom servlet name are not found by the mappings endpoint
Nothing looked likely on a surface scan of 2.0.3. I'm going to give it a rest for now and give you a chance to try some stuff. Good luck!
Edit #3:
I'm sorry to continue suggesting you switch environment stuff around, but one difference I noted between what I tested and what you're working with is that you seem to be using Tomcat-9.0.0.M20 where as I was testing with 9.0.12.
Whether you want to upgrade or not, a few things to note and/or do:
1) Update your question with what you've got now if it's different than before. Include the server.servlet.contextPath=/ in your application.properties just so anyone else looking can see what you've done.
2) The exclusion you have for spring-boot-starter-tomcat under spring-boot-starter-web doesn't appear to do anything - you can verify by comparing the output from running mvn dependency:tree before and after removal.
3) I'm not sure that your spring-web dependency is needed either, as that's brought in by default under the spring-boot-starter.
4) Now to your output. Spring Boot is coming up (note the banner) and your classes are being found and acted upon.
catalina.out.DEBUG also in your DS.log starting ~ 08:35:38.162
2018-10-12 09:30:17.322 DEBUG 55745 --- [ main] o.s.c.a.ClassPathBeanDefinitionScanner : Identified candidate component class: file [/data/apps/tomcat/apache-tomcat-9.0.0.M20/webapps/DataViewer/WEB-INF/classes/com/clarivate/dataviewer/controller/MainController.class]
2018-10-12 09:30:17.328 DEBUG 55745 --- [ main] o.s.c.a.ClassPathBeanDefinitionScanner : Identified candidate component class: file [/data/apps/tomcat/apache-tomcat-9.0.0.M20/webapps/DataViewer/WEB-INF/classes/com/clarivate/dataviewer/database/ReadFromDb.class]
2018-10-12 09:30:17.356 DEBUG 55745 --- [ main] o.s.c.a.ClassPathBeanDefinitionScanner : Identified candidate component class: file [/data/apps/tomcat/apache-tomcat-9.0.0.M20/webapps/DataViewer/WEB-INF/classes/com/clarivate/dataviewer/service/FileFuncs.class]
2018-10-12 09:30:17.357 DEBUG 55745 --- [ main] o.s.c.a.ClassPathBeanDefinitionScanner : Identified candidate component class: file [/data/apps/tomcat/apache-tomcat-9.0.0.M20/webapps/DataViewer/WEB-INF/classes/com/clarivate/dataviewer/service/StringFuncs.class]
...
2018-10-12 09:30:19.417 INFO 55745 --- [ main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/tspsPatentSearch],methods=[POST]}" onto public java.lang.String com.clarivate.dataviewer.controller.MainController.tspsPatentSearch(com.clarivate.dataviewer.model.TspsPatent,org.springframework.ui.Model,org.springframework.validation.BindingResult)
2018-10-12 09:30:19.417 INFO 55745 --- [ main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/tspsPatentSearch],methods=[GET]}" onto public java.lang.String com.clarivate.dataviewer.controller.MainController.tspsPatentSearch(org.springframework.ui.Model)
...
2018-10-12 09:30:19.769 INFO 55745 --- [ main] com.clarivate.dataviewer.DvMain : Started DvMain in 3.125 seconds (JVM running for 5.845)
And I do indeed note the mapping to /error that's returned for your request at 09:32:11.
I find this strange:
2018-10-12 09:32:11.758 DEBUG 55745 --- [nio-8081-exec-1] o.s.web.servlet.DispatcherServlet : DispatcherServlet with name 'dispatcherServlet' processing GET request for [/DataViewer/DataViewer/error]
And it's different in DS.log:
2018-10-12 08:36:56.136 DEBUG 6992 --- [nio-8081-exec-1] o.s.web.servlet.DispatcherServlet : DispatcherServlet with name 'dispatcherServlet' processing GET request for [/DataViewer /error]
Specifically /DataViewer/DataViewer/error - have you tried requesting http://localhost:8081/DataViewer/DataViewer/tspsPatentSearch
In general this appears as though everything is coming up but there is a misconfiguration somewhere that isn't allowing a request to map to the handler.
To confirm.
Tomcat adds the war file name to the end point, so if we create DataViewerX.war and set :
server.servlet.path=/DataViewer
then the end point when running on an external tomcat is:
myServer.com/DataViewerX/DataViewer/tspsPatentSearch
but when we run on Eclispe, using the source code, then the end point is:
http://localhost:8081/DataViewer/tspsPatentSearch
which is a bit annoying but not a major problem. A way round this is to call the war file ROOT.war, then tomcat ignores the war file name and the 2 end points are the same, but I have multiple war files in the webapps dir so this solution isn't acceptable for me.
If anyone know's a way to allow the 2 end points to be the same then please say so, but it's not that important.

Spring Boot | localhost: 8080 404 error page displayed

I created a Spring Boot Maven project, however my RequestMapping, as well as localhost:8080 return a 404 error page. I think the issue is with how my packages are setup, but I've tried solutions in multiple questions, and I still cant get around the error page. Could you guys point me in the right direction as to how to resolve this issue? Perhaps I need to add the Component annotation above my Main class? But I've tried this solution, and the error still persists.
Here is my package structure:
/src/main/java
ControllerLayer
UsersController.java
DataAccessLayer
UsersDAL.java
ServiceLayer
UsersService.java
Main
Main.java
Main.java:
#SpringBootApplication(scanBasePackages = {
"/src/main/java/ControllerLayer", "/src/main/java/DataAccessLayer",
"/src/main/java/ServiceLayer" })
public class Main {
public static void main(String[] args) {
SpringApplication.run(Main.class, args);
}
}
UsersController.java:
import Entities.Users;
import ServiceLayer.UsersService;
#RestController
#RequestMapping("/users")
public class UsersController {
#Autowired
private UsersService usersService;
#RequestMapping(value =
"/create/{userId}/{userPassword}/{userAge}/{userEmail}"
+ "/{userFirstName}/{userlastName}", method =
RequestMethod.POST)
public void createUser(#PathVariable("userId")String userId,
#PathVariable("userPassword")String userPassword,
#PathVariable("userAge")int userAge,
#PathVariable("userEmail")String userEmail,
#PathVariable("userFirstName")String userFirstName,
#PathVariable("userLastName")String userLastName) {
usersService.createUser(new Users(userId, userPassword,
userAge, userEmail, userFirstName, userLastName));
}
}
UserService.java
import DataAccessLayer.UsersDAL;
import Entities.Users;
#Service
public class UsersService {
#Autowired
private UsersDAL usersDAL;
public void createUser(Users user) {
usersDAL.createUser(user);
}
}
pom.xml:
<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>xProjectAlpha</groupId>
<artifactId>org.htech.xProjectAlpha</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.2.RELEASE</version>
</parent>
<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.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>5.2.9.Final</version><!--$NO-MVN-MAN-VER$-->
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
When a request is sent, then a response shall be returned. In your case, you didn't send any content with the response and that's why you get 404 error (page not found).
In main.java, try:
#SpringBootApplication(scanBasePackages = {
"ControllerLayer", "DataAccessLayer",
"ServiceLayer" })
Your package names shouldn't include the root path in the project.
It is advisable to have spring boot Application class in root package and have all other classes in package structure below that package .You don't have to worry about component scan as an example
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.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
#SpringBootApplication
public class CustomerApplication {
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);
}
};
}
}
Controller class
package com.igt.customer.controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
#RestController
public class EmployeeController {
#RequestMapping("/employee")
public String employee() {
return "Greetings from Sam!";
}
}
running the application (go to the directory of your application on cmd )
E:\MongoDb\New folder\customer>mvn install -U -e
you should see this in the end if its fine
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 10.686 s
[INFO] Finished at: 2017-08-16T16:39:57+05:30
[INFO] Final Memory: 21M/219M
[INFO] ------------------------------------------------------------------------
run the jar file
E:\MongoDb\New folder\customer\target>java -jar customer-0.0.1-SNAPSHOT.jar
accessing the application
http://localhost:8080/employee
Notice application name is not required in URL
P.S i have written extra detail here as i have experienced if you are new to spring boot building and running the application is a challenge , in my application i had created a rest controller in the same package as the Application class with RequestMapping "/" as i was getting 404 error , Please see the link below as a reference
spring boot application
This issue will be simply solved if you remove the main package of the main.java class.
The new structure will be:
/src/main/java
Main.java
ControllerLayer
UsersController.java
DataAccessLayer
UsersDAL.java
ServiceLayer
UsersService.java
In my Spring boot application, there is no need to scan the base packages manually because all the configurations are embedded in a single annotation #SpringBootApplication. Please refer to this link.
I don't understand how the base packages are initially configured. Can someone please explain this?
For example, if your base package looks like:
com.example.myapp.SpringApplication
... it means your application takes base packages as com.example.myapp. So if you can create all Controllers, Service, Repository under com.example.myapp in the sense it will load your Controllers, Service, Repository easily or else it can't able to load. This is because springbootapplication intially sets the base packages and loads whatever java classes are inside the base package. So because of this you get a 404 error in the browser as well as in postman. So try to match with base package.

Categories

Resources