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属性以及单例设计模式
注意
小案例

猜你喜欢

转载自blog.csdn.net/qq_21953671/article/details/79801650
今日推荐