I want to add to a an existing spring REST api project a simply configuration for WebSecurityConfigurerAdapter to test it. But when spring starts it doesn't load the configuration. Maybe I need to add it to the application context but I don't know how to do it.
If I make a curl localhost:8080/ always get an unauthorized response, so I think that is not loading the configuration, why it is? Or, how I should load it?
In all the diversed projects that I saw on github, they never do special things to load it! Its maybe because its loading an embbeded servlet first?
This is the simple web security configuration:
#SuppressWarnings("SpringJavaAutowiringInspection")
#Configuration
#EnableWebSecurity
#EnableGlobalMethodSecurity(prePostEnabled = true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
#Autowired
private UserDetailsService userDetailsService;
#Autowired
public void configureAuthentication(AuthenticationManagerBuilder authenticationManagerBuilder) throws Exception {
authenticationManagerBuilder
.userDetailsService(this.userDetailsService)
.passwordEncoder(passwordEncoder());
}
#Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
#Override
protected void configure(HttpSecurity httpSecurity) throws Exception {
httpSecurity
// we don't need CSRF because our token is invulnerable
.csrf().disable()
// don't create session
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and()
.authorizeRequests()
//.antMatchers(HttpMethod.OPTIONS, "/**").permitAll()
// allow anonymous resource requests
.antMatchers(
HttpMethod.GET,
"/",
"/*.html",
"/favicon.ico",
"/**/*.html",
"/**/*.css",
"/**/*.js",
"/**"
).permitAll()
.antMatchers("/auth/**").permitAll()
.anyRequest().authenticated();
// disable page caching
httpSecurity.headers().cacheControl();
}
}
And this is my Application
#Configuration
#EnableConfigurationProperties
#ComponentScan(basePackageClasses = SimpleCORSFilter.class)
#EnableAutoConfiguration org.springframework.boot.actuate.autoconfigure.ManagementSecurityAutoConfiguration.class})
#EntityScan(basePackages = "com.thing.model")
#RestController
public class Application {
#Bean
public FilterRegistrationBean filterRegistrationBean() {
FilterRegistrationBean registrationBean = new FilterRegistrationBean();
CharacterEncodingFilter characterEncodingFilter = new CharacterEncodingFilter();
registrationBean.setFilter(characterEncodingFilter);
characterEncodingFilter.setEncoding("UTF-8");
characterEncodingFilter.setForceEncoding(true);
registrationBean.setOrder(Integer.MIN_VALUE);
registrationBean.addUrlPatterns("/*");
return registrationBean;
}
public static void main(String[] args) {
SpringApplication application = new SpringApplication(Application.class);
SpringApplication.run(Application.class, args);
}
#RequestMapping("/")
public String home() {
return "Hello World";
}
pom.xml dependencies
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.geotools</groupId>
<artifactId>gt-referencing</artifactId>
<version>8.2</version>
<type>jar</type>
</dependency>
<dependency>
<groupId>org.jsoup</groupId>
<artifactId>jsoup</artifactId>
<version>1.7.2</version>
<type>jar</type>
</dependency>
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<version>9.3-1102-jdbc41</version>
</dependency>
<dependency>
<groupId>org.yaml</groupId>
<artifactId>snakeyaml</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
I need to add the WebSecurityConfig to the application context adding this line in the main class declaration:
...
#Import(WebSecurityConfig.class)
public class Application {
...
Another thing that I did is upgrade SpringBoot to 1.4.3.RELEASE and put the main application to root folder:
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.4.3.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
The tree will be, for example:
└── com
└── app
├── Application.java
└── config
└── WebSecurityConfig.java
This automatically load all #Configuration in son folders.
Have a look at this example to learn how to enable web security in Spring projects.
#RunWith(SpringRunner.class)
#SpringBootTest
#AutoConfigureMockMvc
public class ClientResourceControllerTest {
Above helped me for the same issue.
Related
So I am trying to learn Spring because I'll need it for a project later on this year. Project is using Spring Boot 3.0.2 and Java 17. I am also using the Spring Security dependency, which means that I'll need to authorize some URL's without using tokens.
I found a way to do that for all URL's except the H2-console. For some reason, no matter how I write the code, I can't access the H2-console because I'll get 403(Unauthorized) when going to localhost:8080/h2-console.
Any help on this would be appreciated.
This is the pom 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 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>3.0.2</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.example</groupId>
<artifactId>newproject</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>newproject</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>17</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</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.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</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>
This is the application.properties file:
#For h2 database
spring.datasource.url=jdbc:h2:mem:test;DB_CLOSE_DELAY=-1
spring.datasource.driverClassName=org.h2.Driver
spring.datasource.username=sa
spring.datasource.password=
spring.jpa.generate-ddl=true
spring.jpa.show-sql=true
spring.jpa.hibernate.ddl-auto=create-drop
spring.jpa.properties.hibernate.format_sql=true
spring.jpa.database-platform=org.hibernate.dialect.H2Dialect
## H2 specific settings
spring.h2.console.enabled=true
This is the WebSecurityConfig class:
package com.example.newproject.configs;
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.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.SecurityFilterChain;
#Configuration
#EnableWebSecurity
public class WebSecurityConfig {
private static final String[] WHITE_LIST_URLS = {
"/register",
"/api/v1/getUsers",
"/h2-console/**"
};
#Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder(11);
}
#Bean
SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
// FIXME: Cant access h2 console
// http
// .cors()
// .and()
// .csrf()
// .disable()
// .authorizeHttpRequests()
// .requestMatchers(WHITE_LIST_URLS)
// .permitAll();
//
http.authorizeHttpRequests().requestMatchers(WHITE_LIST_URLS).permitAll();
return http.build();
}
}
This is the result:
result
As you can see, I tried to do this in 2 ways. Both work for "/register" and "/api/v1/getUsers", but do not work for "/h2-console/**". I might be doing something wrong, but the commented code is from a youtube guide and the uncommented code is from another question on StackOverflow, so I am all out of ideas. Any help would be appreciated.
EDIT 1: Problem was solved by the marked answers. This is the code that works for me:
public class WebSecurityConfig {
private static final AntPathRequestMatcher[] WHITE_LIST_URLS = {
new AntPathRequestMatcher("/register"),
new AntPathRequestMatcher("/api/v1/getUsers"),
// new AntPathRequestMatcher("/h2-console/**"),
};
#Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder(11);
}
#Bean
SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http
.cors()
.and()
.csrf()
.disable()
.authorizeHttpRequests()
.requestMatchers(WHITE_LIST_URLS)
.permitAll();
return http.build();
}
#Bean
WebSecurityCustomizer webSecurityCustomizer() {
return web -> web.ignoring()
.requestMatchers(new AntPathRequestMatcher("/h2-console/**"));
}
}
By default, when requestMatchers(WHITE_LIST_URLS) is used, it will fall into the MvcRequestMatcher (Reference). The MvcRequestMatcher will only match against the Web MVC DispatcherServlet internal mappings. The H2 Console is not part of the DispatcherServlet by default, but the custom controllers in the application are, hence the difference.
One option to fix it is by using an AntPathRequestMatcher for H2 Console like so:
public class WebSecurityConfig {
// some of the original code was omitted for brevity
private static final String[] WHITE_LIST_URLS = {
"/register",
"/api/v1/getUsers"
};
#Bean
SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http.authorizeHttpRequests()
.requestMatchers(WHITE_LIST_URLS)
.permitAll()
.and()
.authorizeHttpRequests()
.requestMatchers(new AntPathRequestMatcher("/h2-console/**"))
.permitAll();
http.csrf().disable();
return http.build();
}
}
A possible alternative is to use an array of AntPathRequestMatcher instead of an array of String for the whitelist, and keep the security filter as-is:
public class WebSecurityConfig {
// some of the original code was omitted for brevity
private static final AntPathRequestMatcher[] WHITE_LIST_URLS = {
new AntPathRequestMatcher("/register"),
new AntPathRequestMatcher("/api/v1/getUsers"),
new AntPathRequestMatcher("/h2-console/**")
};
#Bean
SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http.authorizeHttpRequests()
.requestMatchers(WHITE_LIST_URLS)
.permitAll();
http.csrf().disable();
return http.build();
}
}
Another option is to add a customizer to ignore H2 Console, which should be fine since H2 Console has its own authentication mechanism.
#Bean
WebSecurityCustomizer webSecurityCustomizer() {
return web -> web.ignoring()
.requestMatchers(new AntPathRequestMatcher("/h2-console/**"));
}
EDIT 1: It is also necessary to disable CSRF, added to snippets above.
EDIT 2: Adding an extra option to ignore H2 Console with Spring Boot 3.
This question already has answers here:
Use Keycloak Spring Adapter with Spring Boot 3
(3 answers)
Closed last month.
I'm having issue about setting #KeycloakConfiguration, I watched keycloak's docs and it say that i have to create a class and set all the methods that are set in the documentation
Documentation Keycloak:
#KeycloakConfiguration
public class SecurityConfig extends KeycloakWebSecurityConfigurerAdapter
{
/**
* Registers the KeycloakAuthenticationProvider with the authentication manager.
*/
#Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth.authenticationProvider(keycloakAuthenticationProvider());
}
/**
* Defines the session authentication strategy.
*/
#Bean
#Override
protected SessionAuthenticationStrategy sessionAuthenticationStrategy() {
return new RegisterSessionAuthenticationStrategy(buildSessionRegistry());
}
#Bean
protected SessionRegistry buildSessionRegistry() {
return new SessionRegistryImpl();
}
#Override
protected void configure(HttpSecurity http) throws Exception
{
super.configure(http);
http
.authorizeRequests()
.antMatchers("/customers*").hasRole("USER")
.antMatchers("/admin*").hasRole("ADMIN")
.anyRequest().permitAll();
}
}
so i did, but when i copy and paste that in my class it says that i have to implements two more method of security configurer that are init(Builder:B) void and configure (Builder:B) void, other than that i already have a configure method.
I saw in the Docs but doesn't specify what i have to do with these two methods, i would like to know if I'm missing something or if is a feature of the last version of keycloak, the keycloak version that i'm using is the 20.0.2
my dependecies are this:
<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>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-spring-boot-starter</artifactId>[enter image description here](https://i.stack.imgur.com/v2En6.png)
</dependency>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-spring-security-adapter</artifactId>
<version>20.0.2</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.keycloak.bom</groupId>
<artifactId>keycloak-adapter-bom</artifactId>
<version>20.0.2</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>```
As i say i would like to know what i have to do with these two methods
Check Use Keycloak Spring Adapter with Spring Boot 3 or https://www.baeldung.com/spring-boot-keycloak both resolved My problem with same issue
I'm writing the Spring Boot project with basic authentication and authorization using Spring Security. I have a config class which extends the WebSecurityConfigurerAdapter (I wanna get rid of it later, since it's deprecated).
So, my config class looks like this:
#Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
#Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication().withUser("spring_user")
.password("password123")
.roles("ADMIN");
}
#Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
.authorizeHttpRequests((authz) -> authz.anyRequest().authenticated())
.httpBasic(Customizer.withDefaults());
return http.build();
}
#Bean
public static PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
}
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 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>3.0.1</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.codelib</groupId>
<artifactId>basic-auth-security</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>basic-auth-security</name>
<description>basic-auth-security</description>
<properties>
<java.version>17</java.version>
</properties>
<dependencies>
<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>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.springframework.security</groupId>
<artifactId>spring-security-config</artifactId>
<version>5.7.3</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
Note that I have spring-boot-starter-web dependency.
There is nothing interesting in the rest of the project. When I try to run the app, the following message is shown:
java: cannot access javax.servlet.Filter
class file for javax.servlet.Filter not found
And IDEA redirects me to the config file. (but no lines of code are underlined with red)
What can be the cause of this?
So, the solution was simple. If you're migrating to Spring 6, you should get rid of using the WebSecurityConfigurerAdapter class and instead configure your security without it.
I've written a new configuration (which does the same operations as well as the config provided in the question), and now it looks like this:
#Configuration
#EnableWebSecurity
public class SpringSecurityConfig {
#Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http
.authorizeHttpRequests((authorize) -> authorize.anyRequest().authenticated())
.httpBasic(Customizer.withDefaults())
.formLogin(Customizer.withDefaults());
return http.build();
}
#Bean
public UserDetailsService userDetailsService() {
PasswordEncoder encoder = PasswordEncoderFactories.createDelegatingPasswordEncoder();
UserDetails user = User
.withUsername("spring_user")
.password(encoder.encode("password123"))
.roles("USER")
.build();
return new InMemoryUserDetailsManager(user);
}
}
That's the minimal configuration required by Spring Security 6 to provide basic authentication, default password encoder (which is recommended to use) and in-memory user.
I am working on spring boot admin server but i want to include a spring security using the spring boot starter security dependency to create a login page. When i put my credentials username and password i get the error of this application has no explicit mapping for error. From what i saw i tried including thymeleaf dependency to resolve this problem but it didn't work. Please tell me what i am missing.
package com.example.demo;
import de.codecentric.boot.admin.server.config.EnableAdminServer;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
#EnableAdminServer
#SpringBootApplication
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
#Configuration
public static class SecurityConfig extends WebSecurityConfigurerAdapter {
#Override
protected void configure(HttpSecurity http) throws Exception {
http.formLogin().loginPage("/login.html").loginProcessingUrl("/login").permitAll();
http.logout().logoutUrl("/logout");
http.csrf().disable();
http.authorizeRequests().antMatchers("/login.html", "/**/*.css", "/img/**", "/third-party/**").permitAll();
http.authorizeRequests().antMatchers("/**").authenticated();
http.httpBasic();
}
}
}
Springboot Admin server already have the login page and no explicit template has to be created for it. Although i believe that it should be customizable but haven't gone deep into it. Below is my working solution for Springboot admin with default login page.
Main Application class
#EnableAdminServer
#SpringBootApplication
public class AdminApplication {
public static void main(String[] args) {
SpringApplication.run(AdminApplication.class, args);
}
}
Spring security configuration
#Configuration
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
private final String adminContextPath;
public WebSecurityConfig(AdminServerProperties adminServerProperties) {
this.adminContextPath = adminServerProperties.getContextPath();
}
#Override
protected void configure(HttpSecurity http) throws Exception {
SavedRequestAwareAuthenticationSuccessHandler successHandler = new SavedRequestAwareAuthenticationSuccessHandler();
successHandler.setTargetUrlParameter("redirectTo");
successHandler.setDefaultTargetUrl(adminContextPath + "/");
http.authorizeRequests()
.antMatchers(adminContextPath + "/assets/**").permitAll()
.antMatchers(adminContextPath + "/login").permitAll()
.anyRequest().authenticated()
.and()
.formLogin().loginPage(adminContextPath + "/login").successHandler(successHandler).and()
.logout().logoutUrl(adminContextPath + "/logout").and()
.httpBasic().and()
.csrf()
.csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse())
.ignoringAntMatchers(
adminContextPath + "/instances",
adminContextPath + "/actuator/**"
);
}
}
Credentials to login on Admin server is defined in application.properties as
spring.security.user.name=admin
spring.security.user.password=Admin#123
Let me know if that helps.
EDIT : I tried to replicate scenario using the files you provided. It was pom.xml that had some missing dependencies. On resolving it, i can login into admin server successfully. Can you update your pom as below and retry. Please refer the comments i added in 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.0.5.RELEASE</version> <!-- EspringDev CHANGED this version -->
<relativePath/>
</parent>
<groupId>com.example</groupId>
<artifactId>demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>admin</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
<spring-boot-admin.version>2.0.2</spring-boot-admin.version> <!-- EspringDev CHANGED this version -->
</properties>
<dependencies>
<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>de.codecentric</groupId>
<artifactId>spring-boot-admin-starter-server</artifactId>
</dependency>
<!-- EspringDev ADDED below 2 dependencies -->
<dependency>
<groupId>de.codecentric</groupId>
<artifactId>spring-boot-admin-server-ui</artifactId>
</dependency>
<dependency>
<groupId>io.projectreactor.netty</groupId>
<artifactId>reactor-netty</artifactId>
<version>0.8.6.RELEASE</version>
</dependency>
<!-- dependencies -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>de.codecentric</groupId>
<artifactId>spring-boot-admin-dependencies</artifactId>
<version>${spring-boot-admin.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>
</plugin>
</plugins>
</build>
</project>
Jsp is shown as default text image
My index.jsp
<%# page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<h1>HelloWorld</h1>
</body>
</html>
My index controller
#Controller
public class IndexController {
#RequestMapping("/")
public String index(Model model) {
return "index";
}
}
Web Config
#Configuration
#EnableWebMvc
#ComponentScan("ru.hyndo.web")
public class WebConfig extends WebMvcConfigurerAdapter {
#Bean
public ViewResolver viewResolver() {
InternalResourceViewResolver resolver = new InternalResourceViewResolver();
resolver.setPrefix("/WEB-INF/views/");
resolver.setSuffix(".jsp");
resolver.setViewClass(JstlView.class);
return resolver;
}
public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
configurer.enable();
}
}
web app initializer
public class SpittrWebAppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
#Override
protected String[] getServletMappings() {
return new String[] { "/" };
}
#Override
protected Class<?>[] getRootConfigClasses() {
return new Class<?>[] { RootConfig.class };
}
#Override
protected Class<?>[] getServletConfigClasses() {
return new Class<?>[] { WebConfig.class };
}
}
RootConfig
#Configuration
#ComponentScan(basePackages = { "ru.hyndo.web" }, excludeFilters = {
#ComponentScan.Filter(type = FilterType.ANNOTATION, value = EnableWebMvc.class) })
public class RootConfig {
}
Application
#SpringBootApplication
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}
pom.xml
<groupId>com.example</groupId>
<artifactId>demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>demo</name>
<description>Demo project for Spring Boot</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.10.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.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-jasper</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>javax.servlet.jsp-api</artifactId>
<version>2.3.1</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet.jsp.jstl</groupId>
<artifactId>javax.servlet.jsp.jstl-api</artifactId>
<version>1.2.1</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</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>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
I tried everything but nothing worked. If you can give some working examples pls give.
Also if you need my project structure in idea - http://prntscr.com/iaemoc
I am stuck here and it feels like I won't ever make it :( I looked at huge amount of tutorials and as many questions on StackOverflow as I could found with no help.
Any advice is very much appreciated!
In a war project, JSP pages are served from src/main/webapp/WEB-INF/.
In a Jar project, JSP pages
cannot
simply be served from webapp location or from src/main/resources/. That's because of the limitation stated in boot ref docs.
The location src/main/webapp/WEB-INF may work in exploded form but should be avoided. From boot ref docs:
Do not use the src/main/webapp directory if your application will be packaged as a jar. Although this directory is a common standard, it will only work with war packaging and it will be silently ignored by most build tools if you generate a jar.
Fortunately there is another option for a Jar project: Servlet 3.0 specification allows to have dynamic pages in src/main/resources/META-INF/resources/ (Please check out an example here).
SOURCE