Spring beans property binding error - spring-mvc

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'workingTimeController' defined in ServletContext resource [/WEB-INF/tracker-servlet.xml]: Initialization of bean failed; nested exception is java.lang.IllegalArgumentException: Validator [de.intec.tracker.controller.WorkingTimeController#4610fa] does not support command class [de.intec.tracker.dto.WorkingTimeDTO]
The Working Controller is the controller classs in java

Your can define like below code snippet
LoginFormCommand
com.aims.commands.LoginFormCommand
and validator should using validator interface like below code snippet
public class LoginFormValidator implements Validator {
public boolean supports(Class arg0) {
// TODO Auto-generated method stub
return LoginFormCommand.class.equals(arg0);
}
public void validate(Object obj, Errors errors) {
// TODO Auto-generated method stub
LoginFormCommand login = (LoginFormCommand) obj;
System.out.println("validate==============");
ValidationUtils.rejectIfEmpty(errors,"username","field.required", "Required field");
ValidationUtils.rejectIfEmpty(errors,"password","field.required", "Required field");
}
}

Related

Throw custom exception in spring boot with an Autowired variable

A custom exception that requires the use of an Autowired variable
// #Component // should be a component to use autowire variable
#ResponseStatus(value = HttpStatus.UNAUTHORIZED)
public class MyException extends Exception {
// This should be commented in
// #Autowired
// public RequestModel reqModel;
// public MyException(ExceptionType type) {
public MyException(ExceptionType type, RequestModel reqModel) {
super();
switch type {
// ...
}
}
}
And then in the rest controllers and interceptors we throw the error
public class MyInterceptor extends HandlerInterceptorAdapter {
// These should be commented out
#Autowired
public RequestModel reqModel;
#Override
public boolean preHandle(HttpServletRequest request,
HttpServletResponse response, Object handler) throws Exception {
// This should be thrown without adding the reqModel as a param
// Unsure how to throw this without using "new"
throw new MyException.MyException(PARAM_MISSING, reqModel);
}
}
I understand that instantiating a class using new will null the Autowired variables. When I tried dropping the new and converting the MyException class to a #Component, I see issues with calling the MyException class constructor.
What is the best way to implement a custom exception in springboot using an autowired variable?

How to wire AuthenticationManager for Spring AbstractPreAuthenticatedProcessingFilter

I have a class derived from AbstractPreAuthenticatedProcessingFilter in my Spring Security Filter Chain. The purpose of this filter is to massage role data left in a special Principal object by a corporate authentication service into a Collection so SpringSecurity can use them.
However, I cannot get past this exception:
Caused by: java.lang.IllegalArgumentException: An AuthenticationManager must be set
at org.springframework.util.Assert.notNull(Assert.java:112) ~[spring-core-4.1.6.RELEASE.jar:4.1.6.RELEASE]
at org.springframework.security.web.authentication.preauth.AbstractPreAuthenticatedProcessingFilter.afterPropertiesSet(AbstractPreAuthenticatedProcessingFilter.java:97) ~[spring-security-web-4.0.1.RELEASE.jar:4.0.1.RELEASE]
I am using Java config, not XML config. My code following the example of How To Inject AuthenticationManager using Java Configuration in a Custom Filter is as follows:
the security configurer adaptor
#Configuration
#EnableWebSecurity
public class MyWebSecurityAdaptor extends WebSecurityConfigurerAdapter {
...
#Bean(name = "myAuthenticationManager")
#Override
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
}
The filter class itself:
#Component
public class MyPreauthFilter extends AbstractPreAuthenticatedProcessingFilter {
...
#Autowired
#Override
public void setAuthenticationManager(AuthenticationManager authenticationManager) {
super.setAuthenticationManager(authenticationManager);
}
}
If instead of the code in Item 1 above, I try the following:
#Autowired
#Override
protected AuthenticationManager authenticationManager() throws Exception
{
// TODO Auto-generated method stub
return super.authenticationManager();
}
Then the error changes.
It then becomes:
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [org.springframework.security.authentication.AuthenticationManager] found for dependency: expected at least 1 bean which qualifies as autowire candidate}
I guess that makes sense, this way does not define a bean. But then why didn't the original way, which DID define a bean, fail?
Instead of adding 'myAuthernticationManager' to the WebSecurityConfigurerAdapter class. Add this directly to you filter class and autowire it.
#Autowired
#Override
public void setMyAuthenticationManager(MyAuthenticationManager myAuthenticationManager) {
this.myAuthenticationManager = myAuthenticationManager;
super.setAuthenticationManager(this.myAuthenticationManager);
}
Remove all the code related to myAuthenticationManager from your WebSecurityConfigurerAdapter.

Configuration of Spring security with Spring boot and a Spring MVC Rest API on Jetty

I'm currently making a Rest API using spring boot and spring mvc hosted on Jetty. At this point everything works. Now I'd like to add spring security but it throws an exception :
FAILED org.springframework.boot.context.embedded.jetty.ServletContextInitializerConfiguration$InitializerListener#36895c35: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'springSecurityFilterChain' defined in class path resource [org/springframework/security/config/annotation/web/configuration/WebSecurityConfiguration.class]: Instantiation of bean failed; nested exception is org.springframework.beans.factory.BeanDefinitionStoreException: Factory method [public javax.servlet.Filter org.springframework.security.config.annotation.web.configuration.WebSecurityConfiguration.springSecurityFilterChain() throws java.lang.Exception] threw exception; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.security.config.annotation.authentication.configuration.AuthenticationConfiguration': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire method: public void org.springframework.security.config.annotation.authentication.configuration.AuthenticationConfiguration.setGlobalAuthenticationConfigurers(java.util.List) throws java.lang.Exception; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.boot.autoconfigure.security.AuthenticationManagerConfiguration': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private java.util.List org.springframework.boot.autoconfigure.security.AuthenticationManagerConfiguration.dependencies; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'securityProperties': Could not bind properties; nested exception is org.springframework.beans.NotWritablePropertyException: Invalid property 'bean' of bean class [org.springframework.boot.autoconfigure.security.SecurityProperties]: Bean property 'bean' is not writable or has an invalid setter method. Does the parameter type of the setter match the return type of the getter?
So here is my main class :
#Configuration
#ComponentScan
#EnableAutoConfiguration
#PropertySource({"classpath:configuration.properties"})
#Import({ApplicationConfig.class, SecurityConfig.class})
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
#Autowired
private Environment environment;
public Environment getEnvironment() {
return environment;
}
public void setEnvironment(Environment environment) {
this.environment = environment;
}
}
Here is my application configuration
#EnableWebMvc
#Configuration
#EnableTransactionManagement
public class ApplicationConfig {
#Autowired
private Environment environment;
public Environment getEnvironment() {
return environment;
}
public void setEnvironment(Environment environment) {
this.environment = environment;
}
#Bean(name = "dataSource")
public DriverManagerDataSource getDataSource() {
DriverManagerDataSource driverManagerDataSource = new DriverManagerDataSource();
driverManagerDataSource.setDriverClassName(this.getEnvironment().getProperty("database.driver"));
driverManagerDataSource.setUrl(this.getEnvironment().getProperty("database.url"));
driverManagerDataSource.setUsername(this.getEnvironment().getProperty("database.username"));
driverManagerDataSource.setPassword(this.getEnvironment().getProperty("database.password"));
return driverManagerDataSource;
}
#Bean(name = "sessionFactory")
public SessionFactory getSessionFactory() {
LocalSessionFactoryBuilder builder = new LocalSessionFactoryBuilder(this.getDataSource());
builder.scanPackages("apt.model").addProperties(this.getHibernateProperties());
return builder.buildSessionFactory();
}
private Properties getHibernateProperties() {
Properties prop = new Properties();
prop.put("hibernate.format_sql", this.getEnvironment().getProperty("database.verbose"));
prop.put("hibernate.show_sql", this.getEnvironment().getProperty("database.verbose"));
prop.put("hibernate.dialect", this.getEnvironment().getProperty("database.dialect"));
prop.put("hbm2ddl.auto", this.getEnvironment().getProperty("database.hbm2ddl"));
prop.put("c3p0.min_size", "5");
prop.put("c3p0.max_size", "50");
prop.put("c3p0.timeout", "300");
prop.put("c3p0.max_statements", "50");
prop.put("c3p0.idle_test_period", "3000");
return prop;
}
#Bean(name = "txManager")
public HibernateTransactionManager getTransactionManager() {
return new HibernateTransactionManager(this.getSessionFactory());
}
}
and here is the security configuration
#Configuration
#EnableWebSecurity
#EnableAutoConfiguration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
#Autowired
private AccountService accountService;
#Autowired
private AuthenticationService authenticationService;
public AccountService getAccountService() {
return accountService;
}
public void setAccountService(AccountService accountService) {
this.accountService = accountService;
}
public AuthenticationService getAuthenticationService() {
return authenticationService;
}
public void setAuthenticationService(AuthenticationService authenticationService) {
this.authenticationService = authenticationService;
}
#Override
public void setAuthenticationConfiguration(AuthenticationConfiguration authenticationConfiguration) {
super.setAuthenticationConfiguration(authenticationConfiguration);
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests().antMatchers("/**").permitAll().anyRequest().authenticated();
http.formLogin().loginPage("/authentication/login").permitAll().and().logout().permitAll();
}
#Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(this.getAuthenticationService()).passwordEncoder(this.getPasswordEncoder());
}
#Bean(name = "passwordEncoder")
public PasswordEncoder getPasswordEncoder() {
return new BCryptPasswordEncoder();
}
}
Do you know where it comes from ?
It sounds as if you have a property defined named security.bean which is causing a binding error on Spring Boot's org.springframework.boot.autoconfigure.security.SecurityProperties.
This happens since SecurityProperties is annotated with #ConfigurationProperties(name = "security", ignoreUnknownFields = false) and does not contain a property named bean.
In short, you should not have any properties that start with security. that are not listed in the reference.

CustomBinder in Spring MVC for processing list of objects

I have spring mvc form from which i am submitting values of a cusomized object A. The customized object A has one of its field as a list of another object B.
In the controller, I can see the size of list of object B but it is throwing error message of
Failed to convert property value of type 'java.lang.String' to required type 'java.util.List'
Now I have created a class CustomBinder which is following
public class CustomBinder extends PropertyEditorSupport {
private List<b> listOfb;
public CustomBinder(List<b> listOfb){
this.listOfb = listOfb;
}
#Override
public void setAsText(String text) throws IllegalArgumentException {
// TODO Auto-generated method stub
setValue(listOfb);
}
#Override
public String getAsText() {
// TODO Auto-generated method stub
return super.getAsText();
}
}
and in the controller, I have registered the custombinder
#InitBinder
protected void initBinder(Object target, WebDataBinder binder)
{
binder.setValidator(this.productUniqueValidator);
A a = (A) target;
List<B> b= a.getLstOfB;
binder.registerCustomEditor(List.class,"bs" ,new CustomBinder(b));
}
I am still getting a error message...Not sure what i am doing wrong !!

Autowiring inside contextInitialized method of Context Listener

I am trying to autowiring my bean inside contextInitialized() method of my custom Context Listener class, but it is not working.
public class CustomContextListener extends ContextLoaderListener {
#Autowired
private MyBeanClass bean;
#Override
public void contextInitialized(javax.servlet.ServletContextEvent event) {
super.contextInitialized(event);
//call to my method.
bean.mymethod();
}
But here it is not getting autowired, i am getting null object for MyBeanClass reference.
How to autowire a class at the time of tomcat startup.
Please provide me alternate places where i can execute some code using autowiring at the time of server startup (here tomcat).
I would suggest to use the WebApplicationContext method to find the bean and then invoke.
WebApplicationContext servletContext = WebApplicationContextUtils.getWebApplicationContext(event.getServletContext());
bean = (MyBeanClass) servletContext.getBean("myBeanClass");
bean.yourMethod();
More systematic to use... :)

Resources