From 4afcff940551079617e8f4116e52bb0ef9df7fcc Mon Sep 17 00:00:00 2001 From: Kamal Wickramanayake Date: Sat, 25 Apr 2026 21:53:33 +0530 Subject: Added Spring Framework sample code --- .../main/java/com/example/spring/bank/Account.java | 21 ++++ .../com/example/spring/bank/AccountManager.java | 21 ++++ .../example/spring/bank/AccountManagerImpl.java | 73 ++++++++++++++ .../com/example/spring/bank/dao/AccountDAO.java | 15 +++ .../spring/bank/dao/jdbc/JDBCAccountDAO.java | 94 ++++++++++++++++++ .../example/spring/bank/tx/TxAccountManager.java | 109 +++++++++++++++++++++ .../com/example/spring/bank/web/BankGateway.java | 59 +++++++++++ .../webapp/WEB-INF/spring/applicationContext.xml | 39 ++++++++ .../src/main/webapp/WEB-INF/spring/jdbc.properties | 7 ++ .../src/main/webapp/WEB-INF/web.xml | 29 ++++++ .../src/main/webapp/deposit.jsp | 21 ++++ .../src/main/webapp/index.jsp | 14 +++ .../src/main/webapp/style/style.css | 4 + 13 files changed, 506 insertions(+) create mode 100644 spring-framework/08-bank-jdbc-servlet-webapp/src/main/java/com/example/spring/bank/Account.java create mode 100644 spring-framework/08-bank-jdbc-servlet-webapp/src/main/java/com/example/spring/bank/AccountManager.java create mode 100644 spring-framework/08-bank-jdbc-servlet-webapp/src/main/java/com/example/spring/bank/AccountManagerImpl.java create mode 100644 spring-framework/08-bank-jdbc-servlet-webapp/src/main/java/com/example/spring/bank/dao/AccountDAO.java create mode 100644 spring-framework/08-bank-jdbc-servlet-webapp/src/main/java/com/example/spring/bank/dao/jdbc/JDBCAccountDAO.java create mode 100644 spring-framework/08-bank-jdbc-servlet-webapp/src/main/java/com/example/spring/bank/tx/TxAccountManager.java create mode 100644 spring-framework/08-bank-jdbc-servlet-webapp/src/main/java/com/example/spring/bank/web/BankGateway.java create mode 100644 spring-framework/08-bank-jdbc-servlet-webapp/src/main/webapp/WEB-INF/spring/applicationContext.xml create mode 100644 spring-framework/08-bank-jdbc-servlet-webapp/src/main/webapp/WEB-INF/spring/jdbc.properties create mode 100644 spring-framework/08-bank-jdbc-servlet-webapp/src/main/webapp/WEB-INF/web.xml create mode 100644 spring-framework/08-bank-jdbc-servlet-webapp/src/main/webapp/deposit.jsp create mode 100644 spring-framework/08-bank-jdbc-servlet-webapp/src/main/webapp/index.jsp create mode 100644 spring-framework/08-bank-jdbc-servlet-webapp/src/main/webapp/style/style.css (limited to 'spring-framework/08-bank-jdbc-servlet-webapp/src/main') diff --git a/spring-framework/08-bank-jdbc-servlet-webapp/src/main/java/com/example/spring/bank/Account.java b/spring-framework/08-bank-jdbc-servlet-webapp/src/main/java/com/example/spring/bank/Account.java new file mode 100644 index 0000000..6222af8 --- /dev/null +++ b/spring-framework/08-bank-jdbc-servlet-webapp/src/main/java/com/example/spring/bank/Account.java @@ -0,0 +1,21 @@ +package com.example.spring.bank; + +import java.math.BigDecimal; + +public class Account { + private int accountNumber; + private BigDecimal balance; + + public int getAccountNumber() { + return accountNumber; + } + public void setAccountNumber(int accountNumber) { + this.accountNumber = accountNumber; + } + public BigDecimal getBalance() { + return balance; + } + public void setBalance(BigDecimal balance) { + this.balance = balance; + } +} diff --git a/spring-framework/08-bank-jdbc-servlet-webapp/src/main/java/com/example/spring/bank/AccountManager.java b/spring-framework/08-bank-jdbc-servlet-webapp/src/main/java/com/example/spring/bank/AccountManager.java new file mode 100644 index 0000000..f299d60 --- /dev/null +++ b/spring-framework/08-bank-jdbc-servlet-webapp/src/main/java/com/example/spring/bank/AccountManager.java @@ -0,0 +1,21 @@ +package com.example.spring.bank; + +import java.math.BigDecimal; + +public interface AccountManager { + + public Account create(); + + public Account find(int accountNumber); + + public Account deposit(int accountNumber, BigDecimal amount); + public Account withdraw(int accountNumber, BigDecimal amount); + + public void delete(int accountNumber); + + /** Returns the first account */ + public Account transfer(int accountNumber1, int accountNumber2, BigDecimal amount); + + public void chargeForLowBalance(BigDecimal minimumBalance, BigDecimal amount); + +} diff --git a/spring-framework/08-bank-jdbc-servlet-webapp/src/main/java/com/example/spring/bank/AccountManagerImpl.java b/spring-framework/08-bank-jdbc-servlet-webapp/src/main/java/com/example/spring/bank/AccountManagerImpl.java new file mode 100644 index 0000000..39dc63e --- /dev/null +++ b/spring-framework/08-bank-jdbc-servlet-webapp/src/main/java/com/example/spring/bank/AccountManagerImpl.java @@ -0,0 +1,73 @@ +package com.example.spring.bank; + +import java.math.BigDecimal; +import java.util.Iterator; +import java.util.List; + +import com.example.spring.bank.dao.AccountDAO; + +public class AccountManagerImpl implements AccountManager { + + private AccountDAO accountDAO; + + public void setAccountDAO(AccountDAO accountDAO) { + this.accountDAO = accountDAO; + } + + @Override + public void chargeForLowBalance(BigDecimal minimumBalance, BigDecimal amount) { + List accounts = accountDAO.findAccountsWithLowBalance(minimumBalance); + for (Iterator iterator = accounts.iterator(); iterator.hasNext();) { + Account account = (Account) iterator.next(); + // Check if the balance will go beyond 0. If yes, set the balance to 0 + account.setBalance(account.getBalance().subtract(amount)); + accountDAO.update(account); + } + } + + @Override + public Account create() { + return accountDAO.createAccount(); + } + + @Override + public Account find(int accountNumber) { + return accountDAO.getAccount(accountNumber); + } + + @Override + public void delete(int accountNumber) { + accountDAO.delete(accountNumber); + } + + @Override + public Account deposit(int accountNumber, BigDecimal amount) { + Account account = accountDAO.getAccount(accountNumber); + account.setBalance(account.getBalance().add(amount)); + accountDAO.update(account); + + return account; + } + + @Override + public Account withdraw(int accountNumber, BigDecimal amount) { + Account account = accountDAO.getAccount(accountNumber); + account.setBalance(account.getBalance().subtract(amount)); + accountDAO.update(account); + + return account; + } + + @Override + public Account transfer(int accountNumber1, int accountNumber2, BigDecimal amount) { + Account account1 = accountDAO.getAccount(accountNumber1); + account1.setBalance(account1.getBalance().subtract(amount)); + accountDAO.update(account1); + + Account account2 = accountDAO.getAccount(accountNumber2); + account2.setBalance(account2.getBalance().add(amount)); + accountDAO.update(account2); + + return account1; + } +} \ No newline at end of file diff --git a/spring-framework/08-bank-jdbc-servlet-webapp/src/main/java/com/example/spring/bank/dao/AccountDAO.java b/spring-framework/08-bank-jdbc-servlet-webapp/src/main/java/com/example/spring/bank/dao/AccountDAO.java new file mode 100644 index 0000000..735aed2 --- /dev/null +++ b/spring-framework/08-bank-jdbc-servlet-webapp/src/main/java/com/example/spring/bank/dao/AccountDAO.java @@ -0,0 +1,15 @@ +package com.example.spring.bank.dao; + +import java.math.BigDecimal; +import java.util.List; + +import com.example.spring.bank.Account; + +public interface AccountDAO { + public Account createAccount(); + public Account getAccount(int accountNumber); + public void update(Account account); + public void delete(int accountNumber); + public List findAllAccounts(); + public List findAccountsWithLowBalance(BigDecimal lessThanAmount); +} diff --git a/spring-framework/08-bank-jdbc-servlet-webapp/src/main/java/com/example/spring/bank/dao/jdbc/JDBCAccountDAO.java b/spring-framework/08-bank-jdbc-servlet-webapp/src/main/java/com/example/spring/bank/dao/jdbc/JDBCAccountDAO.java new file mode 100644 index 0000000..d285a89 --- /dev/null +++ b/spring-framework/08-bank-jdbc-servlet-webapp/src/main/java/com/example/spring/bank/dao/jdbc/JDBCAccountDAO.java @@ -0,0 +1,94 @@ +package com.example.spring.bank.dao.jdbc; + +import java.math.BigDecimal; +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.List; + +import javax.sql.DataSource; + +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.jdbc.core.PreparedStatementCreator; +import org.springframework.jdbc.core.RowMapper; +import org.springframework.jdbc.support.GeneratedKeyHolder; +import org.springframework.jdbc.support.KeyHolder; + +import com.example.spring.bank.Account; +import com.example.spring.bank.dao.AccountDAO; + +public class JDBCAccountDAO implements AccountDAO { + + private JdbcTemplate jdbcTemplate; + + public void setDataSource(DataSource dataSource) { + this.jdbcTemplate = new JdbcTemplate(dataSource); + } + + + @Override + public Account createAccount() { +// Connection con = dataSource.getConnection(); +// PreparedStatement stmt = con.prepareStatement("...", autoGeneratedKeys); +// stmt.execute(); +// con.close(); + + + final String INSERT_SQL = "insert into account (balance) values(0)"; + + KeyHolder keyHolder = new GeneratedKeyHolder(); + jdbcTemplate.update( + new PreparedStatementCreator() { + public PreparedStatement createPreparedStatement(Connection connection) throws SQLException { + PreparedStatement ps = + connection.prepareStatement(INSERT_SQL, new String[] {"account_number"}); + // ps.setString(1, name); + return ps; + } + }, keyHolder); + + Account account = new Account(); + // keyHolder.getKey() now contains the generated key + account.setAccountNumber(keyHolder.getKey().intValue()); + account.setBalance(new BigDecimal("0.0")); + + return account; + } + + @Override + public void delete(int accountNumber) { + jdbcTemplate.update("delete from account where account_number = ?", Integer.valueOf(accountNumber)); + } + + @Override + public List findAccountsWithLowBalance(BigDecimal lessThanAmount) { + return this.jdbcTemplate.query( "select * from account where balance < ?", new Object[] {lessThanAmount.doubleValue()}, new AccountMapper()); + } + + @Override + public List findAllAccounts() { + return this.jdbcTemplate.query( "select * from account", new AccountMapper()); + } + + @Override + public Account getAccount(int accountNumber) { + return this.jdbcTemplate.queryForObject( "select * from account where account_number = ?", new Object[] {accountNumber}, new AccountMapper()); + } + + @Override + public void update(Account account) { + this.jdbcTemplate.update("update account set balance = ? where account_number = ?", account.getBalance(), account.getAccountNumber()); + } + + + private static final class AccountMapper implements RowMapper { + + public Account mapRow(ResultSet rs, int rowNum) throws SQLException { + Account account = new Account(); + account.setAccountNumber(rs.getInt("account_number")); + account.setBalance(rs.getBigDecimal("balance")); + return account; + } + } +} \ No newline at end of file diff --git a/spring-framework/08-bank-jdbc-servlet-webapp/src/main/java/com/example/spring/bank/tx/TxAccountManager.java b/spring-framework/08-bank-jdbc-servlet-webapp/src/main/java/com/example/spring/bank/tx/TxAccountManager.java new file mode 100644 index 0000000..a5b310d --- /dev/null +++ b/spring-framework/08-bank-jdbc-servlet-webapp/src/main/java/com/example/spring/bank/tx/TxAccountManager.java @@ -0,0 +1,109 @@ +package com.example.spring.bank.tx; + +import java.math.BigDecimal; + +import org.springframework.jdbc.datasource.DataSourceTransactionManager; +import org.springframework.transaction.TransactionStatus; +import org.springframework.transaction.support.TransactionCallback; +import org.springframework.transaction.support.TransactionCallbackWithoutResult; +import org.springframework.transaction.support.TransactionTemplate; + +import com.example.spring.bank.Account; +import com.example.spring.bank.AccountManager; + +/** + * This class decorates a given AccountManager by adding transaction boundaries. + * + * @author kamal + * + */ +public class TxAccountManager implements AccountManager { + + private AccountManager accountManager; + + public void setAccountManager(AccountManager accountManager) { + this.accountManager = accountManager; + } + + private TransactionTemplate txTemplate; + + public void setTxManager(DataSourceTransactionManager txManager) { + txTemplate = new TransactionTemplate(txManager); + } + + @Override + public Account create() { + return txTemplate.execute(new TransactionCallback() { + @Override + public Account doInTransaction(TransactionStatus arg0) { + return accountManager.create(); + } + }); + } + + @Override + public Account find(int accountNumber) { + return accountManager.find(accountNumber); + } + + @Override + public Account deposit(int accountNumber, BigDecimal amount) { + return txTemplate.execute(new TransactionCallback() { + + @Override + public Account doInTransaction(TransactionStatus arg0) { + return accountManager.deposit(accountNumber, amount); + } + }); + } + + @Override + public Account withdraw(int accountNumber, BigDecimal amount) { + return txTemplate.execute(new TransactionCallback() { + + @Override + public Account doInTransaction(TransactionStatus arg0) { + return accountManager.withdraw(accountNumber, amount); + } + }); + } + + @Override + public void delete(int accountNumber) { + txTemplate.execute(new TransactionCallbackWithoutResult() { + + @Override + protected void doInTransactionWithoutResult(TransactionStatus arg0) { + accountManager.delete(accountNumber); + } + }); + } + + @Override + public void chargeForLowBalance(BigDecimal minimumBalance, BigDecimal amount) { + txTemplate.execute(new TransactionCallbackWithoutResult() { + + @Override + protected void doInTransactionWithoutResult(TransactionStatus arg0) { + accountManager.chargeForLowBalance(minimumBalance, amount); + } + }); + } + + @Override + public Account transfer(int accountNumber1, int accountNumber2, BigDecimal amount) { + return txTemplate.execute(new TransactionCallback() { + + @Override + public Account doInTransaction(TransactionStatus status) { + try { + return accountManager.transfer(accountNumber1, accountNumber2, amount); + } catch (Exception e) { + // Some exception occurred. + status.setRollbackOnly(); + throw e; + } + } + }); + } +} diff --git a/spring-framework/08-bank-jdbc-servlet-webapp/src/main/java/com/example/spring/bank/web/BankGateway.java b/spring-framework/08-bank-jdbc-servlet-webapp/src/main/java/com/example/spring/bank/web/BankGateway.java new file mode 100644 index 0000000..e7908d5 --- /dev/null +++ b/spring-framework/08-bank-jdbc-servlet-webapp/src/main/java/com/example/spring/bank/web/BankGateway.java @@ -0,0 +1,59 @@ +package com.example.spring.bank.web; + +import java.io.IOException; +import java.math.BigDecimal; + +import javax.servlet.ServletException; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.springframework.web.context.WebApplicationContext; +import org.springframework.web.context.support.WebApplicationContextUtils; + +import com.example.spring.bank.AccountManager; + +/** + * Servlet implementation class BankGateway + */ +public class BankGateway extends HttpServlet { + private static final long serialVersionUID = 1L; + + /** + * @see HttpServlet#HttpServlet() + */ + public BankGateway() { + super(); + } + + /** + * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response) + */ + protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { + getServletContext().getRequestDispatcher("/deposit.jsp").forward(request, response); + } + + /** + * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response) + */ + protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { + WebApplicationContext ctx = WebApplicationContextUtils.getWebApplicationContext(getServletContext()); + AccountManager am = ctx.getBean("accountManager", AccountManager.class); + + int accountNumber = Integer.parseInt(request.getParameter("accountNumber")); + BigDecimal amount = new BigDecimal(request.getParameter("amount")); + + // How to use a session scoped bean (Example only) +// DepositForm form = (DepositForm) ctx.getBean("depositForm"); +// form.setAccountNumber(accountNumber); +// form.setAmount(amount); + // End of example + + + am.deposit(accountNumber, amount); + + // We can dispatch to a success page if we prefer! + getServletContext().getRequestDispatcher("/deposit.jsp").forward(request, response); + } + +} diff --git a/spring-framework/08-bank-jdbc-servlet-webapp/src/main/webapp/WEB-INF/spring/applicationContext.xml b/spring-framework/08-bank-jdbc-servlet-webapp/src/main/webapp/WEB-INF/spring/applicationContext.xml new file mode 100644 index 0000000..138f5d2 --- /dev/null +++ b/spring-framework/08-bank-jdbc-servlet-webapp/src/main/webapp/WEB-INF/spring/applicationContext.xml @@ -0,0 +1,39 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/spring-framework/08-bank-jdbc-servlet-webapp/src/main/webapp/WEB-INF/spring/jdbc.properties b/spring-framework/08-bank-jdbc-servlet-webapp/src/main/webapp/WEB-INF/spring/jdbc.properties new file mode 100644 index 0000000..09ab3ec --- /dev/null +++ b/spring-framework/08-bank-jdbc-servlet-webapp/src/main/webapp/WEB-INF/spring/jdbc.properties @@ -0,0 +1,7 @@ +jdbc.driverClassName=com.mysql.cj.jdbc.Driver +jdbc.url=jdbc:mysql://localhost/bankdb?useSSL=false +jdbc.username=bankdbuser +jdbc.password=abc123 + +#jdbc.driverClassName=org.postgresql.Driver +#jdbc.url=jdbc:postgresql://localhost/bank diff --git a/spring-framework/08-bank-jdbc-servlet-webapp/src/main/webapp/WEB-INF/web.xml b/spring-framework/08-bank-jdbc-servlet-webapp/src/main/webapp/WEB-INF/web.xml new file mode 100644 index 0000000..0fa6cae --- /dev/null +++ b/spring-framework/08-bank-jdbc-servlet-webapp/src/main/webapp/WEB-INF/web.xml @@ -0,0 +1,29 @@ + + + BankBasicWeb + + index.html + index.htm + index.jsp + default.html + default.htm + default.jsp + + + + BankGateway + BankGateway + com.example.spring.bank.web.BankGateway + + + BankGateway + /BankGateway + + + org.springframework.web.context.ContextLoaderListener + + + contextConfigLocation + /WEB-INF/spring/*Context.xml + + \ No newline at end of file diff --git a/spring-framework/08-bank-jdbc-servlet-webapp/src/main/webapp/deposit.jsp b/spring-framework/08-bank-jdbc-servlet-webapp/src/main/webapp/deposit.jsp new file mode 100644 index 0000000..ede3415 --- /dev/null +++ b/spring-framework/08-bank-jdbc-servlet-webapp/src/main/webapp/deposit.jsp @@ -0,0 +1,21 @@ +<%@ page language="java" contentType="text/html; charset=UTF-8" + pageEncoding="UTF-8"%> + + + + + +Deposit Money + + + + + +
+ Account No: + Amount: + +
+ + + \ No newline at end of file diff --git a/spring-framework/08-bank-jdbc-servlet-webapp/src/main/webapp/index.jsp b/spring-framework/08-bank-jdbc-servlet-webapp/src/main/webapp/index.jsp new file mode 100644 index 0000000..324aa4f --- /dev/null +++ b/spring-framework/08-bank-jdbc-servlet-webapp/src/main/webapp/index.jsp @@ -0,0 +1,14 @@ +<%@ page language="java" contentType="text/html; charset=UTF-8" + pageEncoding="UTF-8"%> + + + + +Deposit Money + + + +Deposit + + + \ No newline at end of file diff --git a/spring-framework/08-bank-jdbc-servlet-webapp/src/main/webapp/style/style.css b/spring-framework/08-bank-jdbc-servlet-webapp/src/main/webapp/style/style.css new file mode 100644 index 0000000..38e09ca --- /dev/null +++ b/spring-framework/08-bank-jdbc-servlet-webapp/src/main/webapp/style/style.css @@ -0,0 +1,4 @@ +input { + display:block; + margin-bottom: 0.5em; +} \ No newline at end of file -- cgit v1.2.3