continue my projects I encountered a problem in the authorization for accounts in Spring setsurity
- Problems in the query to the database, all the settings are correct, the database is created at the start of the project, there is no error in debug but at login message pops up in the log:
(UserAuthentication.java:authenticate:56) tradeManager.DAO.Impl.CustomHibernateDaoSupport.find(CustomHibernateDaoSupport.java:60)
tradeManager.service.authentication.UserAuthentication.authenticate(UserAuthentication.java:45)
...
Authentication request failed: org.springframework.security.authentication.BadCredentialsException:
User does not exists!
I added few catches to get precise exception and got new NullPointerException
17:52:34.280:WARN::/tradeManager/j_spring_security_check
java.lang.NullPointerException
at tradeManager.DAO.Impl.CustomHibernateDaoSupport.find(CustomHibernateDaoSupport.java:60)
at tradeManager.service.authentication.UserAuthentication.authenticate(UserAuthentication.java:48)
Can someone explain me what i'm doing wrong? Please help me.
here's the code affected by the query:
#Service("userAuthentication")
public class UserAuthentication implements AuthenticationManager {
protected static Logger userAccessLogger = Logger.getLogger("userAccessLog");
private UserDAO userDAO = new UserDAOImpl();
private Md5PasswordEncoder passwordEncoder = new Md5PasswordEncoder();
public Authentication authenticate(Authentication auth)
throws UsernameNotFoundException {
User user = null;
/*
* Init a database user object
*/
try {
// Retrieve user details from database
//user = userDAO.find(auth.getName());
List<User> list = userDAO.findAllByParam("username", auth.getName());
user = (list.isEmpty()) ? null : list.get(0);
} catch (Exception e) {
StackTraceElement[] stack = e.getStackTrace();
String exception = "";
for (StackTraceElement s : stack) {
exception = exception + s.toString() + "\n\t\t";
}
userAccessLogger.error(exception);
throw new BadCredentialsException("\n\tUser " + auth.getName() + " does not exists!\n");
}
/*
* Compare passwords
* Make sure to encode the password first before comparing
*/
if (user != null) {
if (passwordEncoder.isPasswordValid(user.getPassword(), (String) auth.getCredentials(), null)) {
throw new BadCredentialsException("\n\tWrong password!\n");
}
}
/*
* main logic of authentication manager
* Username and password must be the same to authenticate
*/
if (auth.getName().equals(auth.getCredentials())) {
throw new BadCredentialsException("Entered username and password are the same!");
} else {
assert user != null;
return new UsernamePasswordAuthenticationToken(
auth.getName(),
auth.getCredentials(),
getAuthorities(user.getAccess()));
}
}
/*
* Retrieves the correct ROLE type depending on the access level
*/
public Collection<GrantedAuthority> getAuthorities(Integer access) {
// Create a list of grants for this user
List<GrantedAuthority> authList = new ArrayList<GrantedAuthority>(2);
userAccessLogger.debug("Grant ROLE_USER to this user");
authList.add(new SimpleGrantedAuthority("ROLE_USER"));
if (access.compareTo(1) == 0) {
authList.add(new SimpleGrantedAuthority("ROLE_ADMIN"));
userAccessLogger.debug("Grant ROLE_ADMIN to this user");
}
// Return list of granted authorities
return authList;
}
here is CustomHibernateDaoSupport:
public class CustomHibernateDaoSupport<T> implements DAO<T> {
protected static Logger daoSupportLogger = Logger.getLogger("daoSupportLog");
private Class<T> clazz;
private SessionFactory sessionFactory;
public CustomHibernateDaoSupport(Class<T> clazz) {
this.clazz = clazz;
}
#Autowired
public void setSessionFactory(SessionFactory sessionFactory) {
this.sessionFactory = sessionFactory;
}
private SessionFactory getSessionFactory() {
return sessionFactory;
}
#Override
#Transactional
public void save(T entity) {
getSessionFactory().getCurrentSession().save(entity);
}
#Override
#Transactional
public void update(T entity) {
getSessionFactory().getCurrentSession().update(entity);
}
#Override
#Transactional
public void delete(Serializable key) {
Object entity = getSessionFactory().getCurrentSession().get(clazz, key);
if (entity != null) {
getSessionFactory().getCurrentSession().delete(entity);
}
}
#Override
#Transactional
public T find(Serializable key) {
return (T) getSessionFactory().getCurrentSession().get(clazz, key);
}
#Override
#Transactional
public List<T> findAll() {
return getSessionFactory().getCurrentSession().createCriteria(clazz).list();
}
#Override
#Transactional
public List<T> findAllByParam(final String paramName, final Object paramValue) {
return getSessionFactory().getCurrentSession().createCriteria(clazz)
.add(Restrictions.eq(paramName, paramValue))
.list();
}
}
the security settings are like this:
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:security="http://www.springframework.org/schema/security"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security-3.1.xsd">
<!-- excluded from Security
<security:http pattern="/resources/*" security="none" />-->
<!-- Configuration of Spring-Security. Set to false to assign custom filters -->
<security:http auto-config="false" use-expressions="true" access-denied-page="/crimea/auth/denied"
entry-point-ref="authenticationEntryPoint" >
<security:logout invalidate-session="true"
logout-success-url="/crimea/auth/login"
delete-cookies="SPRING_SECURITY_REMEMBER_ME_COOKIE"
logout-url="/crimea/auth/logout"/>
<security:intercept-url pattern="/crimea/auth/login" access="permitAll"/>
<security:intercept-url pattern="/crimea/main/admin" access="hasRole('ROLE_ADMIN')"/>
<security:intercept-url pattern="/crimea/main/common" access="hasRole('ROLE_ADMIN','ROLE_USER')"/>
<security:custom-filter ref="authenticationFilter" position="FORM_LOGIN_FILTER"/>
</security:http>
<!-- Custom filter for username and password -->
<bean id="authenticationFilter"
class="org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter"
p:authenticationManager-ref="userAuthentication"
p:authenticationFailureHandler-ref="customAuthenticationFailureHandler"
p:authenticationSuccessHandler-ref="customAuthenticationSuccessHandler"
p:postOnly="false" />
<!-- Custom authentication manager. !!! Username and password must not be the same !!! -->
<bean id="userAuthentication" class="tradeManager.service.authentication.UserAuthentication" />
<!-- default failure URL -->
<bean id="customAuthenticationFailureHandler"
class="org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler"
p:defaultFailureUrl="/crimea/auth/login?error=true" />
<!-- default target URL -->
<bean id="customAuthenticationSuccessHandler"
class="org.springframework.security.web.authentication.SimpleUrlAuthenticationSuccessHandler"
p:defaultTargetUrl="/crimea/main/common" />
<!-- The AuthenticationEntryPoint -->
<bean id="authenticationEntryPoint"
class="org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint"
p:loginFormUrl="/crimea/auth/login" />
<!-- Spring Security autowire the parent property -->
<security:authentication-manager/>
</beans>
I'm not showing User model becouse it standart. Acess is managed by Integer var:
/**
* Access level.
* 1 = Admin role
* 2 = Regular role
*/
#Column(name = "Access", nullable = false)
private Integer access;
Ок, didn't get any helpful answer, so tried my best. First of all, this line got my attention:
<security:intercept-url pattern="/crimea/main/common" access="hasRole('ROLE_ADMIN','ROLE_USER')"
I changed it to:
<security:intercept-url pattern="/crimea/main/common" access="hasRole('ROLE_USER')"
OK, I did more and changed query to username and I writed direct access, from:
list = userDAO.findAllByParam("from username",auth.getName());
to:
list = getSessionFactory().getCurrentSession().createCriteria(User.class)
.add(Restrictions.eq("username", auth.getName())).list();
and added the authentication session attributes to the class and start working He = ((
So, can anyone explain to me why my CustomHibernateDaoSupport class does not work??
OK. I solved my problem ))
First of all? I changed location of #Repository("employeeDAOImpl")annotation.
I changed SQL driver to com.jolbox.bonecp.BoneCPDataSource
naw my datasourse config loks likr this:
<!-- for database, imports the properties from database.properties -->
<bean id="dataSource" class="com.jolbox.bonecp.BoneCPDataSource" destroy-method="close">
<property name="driverClass" value="${jdbc.driverClassName}"/>
<property name="jdbcUrl" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
<property name="idleConnectionTestPeriod" value="60"/>
<property name="idleMaxAge" value="240"/>
<property name="maxConnectionsPerPartition" value="30"/>
<property name="minConnectionsPerPartition" value="10"/>
<property name="partitionCount" value="3"/>
<property name="acquireIncrement" value="5"/>
<property name="statementsCacheSize" value="100"/>
<property name="releaseHelperThreads" value="3"/>
</bean>
changed Spring shema to:
<tx:annotation-driven transaction-manager="transactionManager"/>
<mvc:annotation-driven />
in UserAuthentication class I added chek for NullPointer
if (entity == null) {
throw new BadCredentialsException("User does not exists!");
}
added to pom.xml maven dep. for new sql driver:
<dependency>
<groupId>com.jolbox</groupId>
<artifactId>bonecp</artifactId>
<version>0.8.0-rc1</version>
</dependency>
So My Authentication is working perfect naw =))
I solved my problem
First, I changed the location of #Repository("employeeDAOImpl")annotation.
I changed SQL driver to com.jolbox.bonecp.BoneCPDataSource
now my datasourse config looks like this:
<bean id="dataSource" class="com.jolbox.bonecp.BoneCPDataSource" destroy-method="close">
<property name="driverClass" value="${jdbc.driverClassName}"/>
<property name="jdbcUrl" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
<property name="idleConnectionTestPeriod" value="60"/>
<property name="idleMaxAge" value="240"/>
<property name="maxConnectionsPerPartition" value="30"/>
<property name="minConnectionsPerPartition" value="10"/>
<property name="partitionCount" value="3"/>
<property name="acquireIncrement" value="5"/>
<property name="statementsCacheSize" value="100"/>
<property name="releaseHelperThreads" value="3"/>
</bean>
changed Spring schema to:
<tx:annotation-driven transaction-manager="transactionManager"/>
<mvc:annotation-driven />
in UserAuthentication class I added check for a null
if (entity == null) {
throw new BadCredentialsException("User does not exists!");
}
added to pom.xml maven dep. for new sql driver:
com.jolbox
bonecp
0.8.0-rc1
So my authentication is working perfect now =))
Related
I can only get an active programmatic transaction in my spring (3.0.5) jdbc application, running on Oracle 11.2,
when the txAdvice points to the actual method (mainTest()) called from the application context (example "AAA" below).
If the txAdvice points to a child method (transactionTest()) of mainTest() (example "BBB" below) then I no longer have an active transaction.
Relevant code:
public class MainDS {
public static Controller cont;
public static void main(String[] args) {
String [] configList ={"spring.xml"};
ApplicationContext ctx = new ClassPathXmlApplicationContext(configList);
cont = (Controller)ctx.getBean("controller");
cont.mainTest();
}
}
public class Controller {
private JdbcTemplate jdbcTemplate;
public void mainTest()
{
transactionTest();
// MainDS.cont.transactionTest(); // also does not work
}
public void transactionTest(){
try {
// This prints "Transaction active = true" for AAA but "Transaction active = false" for BBB
System.out.println("Transaction active = " + TransactionSynchronizationManager.isActualTransactionActive() );
} catch (SQLException e) {
e.printStackTrace();
}
}
public JdbcTemplate getJdbcTemplate() {
return jdbcTemplate;
}
public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
this.jdbcTemplate = jdbcTemplate;
}
}
and my spring.xml file is:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-2.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-2.0.xsd">
<bean id="controller" class="Controller">
<property name="jdbcTemplate" ref="jdbcTemplate" />
</bean>
<bean id="txManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource" />
</bean>
<tx:advice id="txAdvice" transaction-manager="txManager">
<tx:attributes>
<tx:method name="main*" propagation="REQUIRED" /> <!-- AAA -->
<tx:method name="transaction*" propagation="REQUIRED" /> <!-- or BBB -->
</tx:attributes>
</tx:advice>
<aop:config>
<aop:pointcut id="myMethods" expression="execution(* *..Controller.*(..))" />
<aop:advisor advice-ref="txAdvice" pointcut-ref="myMethods" />
</aop:config>
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="dataSource" />
</bean>
<bean id="dataConfigPropertyConfigurer"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="searchSystemEnvironment" value="true" />
</bean>
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="oracle.jdbc.driver.OracleDriver" />
<property name="initialSize" value="2" />
<property name="maxActive" value="2" />
<property name="url" value="my connection details" />
<property name="username" value="xxx" />
<property name="password" value="xxx" />
</bean>
</beans>
How do I get an active transaction for option BBB.
Any ideas very welcome.
Regards
DS
"BBB" case: the "mainTest()" method calls directly the "transactionTest()" method, omitting the aspect.
If you want to invoke the dynamically created proxy of the "transactionTest()" method, I suppose, you could do it through self bean reference (injected). Also as far as I remember, the spring manual used to suggest to call such methods via interface references (again using injected interface references).
Note: this is a really bad design! Implementation example (per request):
<bean id="controller" class="test.Controller">
<property name="jdbcTemplate" ref="jdbcTemplate"/>
<property name="instance" ref="controller" />
</bean>
public class Controller {
private JdbcTemplate jdbcTemplate;
private Controller instance;
public void mainTest() {
instance.transactionTest();
}
public void transactionTest() {
System.out.println("Transaction active = " + TransactionSynchronizationManager.isActualTransactionActive() );
}
public JdbcTemplate getJdbcTemplate() {
return jdbcTemplate;
}
public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
this.jdbcTemplate = jdbcTemplate;
}
public Controller getInstance() {
return instance;
}
public void setInstance(Controller instance) {
this.instance = instance;
}
}
Transaction active = true
This behaviour is well documented in the spring manual (I recall it in the Aspects section), so you should definitely read it: http://docs.spring.io/spring-framework/docs/current/spring-framework-reference/html/aop.html section 9.6.1
More over, this question has already been covered here: One Service method invoke inner multiple method for Spring transaction
I'm a newbie in Spring and Hibernate and I'm having a NPE in this line:
Session session = getSessionFactory().getCurrentSession();
This is my UserDAO class
public class UserDAO implements IUserDAO{
private SessionFactory sessionFactory;
public SessionFactory getSessionFactory() {
return sessionFactory;
}
public void setSessionFactory(SessionFactory sessionFactory) {
this.sessionFactory = sessionFactory;
}
#Override
public Integer updateUser(User user) {
// TODO Auto-generated method stub
return null;
}
#Override
public User searchUserIfExists(String username, String password) {
Session session = getSessionFactory().getCurrentSession();
Query query = session.createQuery(SEARCH_USER_ACCT);
query.setParameter("username", username);
query.setParameter("password",password);
List<User> userList = query.list();
System.out.println(userList.size());
User user = null;
return user;
}
And this is my UserController
#SessionAttributes(value = {"userSession"})
#Controller
public class UserController {
private IUserDAO userDAO;
#Autowired
public UserController(IUserDAO userDAO) {
this.userDAO = userDAO;
}
#RequestMapping(value = "/processLogin.htm", method=RequestMethod.POST)
public String login(#ModelAttribute User user,#RequestParam("username") String username,
#RequestParam("password") String password,
HttpServletRequest request, HttpServletResponse response){
userDAO = new UserDAO();
User userOb = userDAO.searchUserIfExists(username, password);
if(userOb != null){
ModelAndView modelAndView = new ModelAndView();
String role = userOb.getUserRole();
switch(role){
case "admin":
modelAndView.addObject("userSession", userOb);
modelAndView.addObject("userId", userOb.getUserId());
modelAndView.setViewName("/adminPage_admin");
break;
case "customer":
modelAndView.addObject("userSession", userOb);
modelAndView.addObject("userId", userOb.getUserId());
modelAndView.setViewName("/customerpage_customer");
break;
}
}
return "";
}
}
This is my xml configuration for spring
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.2.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd">
<!-- Enable #Controller annotation support -->
<mvc:annotation-driven />
<mvc:default-servlet-handler/>
<!-- Map simple view name such as "test" into /WEB-INF/test.jsp -->
<beans:bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<beans:property name="prefix" value="/jsp" />
<beans:property name="suffix" value=".jsp" />
</beans:bean>
<!-- Scan classpath for annotations (eg: #Service, #Repository etc) -->
<context:component-scan base-package="com.nacv2.*"/>
<context:spring-configured/>
<!-- JDBC Data Source. It is assumed you have MySQL running on localhost port 3306 with
username root and blank password. Change below if it's not the case -->
<bean id="myDataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/db_nac"/>
<property name="username" value="root"/>
<property name="password" value=""/>
<property name="validationQuery" value="SELECT 1"/>
</bean>
<!-- Hibernate Session Factory -->
<bean id="mySessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource" ref="myDataSource"/>
<property name="packagesToScan">
<array>
<value>com.nacv2.model.*</value>
</array>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">${hibernate.dialect}</prop>
<prop key="hibernate.show_sql">${hibernate.show_sql}</prop>
<prop key="hibernate.connection.pool_size">${hibernate.connection.pool_size}</prop>
</props>
</property>
</bean>
<bean id="userDAO" class="com.nacv2.dataaccess.UserDAO">
<property name="sessionFactory" ref="mySessionFactory"/>
</bean>
<!-- Hibernate Transaction Manager -->
<bean id="transactionManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<property name="sessionFactory" ref="mySessionFactory"/>
</bean>
<!-- Activates annotation based transaction management -->
<tx:annotation-driven transaction-manager="transactionManager"/>
</beans>
Your problem is actually on this line:
userDAO = new UserDAO();
You have correctly wired Spring and Hibernate, but then you go and create a new object outside their knowledge, which won't know about the injected dependencies. Just use the one that's already been autowired for you.
All - In the Spring 3.0, in the applicationContext.xml .... are we supposed to have the bean property name and the reference value to be the same ? If I give a different value, it returns null object. But on giving the same value, it works. For my project, i am supposed to give different values for them. Kindly help. bye, HS
This works: (same values)
<bean id="MNCWIRAdminBaseAction" class="com.megasoft.wiradmin.web.action.WIRAdminBaseAction">
<property name="cacheDelegate">
<ref bean="cacheDelegate" />
</property>
</bean>
This doesn't work: (different values)
<bean id="MNCWIRAdminBaseAction" class="com.megasoft.wiradmin.web.action.WIRAdminBaseAction">
<property name="cacheDelegate">
<ref bean="MNCCacheDelegate" />
</property>
</bean>
bye, HS
My Full Code here:
WIRAdminBaseAction.java ---> my base action
AuthenticateAction.java ---> my java file that calls the bean here
applicationContext.xml --> system's applicationcontext file
applicationContext_MNC.xml ---> my applicationContext for a specific company ... this is getting loaded by my java file, which gets invoked by the web.xml file.
CacheDelegate.java
StatusDBDAO.java
PreXMLWebApplicationContext.java ----> loads my applicationContext file for the specific company.
****** applicationContext.xml ******
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd ">
<bean name="exceptionHandler" class="com.megasoft.wir.eStatement.web.interceptor.WIRExceptionHandlerInterceptor"/>
<bean name="security" class="com.megasoft.wir.eStatement.web.interceptor.SecurityInterceptor"/>
<bean name="permission" class="com.megasoft.wir.eStatement.web.interceptor.PermissionInterceptor"/>
<!-- AutoProxies -->
<bean name="loggingAutoProxy" class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">
<property name="interceptorNames">
<list>
<value>base</value>
<value>exceptionHandler</value>
<value>security</value>
<value>permission</value>
</list>
</property>
</bean>
</beans>
****** applicationContext_MNC.xml ******
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"
"http://www.springframework.org/dtd/spring-beans.dtd">
<beans>
<bean id="MNCWIRAdminBaseAction" class="com.megasoft.wiradmin.web.action.WIRAdminBaseAction">
<property name="cacheDelegate">
<ref bean="MNCCacheDelegate" />
</property>
</bean>
<bean id="MNCCacheDelegate" class="com.megasoft.wiradmin.delegate.CacheDelegate" >
<property name="statusDBDAO"><ref bean="MNCStatusDBDAO" /></property>
</bean>
<bean id="MNCStatusDBDAO" class="com.megasoft.wiradmin.dao.StatusDBDAO">
<property name="dataSource">
<ref bean="MNCAdminDataSource" />
</property>
</bean>
<!-- database configuration from property file -->
<bean id="MNCAdminDataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"
destroy-method="close" lazy-init="default" autowire="default" dependency-check="default">
<property name="driverClass" value="${jdbc.driver}" ></property>
<property name="jdbcUrl" value="${admin.jdbc.url}" ></property>
<property name="user" value="${admin.jdbc.user}" ></property>
<property name="password" value="${admin.jdbc.password}" ></property>
<property name="initialPoolSize" value="3" ></property>
<property name="minPoolSize" value="3" ></property>
<property name="maxPoolSize" value="25" ></property>
<property name="acquireIncrement" value="1" ></property>
<property name="acquireRetryDelay" value="1000" ></property>
<property name="debugUnreturnedConnectionStackTraces" value="true" ></property>
<property name="maxIdleTime" value="300" ></property>
<property name="unreturnedConnectionTimeout" value="300000" ></property>
<property name="preferredTestQuery" value="SELECT COUNT(*) FROM LOCALE_CODE" ></property>
<property name="checkoutTimeout" value="300000" ></property>
<property name="idleConnectionTestPeriod" value="600000" ></property>
</bean>
<!-- this bean is set to map the constants which needs to be configured as per
the environment to the java constants file -->
<bean id="envConstantsConfigbean" class="com.megasoft.wiradmin.util.constants.Environm entConstantsSetter">
<property name="loginUrl" value="${login.url}"/>
<property name="logoutIR" value="${logout.from.image.retrieval}"/>
<property name="adminModuleUrl" value="${admin.url}"/>
<property name="adminUrlSym" value="${admin.url.sym}"/>
<property name="envProperty" value="${env.property}"/>
</bean>
</beans>
****** AuthenticateAction.java ******
package com.megasoft.wiradmin.web.action;
import java.net.UnknownHostException;
import java.sql.SQLException;
import org.bouncycastle.crypto.CryptoException;
import org.springframework.context.ApplicationContext;
import org.springframework.dao.DataAccessException;
import org.springframework.web.context.support.WebApplica tionContextUtils;
import com.megasoft.wiradmin.delegate.ICacheDelegate;
public class AuthenticateAction extends WIRAdminBaseAction {
private static final long serialVersionUID = 1L;
public String authenticate() throws UnknownHostException, CryptoException,
DataAccessException, SQLException{
/** This way of calling works...... This is not encouraged, as we should not use applicationContext always **/
ApplicationContext applicationContext = WebApplicationContextUtils.getWebApplicationContex t(getServletRequest().getSession().getServletConte xt());
ICacheDelegate cacheAction = (ICacheDelegate) applicationContext.getBean("MNCCacheDelegate");
/** The below way of calling does NOT work .... returns null value.... Please help...
* I assume that, since I have extended the WIRAdminBaseAction, i should be able to call the getCacheDelegate directly
* and it should return my cacheDelegate object ...
* Again, Please note.....if I change my applicationContext_MNC.xml as below, the below way of calling works fine...
* but, i don't want to change my applicationContext_MNC.xml as below, due to some necessity.
*
<bean id="MNCWIRAdminBaseAction" class="com.megasoft.wiradmin.web.action.WIRAdminBaseAction">
<property name="cacheDelegate">
<ref bean="cacheDelegate" />
</property>
</bean>
*
<bean id="cacheDelegate" class="com.megasoft.wiradmin.delegate.CacheDelegate" >
<property name="statusDBDAO"><ref bean="MNCStatusDBDAO" /></property>
</bean>
*
... is it that the name and bean should have the same value.... ??? No Need to be.....Am i right ? Please advise.
*
* **/
getCacheDelegate().getActorAction(1); // this way of calling doesn't work and returns null value. please help.
return "success";
}
}
****** WIRAdminBaseAction.java ******
package com.megasoft.wiradmin.web.action;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.struts2.interceptor.ParameterAware;
import org.apache.struts2.interceptor.SessionAware;
import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.Preparable;
import com.opensymphony.xwork2.config.entities.Parameteri zable;
import com.megasoft.wiradmin.delegate.ICacheDelegate;
public class WIRAdminBaseAction extends ActionSupport implements Preparable, ParameterAware, Parameterizable, SessionAware,RequestAware {
private HttpServletRequest request;
private static final long serialVersionUID = 1L;
private HttpServletResponse response;
private ICacheDelegate cacheDelegate;
private Map session;
private Map<String, String> params;
private Map parameters;
public void prepare() throws Exception {
}
public String execute() throws Exception {
return SUCCESS;
}
public void setServletRequest(HttpServletRequest request) {
this.request = request;
}
public HttpServletRequest getServletRequest() {
return this.request;
}
public void setServletResponse(HttpServletResponse response) {
this.response = response;
}
public HttpServletResponse getServletResponse() {
return this.response;
}
public ICacheDelegate getCacheDelegate() {
return cacheDelegate;
}
public void setCacheDelegate(ICacheDelegate cacheDelegate) {
this.cacheDelegate = cacheDelegate;
}
public void addParam(final String key, final String value) {
this.params.put(key, value);
}
public Map getParams() {
return params;
}
public void setParams(final Map<String, String> params) {
this.params = params;
}
public Map getSession() {
return this.session;
}
public void setSession(final Map session) {
this.session = session;
}
public void setParameters(final Map param) {
this.parameters = param;
}
}
PreXMLWebApplicationContext.java **
package com.megasoft.wiradmin.util;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.web.context.support.XmlWebApplicationContext;
public class PreXMLWebApplicationContext extends XmlWebApplicationContext {
/**
* This initializes the Logger.
*/
private static Log logger = LogFactory.getLog(PreXMLWebApplicationContext.class);
protected String[] getDefaultConfigLocations() {
String environment = System.getProperty("envProperty");
String webirConfig = System.getProperty("webirConfig");
String fi = System.getProperty("FI");
String preHostConfiguration =null;
logger.info("The environment is "+environment);
logger.info("The webirConfig is "+webirConfig);
logger.info("The fi is "+fi);
if(environment != null && webirConfig != null && fi != null) {
preHostConfiguration = DEFAULT_CONFIG_LOCATION_PREFIX +
"classes/applicationContext" + "_" + fi.toUpperCase() +
DEFAULT_CONFIG_LOCATION_SUFFIX;
}
return new String[]{DEFAULT_CONFIG_LOCATION, preHostConfiguration};
}
/**
* This is close API.
*
* #see org.springframework.context.support.AbstractApplicationContext
* #close()
*/
public void close() {
this.doClose();
logger.info("Login-->into the closed");
}
}
<property name="userDelegate" ref="userDelegate" />
name is the field name in your class. When name is userDelegate, it means that WIRAdminBaseAction has a field named userDelegate (and probably a setter setUserDelegate())
ref is the bean name you want to set this field to. In your example, you should have another bean, named userDelegate or bmoUserDelegate which should be set as userDelegate in WIRAdminBaseAction.
So if you want to use the second configuration:
You just need to create a bean with id bmoUserDelegate:
<bean id="bmoUserDelegate" class="mypackage.BmoUserDelegateClass"/>
Hi im new to this Spring , MVC and JdBC support.
I want to be able to connect to a mysql database..but when i run my web it returns null. Below codes i believe should be easy,What am i missing here ? Thanks for all replies
Below is my error when try to query the URL
java.lang.NullPointerException
com.simple.myacc.dao.JdbcContactDao.findAll(JdbcContactDao.java:55)
com.simple.myacc.ContactController.getAll(ContactController.java:44)
My spring.xml
.....
<context:component-scan base-package="com.simple.myacc" />
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix">
<value>/WEB-INF/jsp/</value>
</property>
<property name="suffix">
<value>.jsp</value>
</property>
</bean>
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql://localhost:3306/webcontact" />
<property name="username" value="root" />
<property name="password" value="password" />
</bean>
<bean id="jdbcContactDao" class="com.simple.myacc.dao.JdbcContactDao">
<property name="dataSource" ref="dataSource" />
</bean>
My JdbcContactDao
public class JdbcContactDao {
protected static Logger logger = Logger.getLogger("service");
private DataSource dataSource;
private JdbcTemplate jdbcTemplate;
public JdbcContactDao() {
}
public List<Contact> findAll() {
String sql = "select * from contact";
List<Contact> contacts = new ArrayList<Contact>();
List<Map<String, Object>> rows = jdbcTemplate.queryForList(sql);
for (Map rs : rows) {
Contact contact = new Contact();
contact.setId((Integer) rs.get("id"));
contact.setFirstname((String) rs.get("firstname"));
contact.setLastname((String) rs.get("lastname"));
contact.setEmail((String) rs.get("email"));
contact.setPhone((String) rs.get("phone"));
contacts.add(contact);
}
return contacts;
}
#Resource(name = "dataSource")
public void setDataSource(DataSource dataSource) {
this.dataSource = dataSource;
} }
My controller , some part of it
#RequestMapping(value="/contact/list2",method = RequestMethod.GET)
public String getAll(ModelMap model) {
dao=new JdbcContactDao();
List<Contact> contacts = dao.findAll();
// Attach persons to the Model
model.addAttribute("contacts", contacts);
return "contact.list";
}
This is the line that says the NULL
List<Map<String, Object>> rows = jdbcTemplate.queryForList(sql);
A common idiom when using the JdbcTemplate class is to configure a DataSource in your Spring configuration file, and then dependency inject that shared DataSource bean into your DAO classes; the JdbcTemplate is created in the setter for the DataSource.
private JdbcTemplate jdbcTemplate;
public void setDataSource(DataSource dataSource) {
this.jdbcTemplate = new JdbcTemplate(dataSource);
}
You can read more on this here
Your code will look like this
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql://localhost:3306/webcontact" />
<property name="username" value="root" />
<property name="password" value="password" />
You don't need this
<bean id="jdbcContactDao" class="com.simple.myacc.dao.JdbcContactDao">
<property name="dataSource" ref="dataSource" />
Instead do this
#Autowired
public void setDataSource(DataSource dataSource) {
this.jdbcTemplate = new JdbcTemplate(dataSource);
}
and annotate your JdbcContactDao class with #Repository
I think that should work
You have your dataSource and your JdbcContactDAO bean configured in the config file.
So in the same way you need to inject the jdbcContactDAO bean into your Controller.
<bean id="myController" class="mypath.MyController">
<property name="dao" ref="jdbcContactDao"/>
</bean>
And in your controller....
public JdbcContactDao dao;
#Resource(name="dao")
public void setDao(JdbcContactDao dao){
this.dao = dao;
}
#RequestMapping(value="/contact/list2",method = RequestMethod.GET)
public String getAll(ModelMap model) {
List<Contact> contacts = dao.findAll();
// Attach persons to the Model
model.addAttribute("contacts", contacts);
return "contact.list";
}
I'm guessing line 55 of JdbcContactDao is this one List<Map<String, Object>> rows = jdbcTemplate.queryForList(sql); You declare jdbcTemplate, but never give it a value and it's also not annotated for injection, so it's always going to be null. So, when you attempt to use it, you will get the NPE.
Had a similar problem was connecting to old tables using java/jdbc
String sql = "select user_name from table"
jdbc.queryForList(sql);
queryReturnList = jdbc.queryForList(sql);
for (Map mp : queryReturnList){
String userName = (String)mp.get("user_name");
}
userName was always null. looking through the map of returned values found that the map was not using user_name but a label set up on the table of "User Name" Had to have DBA's fix. Hope this helps
I would just like to ask how can i setup a simple mail server and be able to send an email. Im using apache tomcat 6.0 as my localhost server and spring framework+jsp as well. I'm quite new on this. So if someone can give a nice tutorial, it will be of great help. thanks
Below is how you would get the spring configuration. probably applicationContext-mail.xml. Import that into applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"autowire="byName">
default-autowire="byName">
<bean id="mailSender" class="org.springframework.mail.javamail.JavaMailSenderImpl">
<property name="host" value="${mail.host}" />
<property name="port" value="${mail.port}" />
<property name="username" value="${mail.username}" />
<property name="password" value="${mail.password}" />
</bean>
<bean id="freemarkerConfiguration"
class="org.springframework.ui.freemarker.FreeMarkerConfigurationFactoryBean">
<property name="templateLoaderPath" value="/WEB-INF/templates" />
</bean>
<!-- KINDLY MAINTAIN ALPHABETICAL ORDER THIS LINE ONWARDS -->
<bean id="notificationService" class="com.isavera.service.NotificationServiceImpl"
scope="prototype">
<property name="mailSender" ref="mailSender" />
<property name="freemarkerConfiguration" ref="freemarkerConfiguration" />
<property name="freemarkerTemplate" value="accountInformation.ftl" />
<property name="fromAddress" value="info#apnagenie.com" />
<property name="subject" value="Your account information" />
</bean>
Below is the NotificationServiceImpl
public class NotificationServiceImpl implements NotificationService, Runnable {
private boolean asynchronous = true;
private JavaMailSender mailSender;
private Configuration freemarkerConfiguration;
private String freemarkerTemplate;
private Map<String, Object> attributes;
private String deliveryAddress;
private String[] deliveryAddresses;
private String fromAddress;
private String subject;
private SimpleMailMessage message;
private MimeMessage mimeMessage;
public void deliver() {
message = new SimpleMailMessage();
if (getDeliveryAddresses() == null) {
message.setTo(getDeliveryAddress());
} else {
message.setTo(getDeliveryAddresses());
}
message.setSubject(subject);
message.setFrom(fromAddress);
// Merge the model into the template
final String result;
try {
result = FreeMarkerTemplateUtils.processTemplateIntoString(freemarkerConfiguration.getTemplate(appendApplicationName(freemarkerTemplate)), attributes);
message.setText(result);
if (asynchronous) {
Thread emailThread = new Thread(this);
emailThread.start();
} else {
run();
}
} catch (IOException e) {
e.printStackTrace();
} catch (TemplateException e) {
e.printStackTrace();
}
}
}