I'm trying to deploy my simple spring MVC project without spring boot to tomcat in IntelliJ, but I can't get it to work, the server always returns 404. I have tried a lot of tutorials but it still doesn't work.
I have also tried AbstractAnnotationConfigDispatcherServletInitializer class but it didn't work either. It seems that the onStartup method is never called.
Can someone point out where am I wrong and make it work?
Here is my pom.xml file
<?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.learning</groupId>
<artifactId>spring-web-no-boot</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<org.springframework.version>5.1.5.RELEASE</org.springframework.version>
</properties>
<dependencies>
<!-- core spring dependency -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${org.springframework.version}</version>
<!--<scope>runtime</scope>-->
</dependency>
<!-- spring web -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>${org.springframework.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${org.springframework.version}</version>
</dependency>
<!-- provide servlet, web server -->
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-core</artifactId>
<version>9.0.16</version>
</dependency>
<!-- json jackson -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.9.8</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-jdk8</artifactId>
<version>2.9.8</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.module</groupId>
<artifactId>jackson-module-parameter-names</artifactId>
<version>2.9.8</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-jsr310</artifactId>
<version>2.9.8</version>
</dependency>
</dependencies>
</project>
Application.java file
import configuration.RootConfig;
import configuration.WebConfig;
import org.springframework.web.WebApplicationInitializer;
import org.springframework.web.context.ContextLoaderListener;
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
import org.springframework.web.servlet.DispatcherServlet;
import javax.servlet.ServletException;
import javax.servlet.ServletRegistration;
public class Application implements WebApplicationInitializer {
public void onStartup(javax.servlet.ServletContext servletContext) throws ServletException {
AnnotationConfigWebApplicationContext rootContext = new AnnotationConfigWebApplicationContext();
rootContext.register(RootConfig.class);
servletContext.addListener(new ContextLoaderListener(rootContext));
AnnotationConfigWebApplicationContext webContext = new AnnotationConfigWebApplicationContext();
webContext.register(WebConfig.class);
DispatcherServlet servlet = new DispatcherServlet(webContext);
ServletRegistration.Dynamic registration = servletContext.addServlet("app", servlet);
registration.setLoadOnStartup(1);
registration.addMapping("/");
}
}
RootConfig.java file
package configuration;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
#Configuration
#ComponentScan(basePackages = "controller")
public class RootConfig {
}
WebConfig.java file
package configuration;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
#EnableWebMvc
#Configuration
public class WebConfig {
}
HomeController.java file
package controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
#RestController
public class HomeController {
#RequestMapping(value = "/", method = RequestMethod.GET)
public String home() {
return "Hello world from spring";
}
}
First of all you should add <packaging>war</packaging> to your pom.xml, but that's not causing the error.
pom.xml
<groupId>com.learning</groupId>
<artifactId>spring-web-no-boot</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>war</packaging>
You are using two different contexts. If you use only the root context it should work.
Try the following Application.java:
public class Application implements WebApplicationInitializer {
public void onStartup(ServletContext container) throws ServletException {
AnnotationConfigWebApplicationContext context =
new AnnotationConfigWebApplicationContext();
context.setConfigLocation("configuration");
container.addListener(new ContextLoaderListener(context));
ServletRegistration.Dynamic dispatcher =
container.addServlet("dispatcher", new DispatcherServlet(context));
dispatcher.setLoadOnStartup(1);
dispatcher.addMapping("/");
}
}
I think below line might be problem
#ComponentScan(basePackages = "controller")
Can you try to change it to
#ComponentScan(basePackages = {"controller"})
Related
My Spring beans are not getting initialized in Spring Java Config which I am using to create a sample Spring REST Application(As No Web.xml is required I have deleted it) . And also getting 404 while calling the REST endpoint /dest/types.
Can anyone please help. Project Structure
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/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.travel</groupId>
<artifactId>patcyyRestApp</artifactId>
<packaging>war</packaging>
<version>0.0.1-SNAPSHOT</version>
<name>patcyyRestApp Maven Webapp</name>
<url>http://maven.apache.org</url>
<properties>
<springframework.version>5.0.9.RELEASE</springframework.version>
<jackson.library>2.9.6</jackson.library>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<hibernate.core.version>5.3.6.Final</hibernate.core.version>
<javax.servlet.api.version>3.1.0</javax.servlet.api.version>
<lombok.version>1.18.12</lombok.version>
<apache.commons.version>3.9</apache.commons.version>
<failOnMissingWebXml>false</failOnMissingWebXml>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${springframework.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${springframework.version}</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>${javax.servlet.api.version}</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>${jackson.library}</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>${hibernate.core.version}</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>${lombok.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>${apache.commons.version}</version>
</dependency>
</dependencies>
<build>
<finalName>patcyyRestApp</finalName>
</build>
</project>
Dispatch Initializer :
package com.patcyy.rest.config;
import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;
public class PatcyyDispatcherServletInitializer extends
AbstractAnnotationConfigDispatcherServletInitializer {
#Override
protected Class<?>[] getRootConfigClasses() {
return null;
}
#Override
protected Class<?>[] getServletConfigClasses() {
System.out.println("Inside getServletConfigClasses");
return new Class[] { PatcyyConfig.class };
}
#Override
protected String[] getServletMappings() {
System.out.println("Inside mapping");
return new String[] { "/patcyy" };
}
}
Config :
package com.patcyy.rest.config;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
#Configuration
#EnableWebMvc
#ComponentScan("com.patcyy.rest")
public class PatcyyConfig {
}
Controller :
package com.patcyy.rest.controller;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.patcyy.rest.response.DestinationTypes;
import com.patcyy.rest.service.IDestinationService;
#RestController
#RequestMapping(path = "/dest", consumes = MediaType.APPLICATION_JSON_UTF8_VALUE, produces =
MediaType.APPLICATION_JSON_UTF8_VALUE)
public class DestinationController extends BaseController {
private final IDestinationService iDestinationService;
/**
* #param iDestinationService
*/
public DestinationController(#Autowired IDestinationService iDestinationService) {
super();
this.iDestinationService = iDestinationService;
}
#GetMapping("/types")
public ResponseEntity<List<DestinationTypes>> getDestinationTypes() {
List<DestinationTypes> destTypes = iDestinationService.getDestinationTypes();
return new ResponseEntity<List<DestinationTypes>>(destTypes, HttpStatus.OK);
}
}
I had to do two modifications to resolve the issue.
As i am using Java Config only, I had deleted the Web.xml. So i had to make changes in server.xml for Tomcat as :
<Context path="/patcyyRestApp" reloadable="true" docBase="D:\battleGround\patcyyRestApp\target\patcyyRestApp"/></Host>
I had to update the servlet mapping in the Dispatcher Intializer as :
return new String[] { "/patcyy/*" };
After making this two changes, It is working fine now.
Please take a look into this Tomcat without web xml
Please share console log for further investigation. As per my understanding after seeing above code , you can replace
"/patcyy" with only "/"
in getServletMappings() method.
your requested resource url will be like:
http://{hostname:port}/patcyyRestApp/dest/types
It's occurring due to invalid url servlet mapping.
i think the problem is in ComponentScan().
#ComponentScan annotation along with #Configuration annotation to specify the packages that we want to be scanned. #ComponentScan without arguments tells Spring to scan the current package and all of its sub-packages.
in your case you need to add basepackages="com.patcyy.rest"
My code used to works well before I upgraded spring-boot-starter-parent from 1.0.2.RELEASE to 2.1.0.RELEASE.
When the version of spring-boot-starter-parent is 1.0.2.RELEASE, I could deploy this project to tomcat, run tomcat, and when I type localhost:8080/greeting.html on my browser I could see 'Hello World".
But after I upgrade the version to 2.1.0.RELEASE and do the same thing, I just got a 404 not found error.
QUESTION: How can I fix this problem with version 2.1.0.RELEASE of spring-boot-starter-parent?
Here is my code snippet and the pom file:
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.pluralsight</groupId>
<artifactId>event-tracker</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>war</packaging>
<name>event-tracker</name>
<description>An app to track our Events</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.0.RELEASE</version>
<!--<version>1.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>
</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>
WebConfig:
package com.pluralsight;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
#Configuration
#EnableWebMvc
#ComponentScan(basePackages = "com.pluralsight")
public class WebConfig {
}
WebAppInitializer:
package com.pluralsight;
import javax.servlet.ServletContext;
import javax.servlet.ServletRegistration;
import org.springframework.web.WebApplicationInitializer;
import org.springframework.web.context.ContextLoaderListener;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
import org.springframework.web.servlet.DispatcherServlet;
public class WebAppInitializer implements WebApplicationInitializer {
#Override
public void onStartup(ServletContext servletContext) {
WebApplicationContext context = getContext();
servletContext.addListener(new ContextLoaderListener(context));
ServletRegistration.Dynamic dispatcher = servletContext.addServlet("DispatcherServlet", new DispatcherServlet(context));
dispatcher.setLoadOnStartup(1);
dispatcher.addMapping("*.html");
}
private AnnotationConfigWebApplicationContext getContext() {
AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext();
context.setConfigLocation("com.pluralsight.WebConfig");
return context;
}
}
HelloController:
package com.pluralsight.controller;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
#Controller
public class HelloController {
#RequestMapping(value = "/greeting")
public String sayHello(Model model) {
model.addAttribute("greeting", "Hello World");
return "hello.jsp";
}
}
You can follow this link
Instead of WebAppInitializer class write Application class as in above link and declare start-class tag in properties.
It should work.
I am very new to SpringMVC, and right now I am trying to build a simple application using this tutorial:
http://websystique.com/springmvc/spring-4-mvc-helloworld-tutorial-annotation-javaconfig-full-example/
I have checked
Basic SpringMvC controller not working and it does not seem to be my problem, my app is unavailable even when I insert the app name. I use annotation-based config and Tomcat 9.
I have three classes:
MainController.java
package mvc_webapp.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
#Controller
#RequestMapping("/")
public class MainController {
#RequestMapping(method = RequestMethod.GET)
public String sayHello() {
return "index";
}
#RequestMapping(value = "/index", method = RequestMethod.GET)
public String indexPage() {
return "index";
}
}
BlogConfiguration.java
package mvc_webapp.configuration;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.ViewResolver;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.view.InternalResourceViewResolver;
import org.springframework.web.servlet.view.JstlView;
#Configuration
#EnableWebMvc
#ComponentScan(basePackages = "mvc_webapp")
public class BlogConfiguration {
#Bean
public ViewResolver viewResolver() {
InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
viewResolver.setViewClass(JstlView.class);
viewResolver.setPrefix("WEB-INF/views/");
viewResolver.setSuffix(".html");
return viewResolver;
}
}
BlogInitializer.java
package mvc_webapp.configuration;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRegistration;
import org.springframework.web.WebApplicationInitializer;
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
import org.springframework.web.servlet.DispatcherServlet;
public class BlogInitializer implements WebApplicationInitializer {
public void onStartup(ServletContext servletContext) throws ServletException {
AnnotationConfigWebApplicationContext ctx = new AnnotationConfigWebApplicationContext();
ctx.register(BlogConfiguration.class);
ctx.setServletContext(servletContext);
ServletRegistration.Dynamic servlet = servletContext.addServlet("dispatcher", new DispatcherServlet(ctx));
servlet.setLoadOnStartup(1);
servlet.addMapping("/");
}
}
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/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>net.atos</groupId>
<artifactId>mvc_webapp</artifactId>
<packaging>war</packaging>
<version>0.0.1-SNAPSHOT</version>
<name>mvc_webapp Maven Webapp</name>
<url>http://maven.apache.org</url>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.0.8.RELEASE</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>4.0.1</version>
<scope>provided</scope>
</dependency>
</dependencies>
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven</groupId>
<artifactId>maven-plugin-api</artifactId>
<version>3.5.4</version>
<configuration>
<warSourceDirectory>src/main/webapp</warSourceDirectory>
<warName>mvc_webapp</warName>
<failOnMissingWebXml>false</failOnMissingWebXml>
</configuration>
</plugin>
</plugins>
</pluginManagement>
<finalName>mvc_webapp</finalName>
I more or less understand what these components are, but I cannot detect what exactly is wrong - content of the classes is only slightly different from the tutorial.
Update:
I added the screenshot with project issues, even though they did not seem to be relevant to me as neither compiler nor build tool issued any errors. Not to mention that pom.xml complains about the value which is not even there.
First of all check if the server is running or not try hitting the homepage of apache.
Then check inside tomcat directory inside webapps folder there should be a folder with the name of your application if your application is deployed successfully on server.
So, I ended up abandoning attempts to do it in eclipse, made a WebApp project in Netbeans and with significantly less problems managed to start an annotation-based project there. Thanks everyone for the contributions.
I am trying to deploy my spring boot with angular 2 code to a war package
My springboot code contains JWT Spring security,
The problem is when I integrate and run in tomcat server. I am getting:
Whitelabel Error Page This application has no explicit mapping for
/error, so you are seeing this as a fallback.
Thu Mar 01 18:26:53 IST 2018 There was an unexpected error (type=Not
Found, status=404). No message available
But if i remove my spring security and integrate both together then it is working fine.
I don't know what is the problem with spring JWT security, So please, if anybody knows this issue, help me out
Web Security:
package com.boot.hms.security;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.http.HttpMethod;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.CorsConfigurationSource;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
#CrossOrigin
#EnableWebSecurity
public class WebSecurity extends WebSecurityConfigurerAdapter {
private UserDetailsService userDetailsService;
private BCryptPasswordEncoder bCryptPasswordEncoder;
public WebSecurity(UserDetailsService userDetailsService, BCryptPasswordEncoder bCryptPasswordEncoder) {
this.userDetailsService = userDetailsService;
this.bCryptPasswordEncoder = bCryptPasswordEncoder;
}
#Override
protected void configure(HttpSecurity http) throws Exception {
AuthenticationFilter authenticationFilter = new AuthenticationFilter(authenticationManager());
authenticationFilter.setFilterProcessesUrl("/hms/auth");
http .cors().and().csrf().disable().authorizeRequests().antMatchers("/hms/fetchmeta/*", "/hms/registration/*").permitAll()
.anyRequest().authenticated().and().addFilter(authenticationFilter)
.addFilter(new AuthorizationFilter(authenticationManager()))
// this disables session creation on Spring Security
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
System.out.println("<....Web Security......>");
}
#Override
public void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService).passwordEncoder(bCryptPasswordEncoder);
}
#Bean
CorsConfigurationSource corsConfigurationSource() {
final UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", new CorsConfiguration().applyPermitDefaultValues());
return source;
}
}
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.boot</groupId>
<artifactId>hms</artifactId>
<version>1</version>
<packaging>war</packaging>
<name>version</name>
<description>Hospital Management System</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.10.RELEASE</version>
<relativePath/>
</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.programmer.gate.HmsApplication</start-class>
</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-mail</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</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.security</groupId>
<artifactId>spring-security-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>0.2</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jersey</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</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>
<plugin>
<artifactId>maven-war-plugin</artifactId>
<configuration>
<webResources>
<resource>
<directory>D:\hmsDeployment\dist</directory>
</resource>
</webResources>
</configuration>
</plugin>
</plugins>
</build>
</project>
Main class:
package com.boot.hms;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.jdbc.DataSourceTransactionManagerAutoConfiguration;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.web.support.SpringBootServletInitializer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Import;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
import com.boot.hms.security.WebSecurity;
#CrossOrigin
#Import(WebSecurity.class)
#SpringBootApplication
#ComponentScan(basePackages="com.boot.hms")
public class HmsApplication extends SpringBootServletInitializer {
#Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(HmsApplication.class);
}
public static void main(String[] args) {
SpringApplication.run(HmsApplication.class, args);
}
#Bean
public BCryptPasswordEncoder bCryptPasswordEncoder() {
return new BCryptPasswordEncoder();
}
}
Property file:
#Database
spring.datasource.url= jdbc:mysql://192.168.12.112:3306/hms
spring.datasource.username=root
spring.datasource.password=root
#Server
#server.contextPath=/hms
#server.port = 8080
#JPA
spring.jpa.show-sql = true
spring.jpa.hibernate.ddl-auto = update
spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MySQL5Dialect
spring.autoconfigure.exclude=SecurityAutoConfiguration
#security.user.name=admin
#security.user.password=admin
security.basic.enabled=false
spring.jackson.serialization.FAIL_ON_EMPTY_BEANS=false
spring.jackson.deserialization.accept-empty-string-as-null-object=true
Solution
You are probably seeing this error because of your custom security configuration class (WebSecurity)
You did not explicitly declared a "Free for all" rule for the base url, / (were the Angular app will live!). Here I am assuming the base url is /, if not adapt this answer to be used with your base real url.
So, in your WebSecurity add the mentioned rule by changing this:
//...omitted code for brevity
http.cors().and().csrf().disable().authorizeRequests()
.antMatchers("/hms/fetchmeta/*", "/hms/registration/*").permitAll()
//...omitted code for brevity
to
//...omitted code for brevity
http.cors().and().csrf().disable().authorizeRequests()
.antMatchers("/hms/fetchmeta/*", "/hms/registration/*", "/") // <--Notice here the base url added to the "free for all" rule!
.permitAll()
//...omitted code for brevity
But ... Why this error happen?!
Well, as you commented, the explicit error is
Whitelabel Error Page This application has no explicit mapping for
/error, so you are seeing this as a fallback. Fri Mar 02 13:38:44 IST
2018 There was an unexpected error (type=Forbidden, status=403).
Access Denied
This mean when you try to access the Angular app (located from the server point of view at the base url, /, for instance), the server detect that you're not logged in, so it throws a 403 Forbidden. This would normally be shown in an error page in a Spring Boot application... and since you do not have a mapping for this route, /error, (neither you have the file under src/main/resources/static/error/403.html which would normally show this error), then you see this "fallback" message you showed me.
Recommendation
Since now the base url / is free for all, your services (provided by Spring Boot) should be prefixed with something like /api or any similar in order to prevent free access to them.
Reference
If you want to have a reference, check this Security Config, which does exactly what you're trying to do (it belongs to a project which deploy a Spring Boot + Angular packed as war project)
I have tried lot of time the same project to develop spring 4 based web app, but i am able to a project single time. I don't understand where i am making mistake. I have taken lot of references for my first Spring 4 annotation based first web application and i have followed each step by step. But all the time i failed. No i am here to understand where i am making mistake.
Please friend review and let me know the issue.
Efforts
Firstly i have create maven project and used maven-archtypes-webapp and specify group-ip, packages and so on.
Then, i have add dependencies and plugin, here is my pom.xml file.
<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>com.org.spring4</groupId>
<artifactId>FirstApp</artifactId>
<packaging>war</packaging>
<version>0.0.1-SNAPSHOT</version>
<name>FirstApp Maven Webapp</name>
<url>http://maven.apache.org</url>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>4.3.5.RELEASE</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
</dependency>
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>javax.servlet.jsp-api</artifactId>
<version>2.3.1</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
</dependencies>
<build>
<finalName>firstapp</finalName>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.6.0</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>3.0.0</version>
<configuration>
<failOnMissingWebXml>false</failOnMissingWebXml>
<warSourceDirectory>src/main/webapp/</warSourceDirectory>
<warName>firstapp</warName>
</configuration>
</plugin>
</plugins>
</build>
</project>
Then i have created annotation based configuration as mentioned on http://websystique.com/ this website. i have not created [it’s the preferred way] class, instead i have used first two classes.
here are both configuration classes:
AppConfig.java
package com.org.spring.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.ViewResolver;
import org.springframework.web.servlet.config.annotation.DefaultServletHandlerConfigurer;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
import org.springframework.web.servlet.view.InternalResourceViewResolver;
import org.springframework.web.servlet.view.JstlView;
#Configuration
#EnableWebMvc
#ComponentScan(basePackages = "com.org.spring")
public class AppConfig extends WebMvcConfigurerAdapter {
#Bean
public ViewResolver viewResolver() {
InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
viewResolver.setViewClass(JstlView.class);
viewResolver.setPrefix("/WEB-INF/views/");
viewResolver.setSuffix(".jsp");
return viewResolver;
}
#Override
public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
configurer.enable();
}
}
and AppInitializer.java
package com.org.spring.config;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRegistration;
import org.springframework.web.WebApplicationInitializer;
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
import org.springframework.web.servlet.DispatcherServlet;
public class AppInitializer implements WebApplicationInitializer {
public void onStartup(ServletContext container) throws ServletException {
AnnotationConfigWebApplicationContext ctx = new AnnotationConfigWebApplicationContext();
ctx.register(AppConfig.class);
ctx.setServletContext(container);
ServletRegistration.Dynamic servlet = container.addServlet("dispatcher", new DispatcherServlet(ctx));
servlet.setLoadOnStartup(1);
servlet.addMapping("/");
}
}
after that i have created my controller as,
package com.org.spring.controller;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
#Controller
public class HelloController {
#GetMapping("/hello")
public String hello(Model model) {
model.addAttribute("name", "John Doe");
return "welcome";
}
}
then, i have created welcome.jsp file in WEB-INF/views directory as per my configuration.
When i tried to run this project on my tomcat 8 it gives me 404 error always. I don't know why i am getting this error.
Please friend help me.
change #Controller to #RestController and add #RequestMapping to your class in order to access to your api
localhost:port/uri/apimapping/hello