I have developed small spring boot application with jar packaging. The application use case is, user will login into application and it will display welcome page. Below is my code.
Main class
package com.ibm.heathcare;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ComponentScan;
#SpringBootApplication
#ComponentScan(basePackages= {"com.ibm.heathcare.*"})
public class HeathcareappApplication {
public static void main(String[] args) {
SpringApplication.run(HeathcareappApplication.class, args);
}
}
Login controller class
package com.ibm.heathcare.controller;
import java.util.Optional;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.SessionAttributes;
import com.ibm.heathcare.modal.Login;
import com.ibm.heathcare.modal.User;
import com.ibm.heathcare.service.AuthService;
#Controller
#SessionAttributes({"userName","uid"})
public class LoginController {
#Autowired
AuthService authService;
#RequestMapping("/login")
public String showLoginPage(ModelMap model){
//model.addAttribute("login", new Login());
return "login";
}
#RequestMapping("/logout")
public String showLogoutPage(ModelMap model){
model.put("message", "Successfully Log out...");
return "redirect:/login";
}
#RequestMapping("/welcome")
public String showWelcomePage(ModelMap model) {
return "welcome";
}
#RequestMapping(value="/login" ,method=RequestMethod.POST)
public String showwelcomePage(#RequestParam String uid, #RequestParam String pwd,ModelMap model){
Optional<User> optUser=authService.getAuthenticate(uid, pwd);
if(optUser.isPresent()) {
User user=optUser.get();
model.put("userName", user.getUserName() );
model.put("uid", user.getUserId());
return "welcome";
}else {
model.addAttribute("login", new Login("",""));
model.addAttribute("errorMessage",new String("Invalid Credential"));
return "login";
}
}
}
login.jsp
<%# page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Insert title here</title>
</head>
<body>
<form method="post">
User ID :<input type="text" name="uid"/><p>
Password:<input type="password" name="pwd"/><br>
<input type="submit" value="Login" />
</form>
</body>
</html>
welcome.jsp
<%# include file="common/header.jspf" %>
<%# include file="common/navigation.jspf" %>
<div class="jumbotron text-center" >
<h1>Welcome<h1><p>
<h2> ${userName} </h2>
</div>
<%# include file="common/footer.jspf" %>
application.properties
#Server Configuration
server.port = 8282
#ViwResolver
spring.mvc.view.prefix=/WEB-INF/jsp/
spring.mvc.view.suffix=.jsp
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.3.1.RELEASE</version>
<relativePath /> <!-- lookup parent from repository -->
</parent>
<groupId>com.ibm</groupId>
<artifactId>heathcare</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>heathcareapp</name>
<description>Health Care Management Application</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.postgresql</groupId>
<artifactId>postgresql</artifactId>
<version>42.2.9</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</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>org.webjars</groupId>
<artifactId>bootstrap</artifactId>
<version>3.3.6</version>
</dependency>
<dependency>
<groupId>org.webjars</groupId>
<artifactId>jquery</artifactId>
<version>1.9.1</version>
</dependency>
<dependency>
<groupId>org.webjars</groupId>
<artifactId>bootstrap-datepicker</artifactId>
<version>1.0.1</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
Now when I have executed this application through eclipse it was working fine.
I have built a jar of application using maven tool which created in target folder. I have executed the application jar from target folder using command line. It worked fine. But when I copy same jar to another folder on my machine and try to execute using java -jar app.jar command and hit the url http://localhost:8282/login in browser it gives me Whitelabel Error Page with status code 404. I am not sure what is wrong with the application. I have searched lot on web and some experts suggested to explicitly write #ComponentScan with basepackage information in main class. I did same but it was not worked for me.
In console I am getting below log.
2020-07-10 10:38:52.605 INFO 11788 --- [ task-1] j.LocalContainerEntityManagerFactoryBean : Initialized JPA EntityManagerFactory for persistence unit 'default'
2020-07-10 10:38:53.888 INFO 11788 --- [ main] DeferredRepositoryInitializationListener : Spring Data repositories initialized!
2020-07-10 10:38:53.918 INFO 11788 --- [ main] c.ibm.heathcare.HeathcareappApplication : Started HeathcareappApplication in 24.424 seconds (JVM running for 25.755)
2020-07-10 10:39:18.728 INFO 11788 --- [nio-8282-exec-1] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring DispatcherServlet 'dispatcherServlet'
2020-07-10 10:39:18.729 INFO 11788 --- [nio-8282-exec-1] o.s.web.servlet.DispatcherServlet : Initializing Servlet 'dispatcherServlet'
2020-07-10 10:39:18.730 DEBUG 11788 --- [nio-8282-exec-1] o.s.web.servlet.DispatcherServlet : Detected StandardServletMultipartResolver
2020-07-10 10:39:18.783 DEBUG 11788 --- [nio-8282-exec-1] o.s.web.servlet.DispatcherServlet : enableLoggingRequestDetails='false': request parameters and headers will be masked to prevent unsafe logging of potentially sensitive data
2020-07-10 10:39:18.784 INFO 11788 --- [nio-8282-exec-1] o.s.web.servlet.DispatcherServlet : Completed initialization in 54 ms
2020-07-10 10:39:18.901 DEBUG 11788 --- [nio-8282-exec-1] o.s.web.servlet.DispatcherServlet : GET "/login", parameters={}
2020-07-10 10:39:18.916 DEBUG 11788 --- [nio-8282-exec-1] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped to com.ibm.heathcare.controller.LoginController#showLoginPage(ModelMap)
2020-07-10 10:39:19.022 DEBUG 11788 --- [nio-8282-exec-1] o.s.w.s.v.ContentNegotiatingViewResolver : Selected 'text/html' given [text/html, application/xhtml+xml, image/webp, application/xml;q=0.9, */*;q=0.8]
2020-07-10 10:39:19.022 DEBUG 11788 --- [nio-8282-exec-1] o.s.web.servlet.view.JstlView : View name 'login', model {}
2020-07-10 10:39:19.043 DEBUG 11788 --- [nio-8282-exec-1] o.s.web.servlet.view.JstlView : Forwarding to [/WEB-INF/jsp/login.jsp]
2020-07-10 10:39:19.160 DEBUG 11788 --- [nio-8282-exec-1] o.s.web.servlet.DispatcherServlet : Completed 404 NOT_FOUND
2020-07-10 10:39:19.163 DEBUG 11788 --- [nio-8282-exec-1] o.s.web.servlet.DispatcherServlet : "ERROR" dispatch for GET "/error", parameters={}
2020-07-10 10:39:19.168 DEBUG 11788 --- [nio-8282-exec-1] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped to org.springframework.boot.autoconfigure.web.servlet.error.BasicErrorController#errorHtml(HttpServletRequest, HttpServletResponse)
2020-07-10 10:39:19.664 DEBUG 11788 --- [nio-8282-exec-1] o.s.w.s.v.ContentNegotiatingViewResolver : Selected 'text/html' given [text/html, text/html;q=0.8]
2020-07-10 10:39:19.684 DEBUG 11788 --- [nio-8282-exec-1] o.s.web.servlet.DispatcherServlet : Exiting from "ERROR" dispatch, status 404
Please help me to find the problem.
First of all you are trying to serve jsp views using jar. It is provided in the spring-boot documentation itself that jsp does not go well with jar packaging. So, change packaging from jar to war . Then , ensure that the jsp files are placed under the WEB-INF like you provided in the application.properties. Most probably your issue is that the jsp was not included in the jar since it was in the WEB-INF folder.
The issue is that when you are using java -*.jar to deploy a springboot application , the jsp files will not be present in the embedded tomcat and while trying to serve the request you will get a 404 PAGE NOT FOUND. This is because of the jar packaging ,that the jsp files are not getting copied from the WEB-INF folder.If you keep the jsp files under the META-INF/resources folder while using jar as packaging it should work.
Related : Why does Spring boot not support jsp while it can render the page if we add proper jar reference
Related
Summary :
Testing out Spring Security OAuth2 Resource Server JWT with SpringBoot 2.7.7 which uses Spring Security 5.7.6 to query Authorisation Server at startup.
According to :
https://docs.spring.io/spring-security/reference/5.7/servlet/oauth2/resource-server/jwt.html#_startup_expectations
Startup Expectations
When this property and these dependencies are used, Resource Server
will automatically configure itself to validate JWT-encoded Bearer
Tokens.
It achieves this through a deterministic startup process:
Query the Provider Configuration or Authorization Server Metadata endpoint for the jwks_url property
Query the jwks_url endpoint for supported algorithms
Configure the validation strategy to query jwks_url for valid public keys of the algorithms found
Configure the validation strategy to validate each JWTs iss claim against idp.example.com.
A consequence of this process is that the authorization server must be
up and receiving requests in order for Resource Server to successfully
start up.
If the authorization server is down when Resource Server queries it
(given appropriate timeouts), then startup will fail.
I have the property defined in application.properties AND the dependencies in pom.xml as above.
However, my very small example to try this out does not work ( e.g. The Resource Server does not appear to be querying the Authorisation Server at all at startup, and therefore the Resource Server starts-up successfully.
I was expecting my very small app to fail at startup as per documentation, but it did not ! Went as far as shutting down the Authorisation Server, and the SpringBoot Resources Server app still starts up.
Here's what I did :
1) 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.7</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>org.example</groupId>
<artifactId>oauth2-resource-server</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>oauth2-resource-server</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>11</java.version>
<spring-cloud.version>2021.0.5</spring-cloud.version>
<bootstrap.version>5.2.3</bootstrap.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-cache</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-oauth2-resource-server</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-oauth2-client</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-oauth2-jose</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-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<!--dependency>
<groupId>org.thymeleaf.extras</groupId>
<artifactId>thymeleaf-extras-springsecurity5</artifactId>
</dependency-->
<!--dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<optional>true</optional>
</dependency-->
<dependency>
<groupId>org.webjars</groupId>
<artifactId>bootstrap</artifactId>
<version>${bootstrap.version}</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</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>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<excludes>
<exclude>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</build>
</project>
2. application.properties
server.port=8081
spring.thymeleaf.cache=false
spring.security.oauth2.resourceserver.jwt.issuer-uri=http://openam.localtest.me:8080/openam/oauth2/realms/subrealm/
spring.security.oauth2.resourceserver.jwt.jwk-set-uri=http://openam.localtest.me:8080/openam/oauth2/realms/subrealm/connect/jwk_uri
3. Configuration class:
package org.example.oauth2resourceserver;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
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.configurers.oauth2.server.resource.OAuth2ResourceServerConfigurer;
import org.springframework.security.oauth2.jwt.JwtDecoder;
import org.springframework.security.oauth2.jwt.NimbusJwtDecoder;
import org.springframework.security.web.SecurityFilterChain;
#Configuration
#EnableWebSecurity
public class OAuth2ResourceServerSecurityConfiguration {
#Value("${spring.security.oauth2.resourceserver.jwt.jwk-set-uri}")
String jwkSetUri;
#Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http
.authorizeHttpRequests((authorize) -> authorize
.antMatchers(HttpMethod.GET, "/**").hasAuthority("SCOPE_message:read")
.antMatchers(HttpMethod.POST, "/**").hasAuthority("SCOPE_message:write")
.anyRequest().authenticated()
)
.oauth2ResourceServer(OAuth2ResourceServerConfigurer::jwt);
return http.build();
}
#Bean
JwtDecoder jwtDecoder() {
return NimbusJwtDecoder.withJwkSetUri(this.jwkSetUri).build();
}
}
4. Controller
package org.example.oauth2resourceserver;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
#Controller
public class ExampleMVCController {
#GetMapping("/")
public String main(Model model) {
return "welcome";
}
#GetMapping("/welcome")
public String welcome(Model model) {
return "welcome";
}
}
5. Application
package org.example.oauth2resourceserver;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
#SpringBootApplication
public class Oauth2ResourceServerApplication {
public static void main(String[] args) {
SpringApplication.run(Oauth2ResourceServerApplication.class, args);
}
}
With the Authorisation Server down, output on the console when I run the Resource Server is:
2022-12-28 03:32:38.148 INFO 1377958 --- [ main] o.e.o.Oauth2ResourceServerApplication : Starting Oauth2ResourceServerApplication using Java 11.0.15 on xxxxx-Inspiron-15-7510 with PID 1377958 (/home/xxxxx/projects/oauth2-resource-server/target/classes started by jsalvo in /home/xxxxx/projects/oauth2-resource-server)
2022-12-28 03:32:38.150 INFO 1377958 --- [ main] o.e.o.Oauth2ResourceServerApplication : No active profile set, falling back to 1 default profile: "default"
2022-12-28 03:32:38.561 INFO 1377958 --- [ main] o.s.cloud.context.scope.GenericScope : BeanFactory id=12f14043-de4d-3b01-a8aa-ef038a41274e
2022-12-28 03:32:38.733 INFO 1377958 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat initialized with port(s): 8081 (http)
2022-12-28 03:32:38.739 INFO 1377958 --- [ main] o.apache.catalina.core.StandardService : Starting service [Tomcat]
2022-12-28 03:32:38.739 INFO 1377958 --- [ main] org.apache.catalina.core.StandardEngine : Starting Servlet engine: [Apache Tomcat/9.0.70]
2022-12-28 03:32:38.819 INFO 1377958 --- [ main] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext
2022-12-28 03:32:38.820 INFO 1377958 --- [ main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 634 ms
2022-12-28 03:32:38.931 INFO 1377958 --- [ main] o.s.s.web.DefaultSecurityFilterChain : Will secure any request with [org.springframework.security.web.session.DisableEncodeUrlFilter#748ac6f3, org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter#68f6e55d, org.springframework.security.web.context.SecurityContextPersistenceFilter#2bfaba70, org.springframework.security.web.header.HeaderWriterFilter#5584d9c6, org.springframework.security.web.csrf.CsrfFilter#3bf54172, org.springframework.security.web.authentication.logout.LogoutFilter#58af5076, org.springframework.security.oauth2.server.resource.web.BearerTokenAuthenticationFilter#650c405c, org.springframework.security.web.savedrequest.RequestCacheAwareFilter#9301672, org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter#2577a95d, org.springframework.security.web.authentication.AnonymousAuthenticationFilter#6fff46bf, org.springframework.security.web.session.SessionManagementFilter#17e9bc9e, org.springframework.security.web.access.ExceptionTranslationFilter#4da39ca9, org.springframework.security.web.access.intercept.AuthorizationFilter#2954f6ab]
2022-12-28 03:32:39.140 INFO 1377958 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 8081 (http) with context path ''
2022-12-28 03:32:39.152 INFO 1377958 --- [ main] o.e.o.Oauth2ResourceServerApplication : Started Oauth2ResourceServerApplication in 1.27 seconds (JVM running for 1.512)
What am I missing ?
What code in Spring Security OAuth2 Resource Server does the call to the Authorisation Server at startup ?
UPDATE 2022-12-28
As suggested by the comments, I have completely removed my OAuth2ResourceServerSecurityConfiguration above. Still no luck.
On looking at the source code for OAuth2ResourceServerJwtConfiguration.JwtDecoderConfiguration :
It appears that you must only specify one of the following properties, but not both:
spring.security.oauth2.resourceserver.jwt.issuer-uri
spring.security.oauth2.resourceserver.jwt.jwk-set-uri
The method at :
JwtDecoderConfiguration.jwtDecoderByIssuerUri() method has an #IssuerUriCondition annotation that dictates a condition where you must only have the spring.security.oauth2.resourceserver.jwt.issuer-uri property defined.
So I commented out the other property ( commented out spring.security.oauth2.resourceserver.jwt.jwk-set-uri from application.properties), but when I debug into that method via IntelliJ, it steps at line 139 below but it does not step / stop at line 141 within the lambda, which is where the code that actually calls the authorisation server, even if I try to Step-In ( F7 ) from line 139:
In short, I am still at a loss. Anyone have any ideas ?
I have a front application with Vue JS and I'm using axios to call my Spring Boot API, using Spring Security.
Vue is running on http://localhost:8081.
API is running on http://localhost:8080
I have set my Spring Boot application as followed:
application.properties: empty
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.2</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.demin</groupId>
<artifactId>api</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>api</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-data-jpa</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-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</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>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<excludes>
<exclude>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</build>
</project>
ApiApplication:
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
#SpringBootApplication
public class ApiApplication {
public static void main(String[] args) {
SpringApplication.run(ApiApplication.class, args);
}
}
IndexController:
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
#CrossOrigin(origins = "http://localhost:8081/")
#RestController
#RequestMapping("/api")
public class IndexController {
#GetMapping("/index")
public ResponseEntity<String> findTitle() {
System.err.println("Hello IndexController !");
return new ResponseEntity<>("Hello world", HttpStatus.OK);
}
}
SecurityConfig:
import java.util.List;
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.web.cors.CorsConfiguration;
#EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter
{
#Override
protected void configure(HttpSecurity http) throws Exception {
CorsConfiguration corsConfiguration = new CorsConfiguration();
corsConfiguration.setAllowedHeaders(List.of("Authorization", "Cache-Control", "Content-Type"));
corsConfiguration.setAllowedOrigins(List.of("http://localhost:8081"));
corsConfiguration.setAllowedMethods(List.of("GET", "POST", "PUT", "DELETE", "PUT","OPTIONS","PATCH", "DELETE"));
corsConfiguration.setAllowCredentials(true);
corsConfiguration.setExposedHeaders(List.of("Authorization"));
http
.authorizeRequests()
.antMatchers("/**").permitAll()
.anyRequest().authenticated()
.and()
.csrf().disable()
.cors().configurationSource(request -> corsConfiguration);
}
}
Now, when I make a call from Vue js:
axios.get('http://localhost:8080/api/index')
.then((response) => {
console.log(response.data);
})
.catch(function (error) {
console.log(error);
});
My browser returns:
Access to XMLHttpRequest at 'http://localhost:8080/api/index' from
origin 'http://localhost:8081' has been blocked by CORS policy: No
'Access-Control-Allow-Origin' header is present on the requested
resource.
It seems like it's a frequent issue so I've tried a lot of "solutions" but I am obviously missing something and I need some help...
EDIT:
EDIT#2:
import java.util.Arrays;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
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.web.cors.CorsConfiguration;
import org.springframework.web.cors.CorsConfigurationSource;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
#Configuration
#EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter
{
#Override
protected void configure(HttpSecurity http) throws Exception {
http.cors();
http.formLogin().disable();
}
#Bean
CorsConfigurationSource corsConfigurationSource() {
CorsConfiguration configuration = new CorsConfiguration();
configuration.setAllowedOrigins(Arrays.asList("http://localhost:8081"));
configuration.setAllowedMethods(Arrays.asList("GET","POST"));
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", configuration);
return source;
}
}
returns the same error.
EDIT#3:
2021-07-23 07:39:49.050 INFO 3924 --- [ restartedMain] com.demin.api.ApiApplication : No active profile set, falling back to default profiles: default
2021-07-23 07:39:49.082 INFO 3924 --- [ restartedMain] .e.DevToolsPropertyDefaultsPostProcessor : Devtools property defaults active! Set 'spring.devtools.add-properties' to 'false' to disable
2021-07-23 07:39:49.082 INFO 3924 --- [ restartedMain] .e.DevToolsPropertyDefaultsPostProcessor : For additional web related logging consider setting the 'logging.level.web' property to 'DEBUG'
2021-07-23 07:39:49.533 INFO 3924 --- [ restartedMain] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data JPA repositories in DEFAULT mode.
2021-07-23 07:39:49.542 INFO 3924 --- [ restartedMain] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 3 ms. Found 0 JPA repository interfaces.
2021-07-23 07:39:49.983 INFO 3924 --- [ restartedMain] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat initialized with port(s): 8080 (http)
2021-07-23 07:39:49.992 INFO 3924 --- [ restartedMain] o.apache.catalina.core.StandardService : Starting service [Tomcat]
2021-07-23 07:39:49.992 INFO 3924 --- [ restartedMain] org.apache.catalina.core.StandardEngine : Starting Servlet engine: [Apache Tomcat/9.0.48]
2021-07-23 07:39:50.063 INFO 3924 --- [ restartedMain] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext
2021-07-23 07:39:50.064 INFO 3924 --- [ restartedMain] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 980 ms
2021-07-23 07:39:50.084 INFO 3924 --- [ restartedMain] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Starting...
2021-07-23 07:39:50.220 INFO 3924 --- [ restartedMain] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Start completed.
2021-07-23 07:39:50.225 INFO 3924 --- [ restartedMain] o.s.b.a.h2.H2ConsoleAutoConfiguration : H2 console available at '/h2-console'. Database available at 'jdbc:h2:mem:966f4eb4-9170-4c8f-a106-67ce4bac32bd'
2021-07-23 07:39:50.354 INFO 3924 --- [ restartedMain] o.hibernate.jpa.internal.util.LogHelper : HHH000204: Processing PersistenceUnitInfo [name: default]
2021-07-23 07:39:50.395 INFO 3924 --- [ restartedMain] org.hibernate.Version : HHH000412: Hibernate ORM core version 5.4.32.Final
2021-07-23 07:39:50.496 INFO 3924 --- [ restartedMain] o.hibernate.annotations.common.Version : HCANN000001: Hibernate Commons Annotations {5.1.2.Final}
2021-07-23 07:39:50.592 INFO 3924 --- [ restartedMain] org.hibernate.dialect.Dialect : HHH000400: Using dialect: org.hibernate.dialect.H2Dialect
2021-07-23 07:39:50.763 INFO 3924 --- [ restartedMain] o.h.e.t.j.p.i.JtaPlatformInitiator : HHH000490: Using JtaPlatform implementation: [org.hibernate.engine.transaction.jta.platform.internal.NoJtaPlatform]
2021-07-23 07:39:50.771 INFO 3924 --- [ restartedMain] j.LocalContainerEntityManagerFactoryBean : Initialized JPA EntityManagerFactory for persistence unit 'default'
2021-07-23 07:39:50.803 WARN 3924 --- [ restartedMain] JpaBaseConfiguration$JpaWebConfiguration : 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
2021-07-23 07:39:51.019 INFO 3924 --- [ restartedMain] .s.s.UserDetailsServiceAutoConfiguration :
Using generated security password: 5d615eab-a8ac-4024-9fc0-be44e58ac78e
2021-07-23 07:39:51.109 INFO 3924 --- [ restartedMain] o.s.s.web.DefaultSecurityFilterChain : Will secure any request with [org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter#5d114f4, org.springframework.security.web.context.SecurityContextPersistenceFilter#3c920c43, org.springframework.security.web.header.HeaderWriterFilter#45adf32d, org.springframework.security.web.csrf.CsrfFilter#59560611, org.springframework.security.web.authentication.logout.LogoutFilter#3101ec7e, org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter#65bc50ad, org.springframework.security.web.authentication.ui.DefaultLoginPageGeneratingFilter#2439fa5a, org.springframework.security.web.authentication.ui.DefaultLogoutPageGeneratingFilter#4f62b51e, org.springframework.security.web.authentication.www.BasicAuthenticationFilter#42ca4d2d, org.springframework.security.web.savedrequest.RequestCacheAwareFilter#3765695a, org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter#154842ed, org.springframework.security.web.authentication.AnonymousAuthenticationFilter#5f512afa, org.springframework.security.web.session.SessionManagementFilter#180f71e7, org.springframework.security.web.access.ExceptionTranslationFilter#46815abf, org.springframework.security.web.access.intercept.FilterSecurityInterceptor#611036c4]
2021-07-23 07:39:51.145 INFO 3924 --- [ restartedMain] o.s.b.d.a.OptionalLiveReloadServer : LiveReload server is running on port 35729
2021-07-23 07:39:51.173 INFO 3924 --- [ restartedMain] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 8080 (http) with context path ''
2021-07-23 07:39:51.182 INFO 3924 --- [ restartedMain] com.demin.api.ApiApplication : Started ApiApplication in 2.434 seconds (JVM running for 3.184)
This question has nothing to do with CORS.
After reviewing the provided small example, the problem lies in the folder structure.
Springs main function is annotated with the annotation #SpringBootApplication which the api documentation states:
This is a convenience annotation that is equivalent to declaring #Configuration, #EnableAutoConfiguration and #ComponentScan.
For the documentation of #ComponentScan it says the following:
Configures component scanning directives for use with #Configuration classes. ... If specific packages are not defined, scanning will occur from the package of the class that declares this annotation.
Note the last part.
So spring will scan all packages below the class that is annotated with #SpringBootApplication in search for classes that are annotated with #Configuration.
The provided projects directory layout is the following:
java
├── com
│ └─ demin
│ └── api
│ └── #SpringBootApplication
├── config
│ └── #Configuration
└── controller
└── #RestController
Which means that none of the annotated classes will be picked up of the scan.
So the solution to the problem is that the directory structure needs to be changed to:
java
└── com
└─ demin
└── api
├── #SpringBootApplication
├── config
│ └── #Configuration
└── controller
└── #RestController
For spring to be able to scan the underlying packages and pick up the annotated classes.
Or you can define basePackageClasses() or basePackages() in a #ComponentScan annotation if you want spring to scan specific packages in specific locations. Or just specific classes.
When you pull in spring-security-starter you get a auto configuration defined for you which is defined in the Hello Spring Security section of the Spring Security Reference Manual
And since none of defined configuration was even picked up by the application scanning this is the configuration that is currently in use. The rest endpoint wasn't loaded either.
The configuration and endpoint not loaded could have been spotted in the debug logs if these had been enabled and provided.
So how to prevent this:
Always use the Spring Initializr to generate your project.
Follow a tutorial from a trusted source, for instance spring provides several getting started guides
Learn how to enable debug logging in different part of your spring application or for instance spring security
set a breakpoint in your configuration and check that it is even run at startup.
I receive the "HTTP Status 404 – Not Found" even though the Tomcat server seems to have initialized and running in the localhost:8080.
The pom.xml is
<?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>
<groupId>org.springframework</groupId>
<artifactId>gs-consuming-rest</artifactId>
<version>0.1.0</version>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.6.RELEASE</version>
</parent>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</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</groupId>
<artifactId>spring-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-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>
The Controller is
package com.example.demo;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
#RestController
public class HelloController {
#RequestMapping("/")
public String hello(){
return "Hello!";
}
}
The Main Application code is
package com.example.demo;
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 HelloWorldApplication {
public static void main(String[] args) {
SpringApplication.run(HelloWorldApplication.class, args);
}
}
The console logs :
2019-08-09 19:53:07.161 INFO 13948 --- [ main] com.example.demo.HelloWorldApplication : Starting HelloWorldApplication on DESKTOP-BIMC3QL with PID 13948 (C:\Users\AdharshD\Documents\workspace-sts-3.9.9.RELEASE\HelloWorld\target\classes started by AdharshD in C:\Users\AdharshD\Documents\workspace-sts-3.9.9.RELEASE\HelloWorld)
2019-08-09 19:53:07.164 INFO 13948 --- [ main] com.example.demo.HelloWorldApplication : No active profile set, falling back to default profiles: default
2019-08-09 19:53:07.791 INFO 13948 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat initialized with port(s): 8080 (http)
2019-08-09 19:53:07.810 INFO 13948 --- [ main] o.apache.catalina.core.StandardService : Starting service [Tomcat]
2019-08-09 19:53:07.810 INFO 13948 --- [ main] org.apache.catalina.core.StandardEngine : Starting Servlet engine: [Apache Tomcat/9.0.21]
2019-08-09 19:53:07.891 INFO 13948 --- [ main] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext
2019-08-09 19:53:07.891 INFO 13948 --- [ main] o.s.web.context.ContextLoader : Root WebApplicationContext: initialization completed in 679 ms
2019-08-09 19:53:08.076 INFO 13948 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 8080 (http) with context path ''
2019-08-09 19:53:08.079 INFO 13948 --- [ main] com.example.demo.HelloWorldApplication : Started HelloWorldApplication in 1.211 seconds (JVM running for 1.855)
You are missing spring-boot-starter-web artifact. Artifact contains tells spring boot to scan the package (in which main method is present) and all his subpackage for configuration, components and controller. Since this artifact is missing, spring doesn’t register your controller and throws 404-Not found.
I have a problem at displaying view file in Spring Boot with version 1.5.9 (the latest version). I created the project from Spring Initializr. I searched everywhere about the probelm in the internet. I tried many different ways but I could not make the view file displayed so I decided to ask here as the last option.
Here is my settings and 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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.eric</groupId>
<artifactId>spring-boot-starter</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>spring-boot-starter</name>
<description>Demo project for Spring Boot</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.9.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-data-jpa</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>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</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>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
SpringBootStarterApplication.java
package com.eric.springbootstarter;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.web.ErrorMvcAutoConfiguration;
import org.springframework.context.annotation.Configuration;
#SpringBootApplication(exclude = ErrorMvcAutoConfiguration.class)
public class SpringBootStarterApplication{
public static void main(String[] args) {
SpringApplication.run(SpringBootStarterApplication.class, args);
}
}
LoginController.java
package com.eric.springbootstarter;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.servlet.ModelAndView;
#Controller
public class LoginController {
#RequestMapping(value="/giris", method = RequestMethod.GET)
public ModelAndView giris(){
ModelAndView modelAndView = new ModelAndView();
modelAndView.setViewName("index");
return modelAndView;
}
}
In the console tab, I get this log:
2017-12-25 18:49:44.874 INFO 8740 --- [ main] j.LocalContainerEntityManagerFactoryBean : Building JPA container EntityManagerFactory for persistence unit 'default'
2017-12-25 18:49:44.892 INFO 8740 --- [ main] o.hibernate.jpa.internal.util.LogHelper : HHH000204: Processing PersistenceUnitInfo [
name: default
...]
2017-12-25 18:49:44.995 INFO 8740 --- [ main] org.hibernate.Version : HHH000412: Hibernate Core {5.0.12.Final}
2017-12-25 18:49:44.997 INFO 8740 --- [ main] org.hibernate.cfg.Environment : HHH000206: hibernate.properties not found
2017-12-25 18:49:44.998 INFO 8740 --- [ main] org.hibernate.cfg.Environment : HHH000021: Bytecode provider name : javassist
2017-12-25 18:49:45.052 INFO 8740 --- [ main] o.hibernate.annotations.common.Version : HCANN000001: Hibernate Commons Annotations {5.0.1.Final}
2017-12-25 18:49:45.223 INFO 8740 --- [ main] org.hibernate.dialect.Dialect : HHH000400: Using dialect: org.hibernate.dialect.MySQL5Dialect
2017-12-25 18:49:45.625 INFO 8740 --- [ main] org.hibernate.tool.hbm2ddl.SchemaUpdate : HHH000228: Running hbm2ddl schema update
2017-12-25 18:49:45.805 INFO 8740 --- [ main] j.LocalContainerEntityManagerFactoryBean : Initialized JPA EntityManagerFactory for persistence unit 'default'
2017-12-25 18:49:46.631 INFO 8740 --- [ main] s.w.s.m.m.a.RequestMappingHandlerAdapter : Looking for #ControllerAdvice: org.springframework.web.context.support.GenericWebApplicationContext#32b260fa: startup date [Mon Dec 25 18:49:41 EET 2017]; root of context hierarchy
2017-12-25 18:49:46.779 INFO 8740 --- [ main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/giris],methods=[GET]}" onto public org.springframework.web.servlet.ModelAndView com.eric.springbootstarter.LoginController.giris()
2017-12-25 18:49:46.834 INFO 8740 --- [ main] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped URL path [/webjars/**] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
2017-12-25 18:49:46.835 INFO 8740 --- [ main] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped URL path [/**] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
2017-12-25 18:49:46.906 INFO 8740 --- [ main] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped URL path [/**/favicon.ico] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
2017-12-25 18:49:46.954 INFO 8740 --- [ main] oConfiguration$WelcomePageHandlerMapping : Adding welcome page: ServletContext resource [/index.html]
2017-12-25 18:49:47.514 INFO 8740 --- [ main] o.s.s.web.DefaultSecurityFilterChain : Creating filter chain: OrRequestMatcher [requestMatchers=[Ant [pattern='/**']]], []
2017-12-25 18:49:47.614 INFO 8740 --- [ main] o.s.s.web.DefaultSecurityFilterChain : Creating filter chain: org.springframework.boot.autoconfigure.security.SpringBootWebSecurityConfiguration$ApplicationNoWebSecurityConfigurerAdapter$1#41bfa9e9, [org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter#68b7d0ef, org.springframework.security.web.context.SecurityContextPersistenceFilter#59c500f7, org.springframework.security.web.header.HeaderWriterFilter#40ed1802, org.springframework.security.web.csrf.CsrfFilter#2b736fee, org.springframework.security.web.authentication.logout.LogoutFilter#721d5b74, org.springframework.security.web.savedrequest.RequestCacheAwareFilter#50110971, org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter#73c48264, org.springframework.security.web.authentication.AnonymousAuthenticationFilter#7069f076, org.springframework.security.web.session.SessionManagementFilter#7f42e06e, org.springframework.security.web.access.ExceptionTranslationFilter#1b7f06c7]
2017-12-25 18:49:48.040 INFO 8740 --- [ main] .y.s.s.SpringBootStarterApplicationTests : Started SpringBootStarterApplicationTests in 6.593 seconds (JVM running for 7.71)
Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 6.901 sec - in com.eric.springbootstarter.SpringBootStarterApplicationTests
2017-12-25 18:49:48.223 INFO 8740 --- [ Thread-3] o.s.w.c.s.GenericWebApplicationContext : Closing org.springframework.web.context.support.GenericWebApplicationContext#32b260fa: startup date [Mon Dec 25 18:49:41 EET 2017]; root of context hierarchy
2017-12-25 18:49:48.230 INFO 8740 --- [ Thread-3] j.LocalContainerEntityManagerFactoryBean : Closing JPA EntityManagerFactory for persistence unit 'default'
index.html file is located in src/main/resources/templates folder. I did not put it in a folder like "webapp/WEB-INF/views" because it is old and deprecated. Spring Boot handles all I presume.
You have any suggestion what else can I do? Thanks in advance.
I found the reason of not resolving view. I am writing this post for those who might have the same problem like me so they can utilize from this page. I see that there is no information regarding the problem in the internet.
I included these two modules in pom.xml
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-jasper</artifactId>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
</dependency>
You can prefer doing it with Thymeleaf as this is not the only option.
Spring needs view resolver in order to render templates. You can add for example Thymeleaf and it should work:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
I have a GWT application (gwt 2.8) on wich I want to add Spring-Boot dependency (1.5.3.RELEASE). I want a standalone executable war application
Here is my web.xml:
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
version="2.5"
xmlns="http://java.sun.com/xml/ns/javaee">
<init-param>
<param-name>contextClass</param-name>
<param-value>org.springframework.web.context.support.AnnotationConfigWebApplicationContext</param-value>
</init-param>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>com.mycompany.fonems.webapp.server.FonemsWebappApplication</param-value>
</init-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!-- Servlets -->
<servlet>
<servlet-name>messageServlet</servlet-name>
<servlet-class>com.mycompany.fonems.webapp.server.FONEMSWebMessageServiceImpl</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>messageServlet</servlet-name>
<url-pattern>/fonemswebapp/FONEMSWebMessageService.rpc</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>securityServlet</servlet-name>
<servlet-class>com.mycompany.fonems.webapp.server.FONEMSWebSecurityServiceImpl</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>securityServlet</servlet-name>
<url-pattern>/fonemswebapp/FONEMSWebSecurityService.rpc</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>loginServlet</servlet-name>
<servlet-class>com.mycompany.fonems.webapp.server.LoginServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>loginServlet</servlet-name>
<url-pattern>/login</url-pattern>
</servlet-mapping>
<filter>
<filter-name>gwtCacheControlFilter</filter-name>
<filter-class>com.mycompany.fonems.webapp.server.GWTCacheControlFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>gwtCacheControlFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!-- Default page to serve -->
<welcome-file-list>
<welcome-file>Fonemswebapp.html</welcome-file>
</welcome-file-list>
</web-app>
where FonemsWebappApplication is my spring-boot entry point class.
package com.mycompany.fonems.webapp.server;
import java.net.InetAddress;
import java.net.UnknownHostException;
import javax.inject.Inject;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration;
import org.springframework.boot.autoconfigure.validation.ValidationAutoConfiguration;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.Environment;
#Slf4j
#Configuration
#ComponentScan(basePackages = { "com.mycompany.fonems" })
#EnableAutoConfiguration(exclude = { DataSourceAutoConfiguration.class, HibernateJpaAutoConfiguration.class,
ValidationAutoConfiguration.class })
public class FonemsWebappApplication {
#Inject
private Environment env;
public static void main(String[] args) throws UnknownHostException {
log.info("-------------------------------\tApplication is starting ...");
SpringApplicationBuilder app = new SpringApplicationBuilder(FonemsWebappApplication.class);
Environment env = app.run(args).getEnvironment();
String portNumber = env.getProperty("server.port");
log.info("\n----------------------------------------------------------\n\t"
+ "Application '{}' is running! Access URLs:\n\t" + "Local: \t\thttp://127.0.0.1:{}\n\t"
+ "External: \thttp://{}:{}\n----------------------------------------------------------",
env.getProperty("spring.application.name"), portNumber, InetAddress.getLocalHost().getHostAddress(), portNumber);
log.info("-------------------------------\tApplication is running");
}
}
I launch my application. It seems to start with no error. Nevertheless, in my web broser I have this error:
Problem accessing /fonemswebapp/FONEMSWebMessageService.rpc
The path is not found
Here the logs:
[ main] o.s.w.s.resource.ResourceUrlProvider : Looking for resource handler mappings
[ main] o.s.w.s.resource.ResourceUrlProvider : Found resource handler mapping: URL pattern="/**/favicon.ico", locations=[ServletContext resource [/
], class path resource [META-INF/resources/], class path resource [resources/], class path resource [static/], class path resource [public/], class path resource []], resolvers=[org.springframework.we
b.servlet.resource.PathResourceResolver#7de5871d]
[ main] o.s.w.s.resource.ResourceUrlProvider : Found resource handler mapping: URL pattern="/webjars/**", locations=[class path resource [META-INF/
resources/webjars/]], resolvers=[org.springframework.web.servlet.resource.PathResourceResolver#49d42faf]
[ main] o.s.w.s.resource.ResourceUrlProvider : Found resource handler mapping: URL pattern="/**", locations=[ServletContext resource [/], class pat
h resource [META-INF/resources/], class path resource [resources/], class path resource [static/], class path resource [public/]], resolvers=[org.springframework.web.servlet.resource.PathResourceResol
ver#4948daec]
[ main] o.s.web.servlet.DispatcherServlet : Initializing servlet 'dispatcherServlet'
[ main] o.s.web.servlet.DispatcherServlet : FrameworkServlet 'dispatcherServlet': initialization started
[ main] o.s.web.servlet.DispatcherServlet : Using MultipartResolver [org.springframework.web.multipart.support.StandardServletMultipartResolver#
709d86a2]
[ main] o.s.web.servlet.DispatcherServlet : Unable to locate LocaleResolver with name 'localeResolver': using default [org.springframework.web.s
ervlet.i18n.AcceptHeaderLocaleResolver#2e1add6f]
[ main] o.s.web.servlet.DispatcherServlet : Unable to locate ThemeResolver with name 'themeResolver': using default [org.springframework.web.ser
vlet.theme.FixedThemeResolver#46702c26]
[ main] o.s.web.servlet.DispatcherServlet : Unable to locate RequestToViewNameTranslator with name 'viewNameTranslator': using default [org.spri
ngframework.web.servlet.view.DefaultRequestToViewNameTranslator#2e3cd732]
[ main] o.s.web.servlet.DispatcherServlet : Unable to locate FlashMapManager with name 'flashMapManager': using default [org.springframework.web
.servlet.support.SessionFlashMapManager#7f6b57f2]
[ main] o.s.web.servlet.DispatcherServlet : Published WebApplicationContext of servlet 'dispatcherServlet' as ServletContext attribute with name
[org.springframework.web.servlet.FrameworkServlet.CONTEXT.dispatcherServlet]
[ main] o.s.web.servlet.DispatcherServlet : FrameworkServlet 'dispatcherServlet': initialization completed in 31 ms
[ main] o.s.web.servlet.DispatcherServlet : Servlet 'dispatcherServlet' configured successfully
[ main] .s.b.c.e.j.JettyEmbeddedServletContainer : Jetty started on port(s) 8088 (http/1.1)
[ main] o.s.w.c.s.StandardServletEnvironment : Adding [server.ports] PropertySource with highest search precedence
[ main] c.n.f.w.server.FonemsWebappApplication : Started FonemsWebappApplication in 7.634 seconds (JVM running for 8.248)
[ main] c.n.f.w.server.FonemsWebappApplication :
----------------------------------------------------------
Application 'fonems-webapp-refonte' is running! Access URLs:
Local: http://127.0.0.1:8088
External: http://10.20.146.96:8088
----------------------------------------------------------
[ main] c.n.f.w.server.FonemsWebappApplication : ------------------------------- Application is running
<< Then I launch this URL: http://127.0.0.1:8088/Fonemswebapp.html in my web broser>>
o.s.web.servlet.DispatcherServlet : DispatcherServlet with name 'dispatcherServlet' processing GET request for [/fonemswebapp/fonemsweba
pp.nocache.js]
s.w.s.m.m.a.RequestMappingHandlerMapping : Looking up handler method for path /fonemswebapp/fonemswebapp.nocache.js
s.w.s.m.m.a.RequestMappingHandlerMapping : Did not find handler method for [/fonemswebapp/fonemswebapp.nocache.js]
o.s.w.s.handler.SimpleUrlHandlerMapping : Matching patterns for request [/fonemswebapp/fonemswebapp.nocache.js] are [/**]
o.s.w.s.handler.SimpleUrlHandlerMapping : URI Template variables for request [/fonemswebapp/fonemswebapp.nocache.js] are {}
o.s.w.s.handler.SimpleUrlHandlerMapping : Mapping [/fonemswebapp/fonemswebapp.nocache.js] to HandlerExecutionChain with handler [ResourceHttpR
equestHandler [locations=[ServletContext resource [/], class path resource [META-INF/resources/], class path resource [resources/], class path resource [static/], class path resource [public/]], resol
vers=[org.springframework.web.servlet.resource.PathResourceResolver#4948daec]]] and 1 interceptor
o.s.web.servlet.DispatcherServlet : Last-Modified value for [/fonemswebapp/fonemswebapp.nocache.js] is: -1
o.s.web.servlet.DispatcherServlet : DispatcherServlet with name 'dispatcherServlet' processing GET request for [/error]
s.w.s.m.m.a.RequestMappingHandlerMapping : Looking up handler method for path /error
s.w.s.m.m.a.RequestMappingHandlerMapping : Returning handler method [public org.springframework.http.ResponseEntity<java.util.Map<java.lang.Str
ing, java.lang.Object>> org.springframework.boot.autoconfigure.web.BasicErrorController.error(javax.servlet.http.HttpServletRequest)]
o.s.web.servlet.DispatcherServlet : Last-Modified value for [/error] is: -1
o.s.w.s.m.m.a.HttpEntityMethodProcessor : Written [{timestamp=Fri Jun 16 11:02:10 CEST 2017, status=404, error=Not Found, message=Not Found, p
ath=/fonemswebapp/fonemswebapp.nocache.js}] as "application/json" using [org.springframework.http.converter.json.MappingJackson2HttpMessageConverter#6b09ce57]
o.s.web.servlet.DispatcherServlet : Null ModelAndView returned to DispatcherServlet with name 'dispatcherServlet': assuming HandlerAdapt
er completed request handling
o.s.web.servlet.DispatcherServlet : Successfully completed request
o.s.web.servlet.DispatcherServlet : Null ModelAndView returned to DispatcherServlet with name 'dispatcherServlet': assuming HandlerAdapt
er completed request handling
o.s.web.servlet.DispatcherServlet : Successfully completed request
o.s.web.servlet.DispatcherServlet : DispatcherServlet with name 'dispatcherServlet' processing GET request for [/fonemswebapp/fonemsweba
pp.nocache.js]
s.w.s.m.m.a.RequestMappingHandlerMapping : Looking up handler method for path /fonemswebapp/fonemswebapp.nocache.js
s.w.s.m.m.a.RequestMappingHandlerMapping : Did not find handler method for [/fonemswebapp/fonemswebapp.nocache.js]
o.s.w.s.handler.SimpleUrlHandlerMapping : Matching patterns for request [/fonemswebapp/fonemswebapp.nocache.js] are [/**]
o.s.w.s.handler.SimpleUrlHandlerMapping : URI Template variables for request [/fonemswebapp/fonemswebapp.nocache.js] are {}
o.s.w.s.handler.SimpleUrlHandlerMapping : Mapping [/fonemswebapp/fonemswebapp.nocache.js] to HandlerExecutionChain with handler [ResourceHttpR
equestHandler [locations=[ServletContext resource [/], class path resource [META-INF/resources/], class path resource [resources/], class path resource [static/], class path resource [public/]], resol
vers=[org.springframework.web.servlet.resource.PathResourceResolver#4948daec]]] and 1 interceptor
o.s.web.servlet.DispatcherServlet : Last-Modified value for [/fonemswebapp/fonemswebapp.nocache.js] is: -1
o.s.web.servlet.DispatcherServlet : DispatcherServlet with name 'dispatcherServlet' processing GET request for [/error]
s.w.s.m.m.a.RequestMappingHandlerMapping : Looking up handler method for path /error
s.w.s.m.m.a.RequestMappingHandlerMapping : Returning handler method [public org.springframework.http.ResponseEntity<java.util.Map<java.lang.Str
ing, java.lang.Object>> org.springframework.boot.autoconfigure.web.BasicErrorController.error(javax.servlet.http.HttpServletRequest)]
o.s.web.servlet.DispatcherServlet : Last-Modified value for [/error] is: -1
o.s.w.s.m.m.a.HttpEntityMethodProcessor : Written [{timestamp=Fri Jun 16 11:02:10 CEST 2017, status=404, error=Not Found, message=Not Found, p
ath=/fonemswebapp/fonemswebapp.nocache.js}] as "application/json" using [org.springframework.http.converter.json.MappingJackson2HttpMessageConverter#6b09ce57]
o.s.web.servlet.DispatcherServlet : Null ModelAndView returned to DispatcherServlet with name 'dispatcherServlet': assuming HandlerAdapt
er completed request handling
o.s.web.servlet.DispatcherServlet : Successfully completed request
o.s.web.servlet.DispatcherServlet : Null ModelAndView returned to DispatcherServlet with name 'dispatcherServlet': assuming HandlerAdapt
er completed request handling
o.s.web.servlet.DispatcherServlet : Successfully completed request
When I launch the url in firefox, my form is displayed. When I click on search button, I have this error in the broser:
HTTP ERROR 404 Problem accessing /fonemswebapp/FONEMSWebMessageService.rpc. Reason: Not Found
Here is my pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.mycompany.fonems</groupId>
<artifactId>fonems-parent</artifactId>
<version>0.0.140-SNAPSHOT</version>
<relativePath>../fonems-parent/pom.xml</relativePath>
</parent>
<artifactId>fonems-webapp-refonte</artifactId>
<packaging>war</packaging>
<name>FONEMS WebApp</name>
<properties>
<!-- Setting maven.compiler.source to something different to 1.8
needs that you configure the sourceLevel in gwt-maven-plugin since
GWT compiler 2.8 requires 1.8 (see gwt-maven-plugin block below) -->
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<!-- Don't let your Mac use a crazy non-standard encoding -->
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
</properties>
<dependencyManagement>
<dependencies>
<!-- ensure all GWT deps use the same version (unless overridden) -->
<dependency>
<groupId>com.google.gwt</groupId>
<artifactId>gwt</artifactId>
<version>${gwt.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jetty</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.mycompany.fonems</groupId>
<artifactId>fonems-fwk-server-common</artifactId>
<version>${project.version}</version>
<exclusions>
<exclusion>
<artifactId>xercesImpl</artifactId>
<groupId>xerces</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.mycompany.fonems</groupId>
<artifactId>fonems-refonte-dao</artifactId>
<version>${project.version}</version>
<exclusions>
<exclusion>
<artifactId>javax.el-api</artifactId>
<groupId>javax.el</groupId>
</exclusion>
<exclusion>
<artifactId>xercesImpl</artifactId>
<groupId>xerces</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.google.gwt</groupId>
<artifactId>gwt-servlet</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.google.gwt</groupId>
<artifactId>gwt-user</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.google.gwt</groupId>
<artifactId>gwt-dev</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.smartgwt</groupId>
<artifactId>smartgwt</artifactId>
<version>${smartgwt.version}</version>
</dependency>
<dependency>
<groupId>com.smartgwt</groupId>
<artifactId>smartgwt-skins</artifactId>
<version>${smartgwt.version}</version>
<optional>true</optional>
</dependency>
<dependency>
<groupId>mycompany.drh</groupId>
<artifactId>newncauth</artifactId>
<version>${mycompany.drh.version}</version>
</dependency>
<dependency>
<groupId>mycompany.drh</groupId>
<artifactId>mycompany.droits-habilitations.rmi</artifactId>
<version>${mycompany.drh.rmi.version}</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<scope>compile</scope>
</dependency>
</dependencies>
<build>
<!-- Output classes directly into the webapp, so that IDEs and "mvn process-classes" update them in DevMode -->
<!-- <outputDirectory>${project.build.directory}/src/main/webapp/WEB-INF/classes</outputDirectory> -->
<plugins>
<!-- GWT Maven Plugin-->
<plugin>
<groupId>net.ltgt.gwt.maven</groupId>
<artifactId>gwt-maven-plugin</artifactId>
<version>${gwt.maven.plugin.version}</version>
<executions>
<execution>
<goals>
<goal>import-sources</goal>
<goal>compile</goal>
<goal>import-test-sources</goal>
<goal>test</goal>
</goals>
</execution>
</executions>
<configuration>
<moduleName>com.mycompany.fonems.webapp.Fonemswebapp</moduleName>
<moduleShortName>Fonemswebapp</moduleShortName>
<failOnError>true</failOnError>
<!-- GWT compiler 2.8 requires 1.8, hence define sourceLevel here if you use
a different source language for java compilation -->
<sourceLevel>1.8</sourceLevel>
<!-- Compiler configuration -->
<compilerArgs>
<!-- Ask GWT to create the Story of Your Compile (SOYC) (gwt:compile) -->
<arg>-compileReport</arg>
<arg>-XcompilerMetrics</arg>
</compilerArgs>
<!-- DevMode configuration -->
<warDir>${project.build.directory}/${project.build.finalName}</warDir>
<classpathScope>compile+runtime</classpathScope>
<!-- URL(s) that should be opened by DevMode (gwt:devmode). -->
<startupUrls>
<startupUrl>Fonemswebapp.html</startupUrl>
</startupUrls>
<webappDirectory>${outputFolder}</webappDirectory>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<configuration>
<warSourceDirectory>target/www/</warSourceDirectory>
<packagingExcludes>WEB-INF/lib/tomcat-*.jar</packagingExcludes>
</configuration>
</plugin>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<executable>false</executable>
<!-- Enable the line below to have remote debugging of your application on port 5005 <jvmArguments>-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5005</jvmArguments> -->
</configuration>
</plugin>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<descriptors>
<descriptor>assembly.xml</descriptor>
</descriptors>
</configuration>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
Why, in the logs, we see ServletDispatcher occurences? In my application should I define a ServletDispatcher? If it is the case, how to define my 5 web.xml servlets and filter to be taken into account?
What is curious, is that application runs and responds normally when I launch it from the GWT Development Mode (eclipse plugin).
Thank you