Day68 Spring TX (事務)和配置細節以及單例設計模式
Spring其他配置細節
Spring其他配置細節:
Spring配置檔案流程:
載入Schema(配置全域性自動注入)
bean
aop
context
配置註解掃描
配置代理模式
配置屬性配置檔案掃描
配置資料庫源
使用${鍵名}獲取屬性檔案的值
配置工廠
配置mapper掃描
使用sqlSessionFactoryBeanName配置工廠注入
配置其他bean
配置切面
細節:
Spring配置自動注入:
在bean標籤中使用autowire屬性
default:屬性的預設值,表示預設使用全域性配置方式
byName:根據屬性名進行自動注入,只要有bean的id和屬性名相同,則自動進行賦值。
byType:根據屬性型別進行注入。如果bean的型別和屬性的型別一致,則自動注入。
constructor:根據構造器的形參的型別進行注入。其實還是byType
注意:引數必須是引用型別的屬性。
no:不使用自動注入。必須手動配置property
在頂層元標籤beans中使用 default-autowire="方式"設定全域性預設注入方式
注意:
使用了全域性自動注入(byName),配置工廠時可以不用手動注入資料來源物件
配置mapper掃描時。可以不再手動注入工廠了。前提是沒有使用JDBC屬性配置檔案。
Spring配置資料來源檔案
配置資料來源檔案掃描
<context:property-placeholder location="classpath:db.properties"/>
使用${鍵名}配置dataScource的屬性值
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="${jdbc.driver}"></property>
<property name="url" value="${jdbc.url}"></property>
<property name="username" value="${jdbc.username}"></property>
<property name="password" value="${jdbc.password}"></property>
</bean>
注意:
使用了此種配置方式,mapper掃描的工廠配置必須使用sqlSessionFactoryBeanName屬性進行配置。
Spring TX事務
SpringTX事務學習:
Spring配置流程
載入Scheme
IOC
AOP
掃描相關
配置全域性自動注入
配置屬性檔案掃描
配置註解掃描
配置代理模式
配置資料來源
獲取屬性檔案中的資料庫引數
配置工廠
配置mapper掃描
使用SqlSessionFactoryBeanName配置
配置切面
配置其他bean(註解)
配置事務
-------------------------------------------------------------
程式設計式事務:
事務管理程式碼由程式設計師自己編寫。
比如: commit() callback()
宣告式事務:
事務管理程式碼不用程式設計師自己編寫。
程式只需要宣告哪些程式碼需要進行事務管理即可。
Spring宣告式事務的配置:
1 匯入jar包
2 在Spring配置檔案中配置哪些程式碼需要進行事務管理
事務配置的屬性講解:
name屬性:配置新增事務的方法,支援萬用字元
<tx:method name="ins*"/>
propagation 屬性(事務的傳播行為)
isolation(事務的隔離界級別)
事務的配置方式:
<!-- 配置事務管理bean -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"></bean>
<!--配置事務管理的內容 -->
<!--配置要管理的方法 -->
<tx:advice id="advice" transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="ins*"/>
<tx:method name="up*"/>
<tx:method name="del*"/>
<tx:method name="sel*"/>
</tx:attributes>
</tx:advice>
<!--配置方法所在的功能程式碼 -->
<aop:config>
<aop:pointcut expression="execution(* com.bjsxt.serviceImpl.*.*(..))" id="point"/>
<aop:advisor advice-ref="advice" pointcut-ref="point"/>
</aop:config>
Spring註解
Spring註解:
在配置檔案中宣告註解掃描
@Component:相當於bean標籤配置。
@Service:相當於@Component,一般寫在serviceImpl中(使用無參構造器建立物件)
@Controller:相當於@Component寫在控制器上的。
@Resource:按照屬性名或者屬性型別給物件進行注入(依賴注入) java 不需要寫屬性的get/set方法
@Autowired:按照屬性型別給物件進行注入(依賴注入) spring 不需要寫屬性的get/set方法
@Value:給類的基本型別屬性註解賦值,需要屬性配置檔案,以及屬性檔案掃描
@Value("${my.demo}")
private String test;
其他註解(註解配置AOP)
比較全面的Spring配置檔案
配置檔案applicationContext.xml格式:
Spring配置流程
載入Scheme
IOC
AOP
掃描相關
配置全域性自動注入
配置屬性檔案掃描
配置註解掃描
配置代理模式
配置資料來源
獲取屬性檔案中的資料庫引數
配置工廠
配置mapper掃描
使用SqlSessionFactoryBeanName配置
配置切面
配置其他bean(註解)
配置事務
例子:
<?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"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="
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.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
"
default-autowire="byName"
>
<!-- 設定註解掃描 -->
<context:component-scan base-package="com.bjsxt.serviceImpl"></context:component-scan>
<!--設定屬性檔案掃描 -->
<context:property-placeholder location="classpath:db.properties"/>
<!--設定代理模式 -->
<aop:aspectj-autoproxy proxy-target-class="true"></aop:aspectj-autoproxy>
<!--配置資料來源 -->
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="${jdbc.driver}"></property>
<property name="url" value="${jdbc.url}"></property>
<property name="username" value="${jdbc.username}"></property>
<property name="password" value="${jdbc.password}"></property>
</bean>
<!--配置工廠 -->
<bean id="factory" class="org.mybatis.spring.SqlSessionFactoryBean"></bean>
<!--配置mapper掃描 -->
<bean id="mapper" class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="com.bjsxt.mapper"></property>
<property name="sqlSessionFactroyBeanName" value="factory"></property>
</bean>
<!--配置切面 -->
<!--配置切點bean -->
<!--配置通知bean -->
<!--織入形成切面 -->
<!--配置事務 -->
<!--配置事務bean -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"></bean>
<!--配置事務管理方法 -->
<tx:advice id="advice" transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="ins*"/>
<tx:method name="up*"/>
<tx:method name="del*"/>
<tx:method name="sel*" read-only="true"/> ---只讀狀態加快查詢效率
</tx:attributes>
</tx:advice>
<aop:config>
<aop:pointcut expression="execution(* com.bjsxt.serviceImpl.*.*(..))" id="my"/>
<aop:advisor advice-ref="advice" pointcut-ref="my"/>
</aop:config>
<!--配置其他bean -->
</beans>
-------------------------------------------------------------------------------------------------------
db.properties:
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/mybatis
jdbc.username=root
jdbc.password=root
log4j.properties:
log4j.rootCategory=info
log4j.logger.com.bjsxt.mapper=debug, CONSOLE
log4j.logger.com.bjsxt.advice=debug, CONSOLE
log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender
log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout
log4j.appender.CONSOLE.layout.ConversionPattern=- %c-%d-%m%n
log4j.appender.LOGFILE=org.apache.log4j.FileAppender
log4j.appender.LOGFILE.File=D:\axis.log
log4j.appender.LOGFILE.Append=true
log4j.appender.LOGFILE.layout=org.apache.log4j.PatternLayout
log4j.appender.LOGFILE.layout.ConversionPattern=- %c-%d-%m%n
my.properties:
舉例:
my.sid=1
my.sname=zhangsan
web.xml:
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0">
<!--配置Spring配置檔案路徑 -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationcontext.xml</param-value>
</context-param>
<!--配置監聽器 -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
</web-app>
Scope屬性以及單例設計模式
Scope:作用域
1.<bean>的屬性,
2.作用:控制物件有效範圍(單例,多例等)
3.<bean/>標籤對應的物件預設是單例的.
3.1 無論獲取多少次,都是同一個物件
4.scope可取值
4.1 singleton 預設值,單例
4.2 prototype 多例,每次獲取重新例項化
4.3 request 每次請求重新例項化
4.4 session 每個會話物件內,物件是單例的.
4.5 application 在application物件內是單例
4.6 global session spring推出的一個物件,依賴於spring-webmvc-portlet ,類似於session
單例設計模式:
1.作用: 在應用程式有保證最多隻能有一個例項.
2.好處:
2.1 提升執行效率.
2.2 實現資料共享. 案例:application物件
3.懶漢式
3.1 物件只有被呼叫時才去建立.
3.2 示例程式碼
public class SingleTon {
//由於物件需要被靜態方法呼叫,把方法設定為static
//由於物件是static,必須要設定訪問許可權修飾符為private ,如果是public可以直接呼叫物件,不執行訪問入口
private static SingleTon singleton;
/**
* 方法名和類名相同
* 無返回值.
*
*
* 其他類不能例項化這個類物件
*
* 對外提供訪問入口
*/
private SingleTon(){}
/**
* 例項方法,例項方法必須通過物件呼叫
*
* 設定方法為靜態方法
*
*
* @return
*/
public static SingleTon getInstance(){
//新增邏輯如果例項化過,直接返回
if(singleton==null){
/*
* 多執行緒訪問下,可能出現if同時成立的情況,新增鎖
*/
synchronized (SingleTon.class) {
//雙重驗證
if(singleton==null){
singleton = new SingleTon();
}
}
}
return singleton;
}
}
3.3 由於新增了鎖,所以導致效率低.
4.餓漢式
4.1 解決了懶漢式中多執行緒訪問可能出現同一個物件和效率低問題
public class SingleTon {
//在類載入時進行例項化.
private static SingleTon singleton=new SingleTon();
private SingleTon(){}
public static SingleTon getInstance(){
return singleton;
}
}
注意
標籤的使用:
基本資料型別 name - value
引用資料型別 name - ref
UserServlet如果建立的是UserServiceImpl us=... 就必須修改代理模式為
修改代理模式原因:UserServlet建立的是實現類
使用註解配置屬性:註解不使用get/set方法,使用初始化賦值(構造器)。
使用註解配置以後,建立物件的時候,id為 類名首字母小寫。
一、自動注入
二、Spring中載入properties檔案
注意:
問題:
如果配置了全域性自動注入default-autowire="byName",在使用
屬性檔案給資料來源引數進行賦值時就會報錯,因為自動注入的級別是高於
屬性檔案掃描的,也就屬性在沒有賦值之前就已經完成的自動注入.
解決:
在mapper掃描配置標籤中使用SqlSessionFactoryBeanName來進行配置factory注入.
小案例
需求:
資料庫表:
根據實體類進行建立
js:1.9jQuery
匯入相關jar包:aopalliance.jar
asm-3.3.1.jar
aspectjweaver.jar
cglib-2.2.2.jar
commons-logging-1.1.1.jar
commons-logging-1.1.3.jar
javassist-3.17.1-GA.jar
log4j-1.2.17.jar
log4j-api-2.0-rc1.jar
log4j-core-2.0-rc1.jar
mybatis-3.2.7.jar
mybatis-spring-1.2.3.jar
mysql-connector-java-5.1.30.jar
slf4j-api-1.7.5.jar
slf4j-log4j12-1.7.5.jar
spring-aop-4.1.6.RELEASE.jar
spring-aspects-4.1.6.RELEASE.jar
spring-beans-4.1.6.RELEASE.jar
spring-context-4.1.6.RELEASE.jar
spring-core-4.1.6.RELEASE.jar
spring-expression-4.1.6.RELEASE.jar
spring-jdbc-4.1.6.RELEASE.jar
spring-tx-4.1.6.RELEASE.jar
spring-web-4.1.6.RELEASE.jar
src:
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"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:tx="http://www.springframework.org/schema/tx"
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.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
"
default-autowire="byName"
>
<!--配置註解掃描 -->
<context:component-scan base-package="com.bjsxt.serviceImpl"></context:component-scan>
<!--配置代理模式為cglib -->
<aop:aspectj-autoproxy proxy-target-class="true"></aop:aspectj-autoproxy>
<!--資料來源配置檔案掃描 -->
<context:property-placeholder location="classpath:db.properties"/>
<!--配置資料來源 -->
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="${jdbc.driver}"></property>
<property name="url" value="${jdbc.url}"></property>
<property name="username" value="${jdbc.username}"></property>
<property name="password" value="${jdbc.password}"></property>
</bean>
<!--配置工廠 -->
<bean id="factory" class="org.mybatis.spring.SqlSessionFactoryBean"></bean>
<!--配置mapper包掃描 -->
<bean id="mapper" class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="com.bjsxt.mapper"></property>
<property name="sqlSessionFactoryBeanName" value="factory"></property>
</bean>
<!--配置事務 -->
<!--配置事務bean -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"></bean>
<!--配置事務管理辦法 -->
<tx:advice id="advice" transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="ins*"/>
<tx:method name="up*"/>
<tx:method name="del*"/>
<tx:method name="sel*" read-only="true" />
</tx:attributes>
</tx:advice>
<aop:config>
<aop:pointcut expression="execution(* com.bjsxt.serviceImpl.*.*(..))" id="my"/>
<aop:advisor advice-ref="advice" pointcut-ref="my"/>
</aop:config>
<!--配置切面 -->
<!--配置切點bean -->
<!--配置通知bean -->
<!--織入形成切面 -->
<!--配置其他bean -->
</beans>
db.properties:
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/mybatis
jdbc.username=root
jdbc.password=root
com.bjsxt.mapper:
AccountMapper.java:
package com.bjsxt.mapper;
import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.annotations.Update;
import com.bjsxt.pojo.Account;
public interface AccountMapper {
//校驗賬戶和密碼
@Select("select * from account where aid=#{0} and apwd=#{1}")
Account getOutAccountInfo(int aid,String apwd);
//校驗收款人
@Select("select * from account where aid=#{0} and aname=#{1}")
Account getInAccountInfo(int aid,String aname);
//根據使用者賬戶查詢金額
@Select("select * from account where aid=#{0}")
Account getOutAccountMoney(int aid);
//轉賬
@Update("update account set amoney=amoney+#{1} where aid=#{0}")
int transfer(int aid,double amoney);
}
com.bjsxt.pojo:
Account.java:
package com.bjsxt.pojo;
public class Account {
private int aid;
private String aname;
private String apwd;
private double amoney;
public Account() {
super();
// TODO Auto-generated constructor stub
}
public Account(int aid, String aname, String apwd, double amoney) {
super();
this.aid = aid;
this.aname = aname;
this.apwd = apwd;
this.amoney = amoney;
}
public int getAid() {
return aid;
}
public void setAid(int aid) {
this.aid = aid;
}
public String getAname() {
return aname;
}
public void setAname(String aname) {
this.aname = aname;
}
public String getApwd() {
return apwd;
}
public void setApwd(String apwd) {
this.apwd = apwd;
}
public double getAmoney() {
return amoney;
}
public void setAmoney(double amoney) {
this.amoney = amoney;
}
@Override
public String toString() {
return "Account [aid=" + aid + ", aname=" + aname + ", apwd=" + apwd + ", amoney=" + amoney + "]";
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + aid;
long temp;
temp = Double.doubleToLongBits(amoney);
result = prime * result + (int) (temp ^ (temp >>> 32));
result = prime * result + ((aname == null) ? 0 : aname.hashCode());
result = prime * result + ((apwd == null) ? 0 : apwd.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Account other = (Account) obj;
if (aid != other.aid)
return false;
if (Double.doubleToLongBits(amoney) != Double.doubleToLongBits(other.amoney))
return false;
if (aname == null) {
if (other.aname != null)
return false;
} else if (!aname.equals(other.aname))
return false;
if (apwd == null) {
if (other.apwd != null)
return false;
} else if (!apwd.equals(other.apwd))
return false;
return true;
}
}
com.bjsxt.service:
AccountService.java:
package com.bjsxt.service;
import org.apache.ibatis.annotations.Select;
import com.bjsxt.pojo.Account;
public interface AccountService {
//校驗賬戶和密碼
Account getOutAccountInfoService(int aid,String apwd);
//校驗收款人
Account getInAccountInfoService(int aid,String aname);
//校驗金額
Account getOutAccountMoney(int aid);
//轉賬
int transfer(int aid,int aid2,double amoney);
}
com.bjsxt.serviceImpl:
AccountServiceImpl.java:
package com.bjsxt.serviceImpl;
import javax.annotation.Resource;
import org.springframework.stereotype.Service;
import com.bjsxt.mapper.AccountMapper;
import com.bjsxt.pojo.Account;
import com.bjsxt.service.AccountService;
@Service
public class AccountServiceImpl implements AccountService{
//宣告mapper介面屬性
@Resource
private AccountMapper accountMapper;
//校驗賬號和密碼
@Override
public Account getOutAccountInfoService(int aid, String apwd) {
return accountMapper.getOutAccountInfo(aid, apwd);
}
//校驗賬號和姓名
@Override
public Account getInAccountInfoService(int aid, String aname) {
return accountMapper.getInAccountInfo(aid, aname);
}
//校驗金額
@Override
public Account getOutAccountMoney(int aid) {
return accountMapper.getOutAccountMoney(aid);
}
//轉賬
@Override
public int transfer(int aid,int aid2, double amoney) {
int i=accountMapper.transfer(aid, -amoney);
i+=accountMapper.transfer(aid2, amoney);
return i;
}
}
com.bjsxt.servlet:
AccountServlet.java:
package com.bjsxt.servlet;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.context.ApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;
import com.bjsxt.pojo.Account;
import com.bjsxt.serviceImpl.AccountServiceImpl;
/**
* Servlet implementation class AccountServlet
*/
@WebServlet("/account")
public class AccountServlet extends HttpServlet {
//宣告業務層物件
private AccountServiceImpl asi;
@Override
public void init() throws ServletException {
//獲取spring容器物件
ApplicationContext ac=WebApplicationContextUtils.getWebApplicationContext(getServletContext());
//獲取業務層物件
asi=(AccountServiceImpl) ac.getBean("accountServiceImpl");
}
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//設定請求編碼格式
req.setCharacterEncoding("utf-8");
//設定響應編碼格式
resp.setCharacterEncoding("utf-8");
resp.setContentType("text/html;charset=utf-8");
//獲取請求資料
String oper=req.getParameter("oper");
if("trans1".equals(oper)){
trans1(req,resp);
}else if("trans2".equals(oper)){
trans2(req,resp);
}else if("trans3".equals(oper)){
trans3(req,resp);
}
else if("trans".equals(oper)){
trans(req,resp);
}else {
System.out.println("AccountServlet.service(沒有找到對應的操作符)");
}
}
//開始轉賬
private void trans(HttpServletRequest req, HttpServletResponse resp) throws IOException {
//獲取請求資料
int aid=req.getParameter("aid")!=""?Integer.parseInt(req.getParameter("aid")):0;
double amoney=req.getParameter("amoney")!=""?Double.parseDouble(req.getParameter("amoney")):0.0;
int aid2=req.getParameter("aid2")!=""?Integer.parseInt(req.getParameter("aid2")):0;
//處理資料
int i=asi.transfer(aid, aid2, amoney);
if(i==2){
resp.sendRedirect("success.jsp");
}else{
resp.sendRedirect("fail.jsp");
}
}
//校驗賬戶使用者名稱 收款人賬戶
private void trans3(HttpServletRequest req, HttpServletResponse resp) throws IOException {
//獲取請求資料
int aid2=req.getParameter("aid2")!=""?Integer.parseInt(req.getParameter("aid2")):0;
String aname=req.getParameter("aname");
//處理請求資料
Account a=asi.getInAccountInfoService(aid2, aname);
//獲取轉賬人
Account a2=(Account) req.getSession().getAttribute("account");
if(a!=null&&a2.getAid()!=a.getAid()){
resp.getWriter().write("true");
}else{
resp.getWriter().write("false");
}
}
//校驗金額
private void trans2(HttpServletRequest req, HttpServletResponse resp) throws IOException {
//獲取請求資料
double amoney=req.getParameter("amoney")!=""?Double.parseDouble(req.getParameter("amoney")):0.0;
//處理請求資料
Account a=(Account) req.getSession().getAttribute("account");
int aid=a!=null?a.getAid():0;
Account a2=asi.getOutAccountMoney(aid);
double money=a2!=null?a2.getAmoney():0.0;
if(amoney<=money){
resp.getWriter().write("true");
}else{
resp.getWriter().write("false");
}
}
//校驗賬戶密碼
private void trans1(HttpServletRequest req, HttpServletResponse resp) throws IOException {
//獲取請求資料
int aid=req.getParameter("aid")!=""?Integer.parseInt(req.getParameter("aid")):0;
String apwd=req.getParameter("apwd");
//處理請求資料
Account account= asi.getOutAccountInfoService(aid, apwd);
//響應處理結果
if(account!=null){
req.getSession().setAttribute("account", account);
resp.getWriter().write("true");
}else{
resp.getWriter().write("false");
}
}
}
WebContent:
js:1.9
web.xml:
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0">
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
</web-app>
trans.jsp:
<%@ page language="java" contentType="text/html; charset=utf-8"
pageEncoding="utf-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Insert title here</title>
<script type="text/javascript" src="js/j.js"></script>
<script type="text/javascript">
$(function(){
$("#account").blur(function(){
if($(this).val()==""||$(this).val()==null){
$(this).next().html("請輸入賬號").css("color","red");
}else{
$(this).next().html("√").css("color","green");
}
})
$("#account2").blur(function(){
if($(this).val()==""||$(this).val()==null){
$(this).next().html("請輸入賬號").css("color","red");
}else{
$(this).next().html("√").css("color","green");
}
})
//校驗賬號密碼
$("#pwd").blur(function(){
var account=$("#account").val();
var pwd=$(this).val();
$.get("account",{oper:"trans1",aid:account,apwd:pwd},function(data){
if("true"==data){
$("#s1").html("√").css("color","green");
}else{
$("#s1").html("×").css("color","red");
}
})
})
//校驗金額
$("#money").blur(function(){
var money=$(this).val();
$.get("account",{oper:"trans2",amoney:money},function(data){
if("true"==data){
$("#s2").html("√").css("color","green");
}else{
$("#s2").html("×").css("color","red");
}
})
})
//校驗收款人賬號
$("#name").blur(function(){
var account2=$("#account2").val();
var name=$(this).val();
$.get("account",{oper:"trans3",aid2:account2,aname:name},function(data){
if("true"==data){
$("#name").next().html("√").css("color","green");
}else{
$("#name").next().html("×").css("color","red");
}
})
})
//校驗submit
$("form").submit(function(){
$("input[type=text]").trigger("blur");
$("input[type=password]").trigger("blur");
if($("span").css("color")=="rgb(255, 0, 0)"){
return false;
}else{
return true;
}
})
})
</script>
</head>
<body>
<h3>轉賬頁面</h3>
<hr />
<div>
<form action="account" method="get" >
<input type="hidden" name="oper" value="trans"/>
轉賬賬戶:<input type="text" name="aid" value="" id="account"/><span id="saccount"></span><br />
密碼:<input type="password" name="apwd" value="" id="pwd" /><span id="s1"></span><br />
金額: <input type="text" name="amoney" value="" id="money"/><span id="s2"></span><br />
收款賬號: <input type="text" name="aid2" value="" id="account2"/><span></span><br />
收款人姓名 <input type="text" name="aname" value="" id="name"/><span></span><br />
<input type="submit" value="開始轉賬" id="btn"/>
</form>
</div>
</body>
</html>
success.jsp:
<%@ page language="java" contentType="text/html; charset=utf-8"
pageEncoding="utf-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Insert title here</title>
<script type="text/javascript" src="js/j.js"></script>
<script type="text/javascript">
</script>
</head>
<body>
<span>轉賬成功</span>
</body>
</html>
fail.jsp:
<%@ page language="java" contentType="text/html; charset=utf-8"
pageEncoding="utf-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Insert title here</title>
</head>
<body>
轉賬失敗,請檢查填寫的資訊是否正確
</body>
</html>
原始碼地址:
連結:https://pan.baidu.com/s/1P31bbwVcsvn9KT_gKnl2NQ 密碼:ee3d
容易出錯的地方
1、獲取前臺請求資料的時候注意:
如果請求資料為空,會報格式轉換異常,可以用三木運算子判斷進行對其賦值
//獲取請求資料
int aid=req.getParameter("aid")!=""?Integer.parseInt(req.getParameter("aid")):0;
2、如果轉賬頁面沒有輸入賬號,那麼在查詢金額的時候獲取session裡的賬戶ID會報空指標,可以這樣解決:
int aid=a!=null?a.getAid():0;
3、在form表單的submit校驗的時候,$("form"),雙引號裡面不應該加#。
4、不要忘了web.xml
小結
Spring其他配置細節
Spring TX事務
Spring註解
比較全面的Spring配置檔案
Scope屬性以及單例設計模式
注意
小案例
相關文章
- Java TX-LCN:(四)TX-LCN 事務模式Java模式
- Spring程式設計式和宣告式事務例項講解Spring程式設計
- 設計模式(單例模式)設計模式單例
- [設計模式] 單例模式設計模式單例
- 設計模式-單例模式設計模式單例
- 設計模式 —— 單例模式設計模式單例
- 設計模式 單例模式設計模式單例
- 設計模式——單例模式設計模式單例
- 設計模式之單例設計模式設計模式單例
- 單例設計模式單例設計模式
- 設計模式(一)_單例模式設計模式單例
- 常用設計模式-單例模式設計模式單例
- 設計模式之單例模式設計模式單例
- Java設計模式【單例模式】Java設計模式單例
- Java設計模式 | 單例模式Java設計模式單例
- 001設計模式:單例模式設計模式單例
- # Python設計模式 單例模式Python設計模式單例
- 設計模式一(單例模式)設計模式單例
- 設計模式之☞單例模式設計模式單例
- Java設計模式——單例模式Java設計模式單例
- Java設計模式–單例模式Java設計模式單例
- js設計模式--單例模式JS設計模式單例
- Java設計模式-單例模式Java設計模式單例
- 設計模式(二)——單例模式設計模式單例
- 設計模式之---單例模式設計模式單例
- Java設計模式--單例模式Java設計模式單例
- Python設計模式——單例模式Python設計模式單例
- 設計模式—singleton(單例模式)設計模式單例
- python設計模式-單例模式Python設計模式單例
- 設計模式-單例模式、多例模式設計模式單例
- 設計模式總結 —— 單例設計模式設計模式單例
- JavaScript設計模式初探--單例設計模式JavaScript設計模式單例
- TX-LCN分散式事務之LCN模式分散式模式
- Singleton 單例設計模式單例設計模式
- java單例設計模式Java單例設計模式
- 設計模式之單例設計模式單例
- 設計模式:單例模式的使用和實現(JAVA)設計模式單例Java
- Javascript設計模式之單例模式JavaScript設計模式單例