I m studying spring security.
I want to display original html file(loginForm) in spring security when I click localhost/8080:loginForm.
but it shows default page of spring security.
it says please sign in(which i didnt make)
How can I modify it?
build gradle
plugins {
id 'org.springframework.boot' version '2.4.1'
id 'io.spring.dependency-management' version '1.0.10.RELEASE'
id 'java'
}
group = 'com.example'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '1.8'
repositories {
mavenCentral()
}
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'
implementation 'org.springframework.boot:spring-boot-starter-web'
// springsecurityを依存関係に追加
implementation 'org.springframework.boot:spring-boot-starter-security'
// thymeleaf拡張ライブラリを依存関係に追加
implementation 'org.thymeleaf.extras:thymeleaf-extras-springsecurity5'
runtimeOnly 'mysql:mysql-connector-java'
testImplementation('org.springframework.boot:spring-boot-starter-test') {
exclude group: 'org.junit.vintage', module: 'junit-vintage-engine'
}
}
test {
useJUnitPlatform()
}
SecurityConfig.java
#EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
#Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/loginForm").permitAll()
.anyRequest().authenticated(); //
http.formLogin()
.loginProcessingUrl("/login")
.loginPage("/loginForm")
.usernameParameter("email")
.passwordParameter("password")
.defaultSuccessUrl("/home", true)
.failureUrl("/loginForm?error");
LoginController.java
#Controller
public class LoginController {
#GetMapping("/loginForm")
public String getLogin() {
return "loginForm";
}
}
loginForm.html(what I want to display)
<body>
<div th:if="${param.error}">
<p>ユーザ名またはパスワードが違います。</p>
</div>
<form th:action="#{/login}" method="post">
<div>
<label>メールアドレス: </label>
<input type="email" name="email">
</div>
<div>
<label>パスワード: </label>
<input type="password" name="password">
</div>
<div>
<input type="submit" value="ログイン">
</div>
</form>
</body>
Related
I'm new to Spring security and I'm trying to create a custom login page. My problem is the authentication always failed and I always received the Bad Credentials message eventhough the password was correct, note that I have used BCRyptPasswordEncoder when I am saving the new registered account. Without the custom login and using the default formlogin it works fine
This is my WebSecurityConfig
#EnableWebSecurity
#Configuration
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
#Autowired
private DataSource dataSource;
#Bean
public UserDetailsService userDetailsService(){
return new CustomApplicantDetailsService();
}
#Bean
public BCryptPasswordEncoder passwordEncoder(){
return new BCryptPasswordEncoder();
}
#Bean
public DaoAuthenticationProvider authenticationProvider() {
DaoAuthenticationProvider authProvider = new DaoAuthenticationProvider();
authProvider.setUserDetailsService(userDetailsService());
authProvider.setPasswordEncoder(passwordEncoder());
return authProvider;
}
#Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.authenticationProvider(authenticationProvider());
}
#Override
protected void configure(HttpSecurity http) throws Exception { //login logout
http
.authorizeRequests()
.antMatchers("/resources/**")
.authenticated()
.anyRequest()
.permitAll()
.and()
.formLogin()
.loginPage("/login")
.loginProcessingUrl("/loginProcess")
.defaultSuccessUrl("/account")
.usernameParameter("email")
//.successForwardUrl("/account")
.permitAll()
.and()
.logout()
.invalidateHttpSession(true)
.clearAuthentication(true)
.logoutSuccessUrl("/login?logout")
.permitAll();
}}
This is my TemplateController to hanlde the url request. Note that I have tried the GetMapping first with the same line of code as loginProcess and without loginprocessingURL in configure but I received the error method get not supported altho most tutorials works somehow.
#Controller
#RequestMapping("/")
public class TemplateController {
#GetMapping("login")
public String login(){
return "loginStudent"; // logicalname
}
#PostMapping("loginProcess")
public String loginProcess(){
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
if(authentication == null ||authentication instanceof AnonymousAuthenticationToken){
return "loginStudent"; // logicalname
}
return "redirect:/account.html"; // redirect to account homepage
}
And here is the form from the "loginStudent.html"
<form th:action="#{/loginProcess}" th:method="post" >
<div th:if="${param.error}">
<p class="text-danger">. [[${session.SPRING_SECURITY_LAST_EXCEPTION.message}]]</p>
</div>
<div th:if="${param.logout}">
<p class="text-warning">You have been logged out.</p>
</div>
<div class="form-group">
<label for="email">E-Mail Adresse:</label>
<input type="email" class="form-control" placeholder="Enter email" id="email" name="username " autofocus="autofocus">
</div>
<div class="form-group">
<label for="password">Passwort:</label>
<input type="password" class="form-control" placeholder="Passwort" id="password" name="password">
</div>
<div class="form-group form-check">
<label class="form-check-label">
<input class="form-check-input" type="checkbox"> Remember me
</label>
</div>
<button type="submit" class="btn btn-primary">Submit</button>
</form>
I am a newbie in spring boot. I'm using basic thymeleaf form login. But when I login it returns "localhost:8080/login?error=true". I don't know why. My username and password in the database are correct. Maybe I must add a new controller with post method? please help me
And here, this is my security config class
protected void configure(HttpSecurity http) throws Exception {
logger.info("-----configure(HttpSecurity http)");
http.authorizeRequests()
.antMatchers("/**").permitAll()
.antMatchers("/user/**").hasAnyRole("USER")
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/login")
.defaultSuccessUrl("/home")
.permitAll()
.and()
.logout()
.permitAll()
.and().csrf().disable();
}
#Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
logger.info("-----configureGlobal(AuthenticationManagerBuilder auth)");
auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder);
}
login form page
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<title>Login</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js"></script>
</head>
<body>
<div class="container">
<h2>Stacked form</h2>
<form th:action="#{/login}" method="post">
<div class="form-group">
<input type="text" name="username" id="username" class="form-control input-lg"
placeholder="UserName" required="true" autofocus="true"/>
</div>
<div class="form-group">
<input type="password" name="password" id="password" class="form-control input-lg"
placeholder="Password" required="true"/>
</div>
<div class="form-group form-check">
<label class="form-check-label">
<input class="form-check-input" type="checkbox" name="remember"> Remember me
</label>
</div>
<a class="btn btn-success" th:href="#{'/register'}" role="button">Register</a>
<button type="submit" class="btn btn-primary">Login</button>
</form>
</div>
</body>
</html>
My controller
#GetMapping("/login")
public String login() {
return "/login";
}
The entity
#Entity(name = "dbo_user")
public class User {
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name = "user_id")
#Id
private int id;
private String email;
private String password;
private String username;
}
First of all, User class has to implement UserDetails interface like this:
// userdetails methods
#Override
public Collection<? extends GrantedAuthority> getAuthorities() {
return this.roles.stream().map(SimpleGrantedAuthority::new).collect(toList());
}
#Override
public String getUsername() {
return this.getEmail();
}
#Override
public boolean isAccountNonExpired() {
return true;
}
#Override
public boolean isAccountNonLocked() {
return true;
}
#Override
public boolean isCredentialsNonExpired() {
return true;
}
#Override
public boolean isEnabled() {
return true;
}
#Transient
private List<String> roles = Arrays.asList("ROLE_USER");
public List<String> getRoles() {
return roles;
}
2nd you need a class that implements UserDetailsService like this:
#Service("customCustomerDetailsService")
public class CustomUserDetailsService implements UserDetailsService {
#Autowired
private CredentialRepository users;
#Override
public UserDetails loadUserByUsername(String email) {
return this.users.findByEmail(email)
.orElseThrow(() -> new UsernameNotFoundException("Username: " + email + " not found"));
}
}
Then you autowire that class into your security config class
#Autowired
CustomUserDetailsService customCustomerDetailsService;
You need to implement DAO DaoAuthenticationProvider in your security config class like this:
#Bean
public DaoAuthenticationProvider authenticationProvider() {
DaoAuthenticationProvider authProvider = new DaoAuthenticationProvider();
authProvider.setUserDetailsService(userDetailsService());
authProvider.setPasswordEncoder(encoder());
return authProvider;
I'm quite sure this question would have been answered on this platform.
Are you using thymeleaf security extras? If so, then you need to have dependency included with maven/gradle and thymeleaf namespaces on the login page.
<dependency>
<groupId>org.thymeleaf.extras</groupId>
<artifactId>thymeleaf-extras-springsecurity5</artifactId>
<version>3.0.4.RELEASE</version>
</dependency>
and
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:th="http://www.thymeleaf.org"
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity5" lang="en">
I followed this code sample https://kotlinlang.org/docs/tutorials/spring-boot-restful.html to get a basic spring boot application working.
Now I want to add frontend components through thymleaf. Passing variables into the Model dont are always null in the outputted html
controller
#Controller
class IndexController {
#GetMapping("/")
fun index(#RequestParam(value = "name", defaultValue = "brian") name: String, model: Model): String {
model.addAttribute("name", name)
model.addAttribute("title", "some title")
return "index"
}
}
resources/templates/index.html
<html xmlns:th="http://www.thymeleaf.org">
<head>
<title th:text="${title}"></title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
</head>
<body>
<div class="page-content">
<h1 th:text="|Hello ${name}!|"></h1>
<h2 th:text="|Welcome to ${title} application|"></h2>
</div>
</body>
</html>
spring seems to a lot of things under the hood so maybe i missing something obvious.
and the build gradle
plugins {
id("org.springframework.boot") version "2.1.6.RELEASE"
id("io.spring.dependency-management") version "1.0.7.RELEASE"
kotlin("jvm") version "1.2.71"
kotlin("plugin.spring") version "1.2.71"
}
group = "com.ghost"
version = "0.0.1-SNAPSHOT"
java.sourceCompatibility = JavaVersion.VERSION_1_8
repositories {
mavenCentral()
}
//extra["springCloudVersion"] = "Greenwich.SR1"
dependencies {
implementation("org.springframework.boot:spring-boot-starter-oauth2-client")
implementation("org.springframework.boot:spring-boot-starter-thymeleaf")
implementation("org.springframework.boot:spring-boot-starter-web")
implementation("com.fasterxml.jackson.module:jackson-module-kotlin")
implementation("org.jetbrains.kotlin:kotlin-reflect")
implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8")
// implementation("org.springframework.cloud:spring-cloud-gcp-starter")
// implementation("org.springframework.cloud:spring-cloud-gcp-starter-storage")
// implementation("org.springframework.cloud:spring-cloud-starter-sleuth")
implementation("org.springframework.session:spring-session-core")
testImplementation("org.springframework.boot:spring-boot-starter-test")
}
//dependencyManagement {
// imports {
// mavenBom("org.springframework.cloud:spring-cloud-dependencies:${property("springCloudVersion")}")
// }
//}
tasks.withType<KotlinCompile> {
kotlinOptions {
freeCompilerArgs = listOf("-Xjsr305=strict")
jvmTarget = "1.8"
}
}
I have configured my Java Spring backend to use in memory authentication but when I do a POST request through my angular2 frontend entering the right username/password in a login form, I always get the following errors:
x POST http://localhost:8080/authenticate 401 () zone.js:1382
x EXCEPTION: Response with status: 401 OK for URL: http://localhost:8080/authenticate core.umd.js:3370
x Uncaught Response {_body: "{"code":401,"message":"Authentication failed","err…reason":"authError","message":"Bad credentials"}}", status: 401, ok: false, statusText: "OK", headers: Headers…} Subscriber.ts:241
I have tried so many different security configurations but nothing seems to work. I may be doing something wrong... here's my code:
SecurityConfiguration.java
#Configuration
#EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
private static final Logger logger = LoggerFactory.getLogger(SecurityConfig.class);
public static final String REMEMBER_ME_KEY = "rememberme_key";
public SecurityConfig() {
super();
logger.info("loading SecurityConfig ................................................ ");
}
#Autowired
private RestUnauthorizedEntryPoint restAuthenticationEntryPoint;
#Autowired
private AccessDeniedHandler restAccessDeniedHandler;
#Autowired
private AuthenticationSuccessHandler restAuthenticationSuccessHandler;
#Autowired
private AuthenticationFailureHandler restAuthenticationFailureHandler;
#Override
public void configure(WebSecurity web) throws Exception {
web.ignoring().antMatchers("/","/client/**","/systemjs.config.js","/index.html");
}
#Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication().withUser("test").password("test").authorities("ADMIN");
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.headers().disable()
.csrf().disable()
.authorizeRequests()
.antMatchers("/failure").permitAll()
.antMatchers("/api/**").permitAll()
.antMatchers("/users").hasAnyAuthority("ADMIN")
.anyRequest().authenticated()
.and()
.exceptionHandling()
.authenticationEntryPoint(restAuthenticationEntryPoint)
.accessDeniedHandler(restAccessDeniedHandler)
.and()
.formLogin()
.loginPage("/login")
.loginProcessingUrl("/authenticate")
.successHandler(restAuthenticationSuccessHandler)
.failureHandler(restAuthenticationFailureHandler)
.usernameParameter("username")
.passwordParameter("password")
.permitAll()
.and()
.logout()
.logoutUrl("/logout")
.logoutSuccessHandler(new HttpStatusReturningLogoutSuccessHandler())
.deleteCookies("JSESSIONID")
.permitAll()
.and();
}
}
login.service.ts
#Injectable()
export class LoginService {
constructor(private http: Http) {
console.log('Login service initialized...')
}
loginUser(data) {
var headers = new Headers();
headers.append('Content-type', 'application/json');
return this.http.post('/authenticate', JSON.stringify(data), { headers: headers })
.map(res => res.json());
}
login.component.ts
export class LoginComponent {
username:String;
password:String;
data:any
constructor(private LoginService: LoginService) {
}
loginUser(event) {
this.data = {
username: this.username,
password: this.password
};
this.LoginService.loginUser(this.data).subscribe(data => {
this.username = '';
this.password = '';
});
}
login.html
<form class="container col-md-8" (ngSubmit)="loginUser()" style="margin:15px 15px">
<div class="row">
<div class="form group col-md-2 parent ">
<button type="submit" class="btn btn-warning centerV_element">Log In</button>
</div>
<div class="form group col-md-3 parent" style="margin:3px 3px">
<input type="text" [(ngModel)]="username" name="username" class="form control" placeholder="username">
</div>
<div class="form group col-md-3 parent" style="margin:3px 3px">
<input type="text" [(ngModel)]="password" name="password" class="form control" placeholder="password">
</div>
</div>
</form>
I'm finding troubles using HDIV with the tag Spring element: "< form:form >".
First, I'm going to explain the architecture of my application:
I'm using Spring framework 4.1.6, Spring Security 4.0.0 and HDIV 2.1.10.
So far I'm not having errors during the development, nevertheless now I 've found one in a jsp file, when I'm using the form tag from Spring:
<form:form
action="${pageContext.servletContext.contextPath}/newUser"
method="POST" class="form-horizontal" commandName="user">
I obtained this error in the line 34: "< form:form "
java.lang.NullPointerException at
org.hdiv.web.servlet.support.HdivRequestDataValueProcessor.processAction(HdivRequestDataValueProcessor.java:122)
at
org.springframework.web.servlet.tags.form.FormTag.processAction(FormTag.java:479)
at
org.springframework.web.servlet.tags.form.FormTag.resolveAction(FormTag.java:433)
at
org.springframework.web.servlet.tags.form.FormTag.writeTagContent(FormTag.java:349)
at
org.springframework.web.servlet.tags.form.AbstractFormTag.doStartTagInternal(AbstractFormTag.java:84)
at
org.springframework.web.servlet.tags.RequestContextAwareTag.doStartTag(RequestContextAwareTag.java:80)
at
org.apache.jsp.WEB_002dINF.jsp.newUser_jsp._jspx_meth_form_005fform_005f0(newUser_jsp.java:197)
at
org.apache.jsp.WEB_002dINF.jsp.newUser_jsp._jspService(newUser_jsp.java:137)
at org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:70)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:729)
and more at.....(if it's necessary, I can provide it)
When I try the same code, but exchanging the tag "< form:form >" for the tag "< form >" It works.
When I examined in detail the code from HDIV:
HdivRequestDataValueProcessor.class
public class HdivRequestDataValueProcessor implements RequestDataValueProcessor
protected LinkUrlProcessor linkUrlProcessor;
protected FormUrlProcessor formUrlProcessor;
if (this.innerRequestDataValueProcessor != null) {
String processedAction = this.innerRequestDataValueProcessor.processAction(request, action, method);
if (processedAction != action) {
action = processedAction;
}
}
String result = this.formUrlProcessor.processUrl(request, action, method);//line 122
return result;
}
I wondered that maybe due to the fact that 'form:form' has a different structure than 'form', HDIV cannot find some parameters such as 'action', 'method'...But I'm not sure.
Also I attached my config files to provide more useful information (Java-based Config):
WebApplicationInit.class
import javax.servlet.Filter;
import javax.servlet.ServletContext;
import org.hdiv.filter.ValidatorFilter;
import org.hdiv.listener.InitListener;
import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;
public class WebApplicationInit extends
AbstractAnnotationConfigDispatcherServletInitializer {
// http://www.robinhowlett.com/blog/2013/02/13/spring-app-migration-from-xml-to-java-based-config/
#Override
protected Class<?>[] getRootConfigClasses() {
return new Class[] { RootConfig.class, DatabaseConfig.class,
SecurityConfig.class, HdivSecurityConfig.class };
// , HdivSecurityConfig.class
}
#Override
protected Class<?>[] getServletConfigClasses() {
return new Class[] { MvcConfig.class };
}
#Override
protected String[] getServletMappings() {
return new String[] { "/" };
}
//web.xml filter
#Override
protected Filter[] getServletFilters(){
return new Filter[] { new ValidatorFilter()};
}
// web.xml listener
#Override
protected void registerDispatcherServlet(ServletContext servletContext) {
super.registerDispatcherServlet(servletContext);
servletContext.addListener(InitListener.class);
}
}
HdivSecurityConfig.class
#Configuration
#EnableHdivWebSecurity
public class HdivSecurityConfig extends HdivWebSecurityConfigurerAdapter {
#Override
public void addExclusions(ExclusionRegistry registry) {
registry.addUrlExclusions("/login").method("GET");
registry.addUrlExclusions("/newUser").method("GET");
registry.addUrlExclusions("/newUser").method("POST");
registry.addUrlExclusions("/about").method("GET");
registry.addUrlExclusions("/resources/.*").method("GET");
registry.addUrlExclusions("/bst-lib/.*").method("GET");
registry.addUrlExclusions("/images/.*").method("GET");
}
#Override
public void configure(SecurityConfigBuilder builder) {
//the session has expired, go to login again
builder.sessionExpired().homePage("/").loginPage("/login");
//Execution strategy
builder.strategy(Strategy.CIPHER);
//error page
builder.errorPage("/error");
}
}
SecurityConfig.class
#EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
#Autowired
private DriverManagerDataSource myWebAppDataSource;
#Autowired
private MyWebAppSimpleAuthenticationProvider myWebAppAuthenticationProvider;
#Autowired
public void configureGlobal(AuthenticationManagerBuilder auth)
throws Exception {
auth.authenticationProvider(myWebAppAuthenticationProvider);
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/resources/**", "/bst-lib/**", "/images/**",
"/about", "/newUser").permitAll().anyRequest()
.authenticated().and().formLogin().loginPage("/login")
.permitAll();
}
}
SecurityWebApplicationInit.class
public class SecurityWebApplicationInit extends
AbstractSecurityWebApplicationInitializer {}
Thank you in advance!!
Best Regards,
Alberto
----EDIT---
Following the given example, This is now my code:
WebApplicationInit.class
import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;
public class WebApplicationInit extends
AbstractAnnotationConfigDispatcherServletInitializer {
// http://www.robinhowlett.com/blog/2013/02/13/spring-app-migration-from-xml-to-java-based-config/
#Override
protected Class<?>[] getRootConfigClasses() {
return new Class[] { RootConfig.class, DatabaseConfig.class,
SecurityConfig.class, HdivSecurityConfig.class };
}
#Override
protected Class<?>[] getServletConfigClasses() {
return new Class[] { MvcConfig.class };
}
#Override
protected String[] getServletMappings() {
return new String[] { "/" };
}
#Override
protected String getServletName(){
return "myDispatcher";
}
}
HDIVSecurityConfig.class
import org.hdiv.config.Strategy;
import org.hdiv.config.annotation.EnableHdivWebSecurity;
import org.hdiv.config.annotation.ExclusionRegistry;
import org.hdiv.config.annotation.RuleRegistry;
import org.hdiv.config.annotation.ValidationConfigurer;
import org.hdiv.config.annotation.builders.SecurityConfigBuilder;
import org.hdiv.config.annotation.configuration.HdivWebSecurityConfigurerAdapter;
import org.springframework.context.annotation.Configuration;
#Configuration
#EnableHdivWebSecurity
public class HdivSecurityConfig extends HdivWebSecurityConfigurerAdapter {
#Override
public void addExclusions(ExclusionRegistry registry) {
registry.addUrlExclusions("/login").method("GET");
registry.addUrlExclusions("/newUser").method("GET");
registry.addUrlExclusions("/newUser").method("POST");
registry.addUrlExclusions("/about").method("GET");
registry.addUrlExclusions("/resources/.*").method("GET");
registry.addUrlExclusions("/bst-lib/.*").method("GET");
registry.addUrlExclusions("/images/.*").method("GET");
registry.addParamExclusions("_csrf");
}
#Override
public void configure(SecurityConfigBuilder builder) {
// the session has expired, go to login again
builder.sessionExpired().homePage("/").loginPage("/login");
// Execution strategy
builder.strategy(Strategy.MEMORY);
builder.maxPagesPerSession(5);
// error page
builder.errorPage("/error");
}
#Override
public void addRules(RuleRegistry registry) {
//registry.addRule("safeText").acceptedPattern("^[a-zA-Z0-9#.\\-_]*$");
}
#Override
public void configureEditableValidation(
ValidationConfigurer validationConfigurer) {
validationConfigurer.addValidation("/.*");
}
}
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
id="WebApp_ID" version="3.1">
<display-name>myWebApp</display-name>
<listener>
<listener-class>org.hdiv.listener.InitListener</listener-class>
</listener>
<!-- HDIV Validator Filter -->
<filter>
<filter-name>ValidatorFilter</filter-name>
<filter-class>org.hdiv.filter.ValidatorFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>ValidatorFilter</filter-name>
<servlet-name>myDispatcher</servlet-name>
</filter-mapping>
<jsp-config>
<taglib>
<taglib-uri>http://java.sun.com/jsp/jstl/core</taglib-uri>
<taglib-location>/WEB-INF/tlds/hdiv-c.tld</taglib-location>
</taglib>
</jsp-config>
</web-app>
newUser.jsp
<form:form
action="${pageContext.servletContext.contextPath}/newUser"
method="POST" class="form-horizontal" commandName="user">
<div class="form-group">
<label for="inputName"
class="col-sm-offset-2 col-sm-2 control-label">Name:</label>
<div class="col-sm-6">
<form:input class="form-control" id="inputName"
placeholder="Name" path="name" />
</div>
</div>
<div class="form-group">
<label for="inputSurname"
class="col-sm-offset-2 col-sm-2 control-label">Surname:</label>
<div class="col-sm-6">
<form:input class="form-control" id="inputSurname"
placeholder="Surname" path="surname" />
</div>
</div>
<div class="form-group">
<label for="inputOrganisation"
class="col-sm-offset-2 col-sm-2 control-label">Organization:</label>
<div class="col-sm-6">
<form:input class="form-control" id="inputOrganisation"
placeholder="Organization" path="organization" />
</div>
</div>
<div class="form-group">
<label for="inputEmail"
class="col-sm-offset-2 col-sm-2 control-label">Email:</label>
<div class="col-sm-6">
<form:input type="email" class="form-control" id="inputEmail"
placeholder="Email" path="email" />
</div>
</div>
<div class="form-group">
<label for="inputPassword"
class="col-sm-offset-2 col-sm-2 control-label">Password:</label>
<div class="col-sm-6">
<form:password class="form-control" id="inputPassword"
placeholder="Password" path="password" />
</div>
</div>
<div class="form-group">
<label for="inputRPassword"
class="col-sm-offset-2 col-sm-2 control-label">Repeat
Password:</label>
<div class="col-sm-6">
<form:password class="form-control" id="inputRPassword"
placeholder="Repeat Password" path="rPassword" />
</div>
</div>
<div class="col-sm-offset-4 col-sm-8">
<button type="submit" class="btn btn-default login-button">Sing
in</button>
<button type="button" class="btn btn-default login-button"
onclick="clearAll()">Clear All</button>
<button type="button" class="btn btn-default login-button"
onclick="comeBack()">Come Back</button>
</div>
<input type="hidden" name="${_csrf.parameterName}"
value="${_csrf.token}" />
</form:form>
MvcConfig.class
#Configuration
#EnableWebMvc
#ComponentScan(basePackages = { "com.ec.myWebApp" })
public class MvcConfig extends WebMvcConfigurerAdapter {
#Autowired
/*
* If I use this commented line, The application fails due to the fact that the bean "hdivEditableValidator" can't be found...If I don't use the tag "Qualifier" it does not fail
*/
// #Qualifier("hdivEditableValidator")
private Validator hdivEditableValidator;
// View Name -> View
#Bean
public InternalResourceViewResolver getViewResolver() {
InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
viewResolver.setViewClass(JstlView.class);
viewResolver.setPrefix("/WEB-INF/jsp/");
viewResolver.setSuffix(".jsp");
return viewResolver;
}
// static resources
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/resources/**").addResourceLocations(
"/public-resources/");
registry.addResourceHandler("/bst-lib/**").addResourceLocations(
"/public-resources/lib/bootstrap-3.3.2-dist/");
registry.addResourceHandler("/images/**").addResourceLocations(
"/public-resources/images/");
}
#Bean
public MultipartResolver multipartResolver() {
HdivCommonsMultipartResolver resolver = new HdivCommonsMultipartResolver();
resolver.setMaxUploadSize(100000);
return resolver;
}
#Override
public Validator getValidator() {
return hdivEditableValidator;
}
}
I changed the way to add the HDIV to my Web Application, adding it in the xml file, instead of doing that in using java-based configuration. Additionally, I added the Qualifier tag (MvcConfig.class), using the example, but it does not work when I use it...(It can not find the bean...).
The null error hasn't disappeared...
The problem has been solved changing this line:
#ComponentScan(basePackages = { "com.ec.myWebApp" })
in the class: MvcConfing, for this:
#ComponentScan(basePackages = { "com.ec.myWebApp.controllers",
"com.ec.myWebApp.dao", "com.ec.myWebApp.services" })
My original line scanned twice the HDIV config class, first during the context creation and the second one by the "#ComponentScan". This gave place to an incorrect initialization. So, the config package was used twice, instead of once.
Thank you.