2009年5月31日星期日

使用 Spring 2.5 TestContext 测试框架

使用 Spring 2.5 TestContext 测试框架

级别: 初级

陈 雄华 (quickselect@163.com), 技术总监, 宝宝淘网络科技有限公司

2008 年 3 月 28 日

Spring 2.5 TestContext 测试框架用于测试基于 Spring 的程序,TestContext 测试框架和低版本 Spring 测试框架没有任何关系,是一个全新的基于注解的测试框架,为 Spring 推荐使用该测试框架。

概述

Spring 2.5 相比于 Spring 2.0 所新增的最重要的功能可以归结为以下 3 点:

  • 基于注解的 IoC 功能;
  • 基于注解驱动的 Spring MVC 功能;
  • 基于注解的 TestContext 测试框架。

Spring 推荐开发者使用新的基于注解的 TestContext 测试框架,本文我们将对此进行详细的讲述。

低版本的 Spring 所提供的 Spring 测试框架构在 JUnit 3.8 基础上扩展而来,它提供了若干个测试基类。而 Spring 2.5 所新增的基于注解的 TestContext 测试框架和低版本的测试框架没有任何关系。它采用全新的注解技术可以让 POJO 成为 Spring 的测试用例,除了拥有旧测试框架所有功能外,TestContext 还添加了一些新的功能,TestContext 可以运行在 JUnit 3.8、JUnit 4.4、TestNG 等测试框架下。





回页首


直接使用 JUnit 测试 Spring 程序存在的不足

在拙作《精通 Spring 2.x — 企业应用开发详解》一书中,笔者曾经指出如果直接使用 JUnit 测试基于 Spring 的程序,将存在以下 4 点明显的不足:

  • 导致 Spring 容器多次初始化问题:根据 JUnit 测试用例的调用流程,每执行一个测试方法都会重新创建一个测试用例实例并调用其 setUp() 方法。由于在一般情况下,我们都在 setUp() 方法中初始化 Spring 容器,这意味着测试用例中有多少个测试方法,Spring 容器就会被重复初始化多少次。
  • 需要使用硬编码方式手工获取 Bean:在测试用例中,我们需要通过 ApplicationContext.getBean() 的方法从 Spirng 容器中获取需要测试的目标 Bean,并且还要进行造型操作。
  • 数据库现场容易遭受破坏:测试方法可能会对数据库记录进行更改操作,破坏数据库现场。虽然是针对开发数据库进行测试工作的,但如果数据操作的影响是持久的,将会形成积累效应并影响到测试用例的再次执行。举个例子,假设在某个测试方法中往数据库插入一条 ID 为 1 的 t_user 记录,第一次运行不会有问题,第二次运行时,就会因为主键冲突而导致测试用例执行失败。所以测试用例应该既能够完成测试固件业务功能正确性的检查,又能够容易地在测试完成后恢复现场,做到踏雪无迹、雁过无痕。
  • 不容易在同一事务下访问数据库以检验业务操作的正确性:当测试固件操作数据库时,为了检测数据操作的正确性,需要通过一种方便途径在测试方法相同的事务环境下访问数据库,以检查测试固件数据操作的执行效果。如果直接使用 JUnit 进行测试,我们很难完成这项操作。

Spring 测试框架是专门为测试基于 Spring 框架应用程序而设计的,它能够让测试用例非常方便地和 Spring 框架结合起来,以上所有问题都将迎刃而解。





回页首


一个需要测试的 Spring 服务类

在具体使用 TextContext 测试框架之前,我们先来认识一下需要测试的 UserService 服务类。UserService 服务类中拥有一个处理用户登录的服务方法,其代码如下所示:


清单1. UserService.java 需要测试的服务类
	
package com.baobaotao.service;

import com.baobaotao.domain.LoginLog;
import com.baobaotao.domain.User;
import com.baobaotao.dao.UserDao;
import com.baobaotao.dao.LoginLogDao;

public class UserService{

private UserDao userDao;
private LoginLogDao loginLogDao;

public void handleUserLogin(User user) {
user.setCredits( 5 + user.getCredits());
LoginLog loginLog = new LoginLog();
loginLog.setUserId(user.getUserId());
loginLog.setIp(user.getLastIp());
loginLog.setLoginTime(user.getLastVisit());
userDao.updateLoginInfo(user);
loginLogDao.insertLoginLog(loginLog);
}
//省略get/setter方法
}

UserService 需要调用 DAO 层的 UserDao 和 LoginLogDao 以及 User 和 LoginLog 这两个 PO 完成业务逻辑,User 和 LoginLog分别对应 t_user 和 t_login_log 这两张数据库表。

在用户登录成功后调用 UserService 中的 handleUserLogin() 方法执行用户登录成功后的业务逻辑:

  1. 登录用户添加 5 个积分(t_user.credits);
  2. 登录用户的最后访问时间(t_user.last_visit)和 IP(t_user.last_ip)更新为当前值;
  3. 在日志表中(t_login_log)中为用户添加一条登录日志。

这是一个需要访问数据库并存在数据更改操作的业务方法,它工作在事务环境下。下面是装配该服务类 Bean 的 Spring 配置文件:


清单2. applicationContext.xml: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:p="http://www.springframework.org/schema/p"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-2.5.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-2.5.xsd">
<!-- 配置数据源 -->
<bean id="dataSource"
class="org.apache.commons.dbcp.BasicDataSource"
destroy-method="close"
p:driverClassName="com.mysql.jdbc.Driver"
p:url="jdbc:mysql://localhost/sampledb"
p:username="root"
p:password="1234"/>

<!-- 配置Jdbc模板 -->
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"
p:dataSource-ref="dataSource"/>

<!-- 配置dao -->
<bean id="loginLogDao"class="com.baobaotao.dao.LoginLogDao"
p:jdbcTemplate-ref="jdbcTemplate"/>
<bean id="userDao" class="com.baobaotao.dao.UserDao"
p:jdbcTemplate-ref="jdbcTemplate"/>

<!-- 事务管理器 -->
<bean id="transactionManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager"
p:dataSource-ref="dataSource"/>

<bean id="userService" class="com.baobaotao.service.UserService"
p:userDao-ref="userDao" p:loginLogDao-ref="loginLogDao"/>

<!-- 使用aop/tx命名空间配置事务管理,这里对service包下的服务类方法提供事务-->
<aop:config>
<aop:pointcut id="jdbcServiceMethod"
expression= "within(com.baobaotao.service..*)" />
<aop:advisor pointcut-ref="jdbcServiceMethod" advice-ref="jdbcTxAdvice" />
</aop:config>
<tx:advice id="jdbcTxAdvice" transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="*"/>
</tx:attributes>
</tx:advice>
</beans>

UserService 所关联的 DAO 类和 PO 类都比较简单,请参看本文附件的程序代码。在着手测试 UserSerivce 之前,需要将创建数据库表,你可以在附件的 schema 目录下找到相应的 SQL 脚本文件。





回页首


编写 UserService 的测试用例

下面我们为 UserService 编写一个简单的测试用例类,此时的目标是让这个基于 TestContext 测试框架的测试类运行起来,我们将在后面逐步完善这个测试用例。


清单3.TestUserService.java: 基于注解的测试用例
	
package com.baobaotao.service;

import org.springframework.test.context.junit4.
AbstractTransactionalJUnit4SpringContextTests;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.beans.factory.annotation.Autowired;
import org.junit.Test;
import com.baobaotao.domain.User;

import java.util.Date;

@ContextConfiguration //①
public class TestUserService extends
AbstractTransactionalJUnit4SpringContextTests {

@Autowired //②
private UserService userService;

@Test //③
public void handleUserLogin(){
User user = new User();
user.setUserId(1);
user.setLastIp("127.0.0.1");
Date now = new Date();
user.setLastVisit(now.getTime());
userService.handleUserLogin(user);
}
}

这里,我们让 TestUserService 直接继承于 Spring 所提供的 AbstractTransactionalJUnit4SpringContextTests 的抽象测试类,稍后本文将对这个抽象测试类进行剖析,这里你仅须知道该抽象测试类的作用是让 TestContext 测试框架可以在 JUnit 4.4 测试框架基础上运行起来就可以了。

在 ① 处,标注了一个类级的 @ContextConfiguration 注解,这里 Spring 将按 TestContext 契约查找 classpath:/com/baobaotao/service/TestUserService-context.xml 的 Spring 配置文件,并使用该配置文件启动 Spring 容器。@ContextConfiguration 注解有以下两个常用的属性:

  • locations:可以通过该属性手工指定 Spring 配置文件所在的位置,可以指定一个或多个 Spring 配置文件。如下所示:

    @ContextConfiguration(locations={“xx/yy/beans1.xml”,” xx/yy/beans2.xml”})

  • inheritLocations:是否要继承父测试用例类中的 Spring 配置文件,默认为 true。如下面的例子:

    @ContextConfiguration(locations={"base-context.xml"})
    public class BaseTest {
    // ...
    }
    @ContextConfiguration(locations={"extended-context.xml"})
    public class ExtendedTest extends BaseTest {
    // ...
    }

如果 inheritLocations 设置为 false,则 ExtendedTest 仅会使用 extended-context.xml 配置文件,否则将使用 base-context.xml 和 extended-context.xml 这两个配置文件。

② 处的 @Autowired 注解让 Spring 容器自动注入 UserService 类型的 Bean。而在 ③ 处标注的 @Test 注解则让 handleUserLogin() 方法成为一个 JUnit 4.4 标准的测试方法, @Test 是 JUnit 4.4 所定义的注解。

在运行 TestUserService 测试类之前,让我们先看一下 TestUserService-context.xml 配置文件的内容:


清单 4.TestUserService 所引用的 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"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">

<!-- ① 引入清单1定义的Spring配置文件 -->
<import resource="classpath:/applicationContext.xml"/>

</beans>

在 ① 处引入了清单 1 中定义的 Spring 配置文件,这样我们就可以将其中定义的 UserService Bean 作为测试固件注入到 TestUserService 中了。

在你的 IDE 中(Eclipse、JBuilder、Idea 等),将 JUnit 4.4 类包引入到项目工程中后,在 TestUserService 类中点击右键运行该测试类,将发现 TestUserService 已经可以成功运行了,如 图 1 所示:


图 1. 在 Eclipse 6.0 中运行 TestUserService
图 1. 在 Eclipse 6.0 中运行 TestUserService 

TestUserService 可以正确运行,说明其 userService 这个测试固件已经享受了 Spring 自动注入的功能。在运行该测试用例后,到数据库中查看 t_user 表和 t_login_log 表,你会发现表数据和测试前是一样的!这说明虽然我们在清单 3 的 handleUserLogin() 测试方法中执行了 userService.handleUserLogin(user) 的操作,但它并没有对数据库现场造成破坏:这是因为 Spring 的在测试方法返回前进行了事务回滚操作。

虽然 TestUserService.handleUserLogin() 测试方法已经可以成功运行,但是它在测试功能上是不完善的,读者朋友可以已经发现了它存在以下两个问题:

  • 我们仅仅执行了 UserService#handleUserLogin(user) 方法,但验证该方法执行结果的正确性。
  • 在测试方法中直接使用 ID 为 1 的 User 对象进行测试,这相当于要求在数据库 t_user 表必须已经存在 ID 为 1 的记录,如果 t_user 中不存在这条记录,将导致测试方法执行失败。




回页首


准备测试数据并检测运行结果

在这节里,我们将着手解决上面所提出的两个问题,在测试用例中准备测试数据并到数据库中检测业务执行结果的正确性。

准备测试数据

相比于在测试方法中直接访问预定的数据记录,在测试方法执行前通过程序准备一些测试数据,然后在此基础上运行测试方法是比较好的策略,因为后者不需要对数据库的状态做假设。在 TestContext 中,你可以通过使用 JUnit 4.4 的 @Before 注解达到这个目的,请看下面的代码:


清单5. 为测试方法准备数据
	
package com.baobaotao.service;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.Date;

import org.junit.Before;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.PreparedStatementCreator;
import org.springframework.jdbc.support.GeneratedKeyHolder;
import org.springframework.jdbc.support.KeyHolder;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.
AbstractTransactionalJUnit4SpringContextTests;

import com.baobaotao.dao.UserDao;
import com.baobaotao.domain.User;

@ContextConfiguration
public class TestUserService
extends AbstractTransactionalJUnit4SpringContextTests {
@Autowired
private UserService userService;

@Autowired
private UserDao userDao;

private int userId;

@Before //① 准备测试数据
public void prepareTestData() {
final String sql = "insert into t_user(user_name,password) values('tom','1234')";
simpleJdbcTemplate.update(sql);
KeyHolder keyHolder = new GeneratedKeyHolder();
simpleJdbcTemplate.getJdbcOperations().update(
new PreparedStatementCreator() {
public PreparedStatement createPreparedStatement(Connection conn)
throws SQLException {
PreparedStatement ps = conn.prepareStatement(sql);
return ps;
}
}, keyHolder);
userId = keyHolder.getKey().intValue();//①-1 记录测试数据的id
}

@Test
public void handleUserLogin(){
User user = userDao.getUserById(userId); //② 获取测试数据
user.setLastIp("127.0.0.1");
Date now = new Date();
user.setLastVisit(now.getTime());
userService.handleUserLogin(user);
}
}

JUnit 4.4 允许通过注解指定某些方法在测试方法执行前后进行调用,即是 @Before 和 @After 注解。在 Spring TestContext 中,标注 @Before 和 @After 的方法会在测试用例中每个测试方法运行前后执行,并和测试方法运行于同一个事务中。在 清单 5 中 ① 处,我们给 prepareTestData() 标注上了 @Before 注解,在该方法中准备一些测试数据,以供 TestUserService 中所有测试方法使用(这里仅有一个 handleUserLogin() 测试方法)。由于测试方法运行后,整个事务会被回滚,在 prepareTestData() 中插入的测试数据也不会持久化到数据库中,因此我们无须手工删除这条记录。

标注 @Before 或 @After 注解的方法和测试方法运行在同一个事务中,但有时我们希望在测试方法的事务开始之前或完成之后执行某些方法以便获取数据库现场的一些情况。这时,可以使用 Spring TestContext 的 @BeforeTransaction 和 @AfterTransaction 注解来达到目录(这两个注解位于 org.springframework.test.context.transaction 包中)。

虽然大多数业务方法都会访问数据库,但也并非所有需要测试的业务方法都需要和数据库打交道。而在默认情况下,继承于 AbstractTransactionalJUnit4SpringContextTests 测试用例的所有测试方法都将工作于事务环境下,你可以显式地通过 @NotTransactional 注解,让测试方法不工作于事务环境下。

prepareTestData() 方法中使用到了 simpleJdbcTemplate 对象访问操作数据库,该对象在 AbstractTransactionalJUnit4SpringContextTests 抽象类中定义,只要 Spring 容器有配置数据源,simpleJdbcTemplate 就会被自动创建。同时该抽象类中还拥有一个 Spring 容器引用:applicationContext,你可以借助该成员变量访问 Spring 容器,执行获取 Bean,发布事件等操作。

此外,AbstractTransactionalJUnit4SpringContextTests 还提供了若干个访问数据库的便捷方法,说明如下:

  • protected int countRowsInTable(String tableName) :计算数据表的记录数。
  • protected int deleteFromTables(String... names):删除表中的记录,可以指定多张表。
  • protected void executeSqlScript(String sqlResourcePath, boolean continueOnError):执行 SQL 脚本文件,在脚本文件中,其格式必须一个 SQL 语句一行。

在测试方法 handleUserLogin() 的 ② 处,我们通过 userDao 获取 prepareTestData() 添加的测试数据,测试方法在测试数据的基础上执行业务逻辑。使用这种测试方式后,在任何情况下运行 TestUserService 都不会发生业务逻辑之外的问题。

检验业务逻辑的正确性

到目前为此,TestUserService 的 handleUserLogin() 测试方法仅是简单地执行 UserService#handleUserLogin() 业务方法,但并没有在业务方法执行后检查执行结果的正确性,因此这个测试是不到位的。也就是说,我们必须访问数据库以检查业务方法对数据更改是否成功:这包括积分(credits)、最后登录时间(last_visit)、最后登录 IP(last_ip)以及登录日志表中的登录日志记录(t_login_log)。下面,我们补充这项重要的检查数据正确性的工作:


清单5. 检验业务方法执行结果的正确性
	
@Test
public void handleUserLogin(){
User user = userDao.getUserById(userId);
user.setLastIp("127.0.0.1");
Date now = new Date();
user.setLastVisit(now.getTime());
userService.handleUserLogin(user);

//------------------以下为业务执行结果检查的代码---------------------
User newUser = userDao.getUserById(userId);
Assert.assertEquals(5, newUser.getCredits()); //①检测积分
//①检测最后登录时间和IP
Assert.assertEquals(now.getTime(), newUser.getLastVisit());
Assert.assertEquals("127.0.0.1",newUser.getLastIp());

// ③检测登录记录
String sql = "select count(1) from t_login_log where user_id=? "+
“ and login_datetime=? and ip=?";
int logCount =simpleJdbcTemplate.queryForInt(sql, user.getUserId(),
user.getLastVisit(),user.getLastIp());
Assert.assertEquals(1, logCount);
}

在业务方法执行后,我们查询数据库中相应记录以检查是否和期望的效果一致,如 ① 和 ② 所示。在 ③ 处,我们使用 SimpleJdbcTemplate 查询 t_login_log,以检查该表中是否已经添加了一条用户登录日志。

注意:由于我们的 DAO 层采用 Spring JDBC 框架,它没有采用服务层缓存技术,所以可以使用 DAO 类返回数据库中的数据。如果采用 Hibernate 等 ORM 框架,由于它们采用了服务层缓存的技术,为了获取数据库中的相应数据,需要在业务方法执行后调用 HibernateTemplate.flush() 方法,将缓存中的对象同步到数据库中,这时才可以通过 SimpleJdbcTemplate 在数据库中访问业务方法的执行情况。





回页首


Spring TestContext 测试框架体系结构

在前面,我们直接通过扩展 AbstractTransactionalJUnit4SpringContextTests 编写测试用例,在了解了编写基于 TestContext 测试框架的测试用例后,现在是了解 TestContext 测试框架本身的时候了。

TestContext 核心类、支持类以及注解类

TestContext 测试框架的核心由 org.springframework.test.context 包中三个类组成,分别是 TestContext 和 TestContextManager 类以及 TestExecutionListener 接口。其类图如下 图 2 所示:


图 2. Spring TestContext 测试框架核心类
图 2. Spring TestContext 测试框架核心类 
  • TestContext:它封装了运行测试用例的上下文;
  • TestContextManager:它是进入 Spring TestContext 框架的程序主入口,它管理着一个 TestContext 实例,并在适合的执行点上向所有注册在 TestContextManager 中的 TestExecutionListener 监听器发布事件:比如测试用例实例的准备,测试方法执行前后方法的调用等。
  • TestExecutionListener:该接口负责响应 TestContextManager 发布的事件。

Spring TestContext 允许在测试用例类中通过 @TestExecutionListeners 注解向 TestContextManager 注册多个监听器,如下所示:

@TestExecutionListeners( { 
DependencyInjectionTestExecutionListener.class,
DirtiesContextTestExecutionListener.class })
public class TestXxxService{

}

Spring 提供了几个 TestExecutionListener 接口实现类,分别说明如下:

  • DependencyInjectionTestExecutionListener:该监听器提供了自动注入的功能,它负责解析测试用例中 @Autowried 注解并完成自动注入;
  • DirtiesContextTestExecutionListener:一般情况下测试方法并不会对 Spring 容器上下文造成破坏(改变 Bean 的配置信息等),如果某个测试方法确实会破坏 Spring 容器上下文,你可以显式地为该测试方法添加 @DirtiesContext 注解,以便 Spring TestContext 在测试该方法后刷新 Spring 容器的上下文,而 DirtiesContextTestExecutionListener 监听器的工作就是解析 @DirtiesContext 注解;
  • TransactionalTestExecutionListener:它负责解析 @Transaction、@NotTransactional 以及 @Rollback 等事务注解的注解。@Transaction 注解让测试方法工作于事务环境中,不过在测试方法返回前事务会被回滚。你可以使用 @Rollback(false) 让测试方法返回前提交事务。而 @NotTransactional 注解则让测试方法不工作于事务环境中。此外,你还可以使用类或方法级别的 @TransactionConfiguration 注解改变事务管理策略,如下所示:
    @TransactionConfiguration(transactionManager="txMgr", defaultRollback=false)
    @Transactional
    public class TestUserService {

    }

我们知道在 JUnit 4.4 中可以通过 @RunWith 注解指定测试用例的运行器,Spring TestContext 框架提供了扩展于 org.junit.internal.runners.JUnit4ClassRunner 的 SpringJUnit4ClassRunner 运行器,它负责总装 Spring TestContext 测试框架并将其统一到 JUnit 4.4 框架中。

TestContext 所提供的抽象测试用例

Spring TestContext 为基于 JUnit 4.4 测试框架提供了两个抽象测试用例类,分别是 AbstractJUnit4SpringContextTests 和 AbstractTransactionalJUnit4SpringContextTests,而后者扩展于前者。让我们来看一下这两个抽象测试用例类的骨架代码:

@RunWith(SpringJUnit4ClassRunner.class) //① 指定测试用例运行器
@TestExecutionListeners( //② 注册了两个TestExecutionListener监听器
{ DependencyInjectionTestExecutionListener.class,
DirtiesContextTestExecutionListener.class })
public class AbstractJUnit4SpringContextTests implements ApplicationContextAware {

}

① 处将 SpringJUnit4ClassRunner 指定为测试用例运行器,它负责无缝地将 TestContext 测试框架移花接木到 JUnit 4.4 测试框架中,它是 Spring TestContext 可以运行起来的根本所在。② 处通过 @TestExecutionListeners 注解向测试用例类中注册了两个 TestExecutionListener 监听器,这两个监听器分别负责对 @Autowired 和 @DirtiesContext 注解进行处理,为测试用例提供自动注入和重新刷新 Spring 容器上下文的功能。

AbstractTransactionalJUnit4SpringContextTests 扩展于 AbstractJUnit4SpringContextTests,提供了事务管理的支持,其骨架代码如下所示:

//① 注册测试用例事务管理的监听器
@TestExecutionListeners( { TransactionalTestExecutionListener.class })
@Transactional //② 使测试用例的所有方法都将工作于事务环境下
public class AbstractTransactionalJUnit4SpringContextTests
extends AbstractJUnit4SpringContextTests {

}

在 ① 处,AbstractTransactionalJUnit4SpringContextTests 向测试用例类中注册了 TransactionalTestExecutionListener 监听器,这样测试用例中的 @Transaction、@NotTransaction 以及 @Rollback 等注解就可以正确地工作起来了。注意,你不需要在 Spring 配置文件通过 <tx:annotation-driven /> 和 <context:annotation-config/> 为测试用例类启用注解事务驱动和注解自动注入,这个工作完全于 TestContext 自身来解决(通过注册 DependencyInjectionTestExecutionListener 和 TransactionalTestExecutionListener 监听器),毕竟测试用例类没有注册到 Spring 容器中,没有成为 Spring 的 Bean。





回页首


小结

我们通过对一个典型的涉及数据库访问操作的 UserService 服务类的测试,讲述了使用 Spring 2.5 TestContext 测试框架进行集成测试的各项问题,这包括测试固件的自动注入、事务自动回滚、通过 SimpleJdbcTemplate 直接访问数据库以及测试数据准备等问题。

在通过一个实际例子的学习后,我们对如何使用 TestContext 测试框架有了一个具体的认识,在此基础上我们对 Spring TestContext 测试框架体系结构进行了分析,然后剖析了 Spring 为 TestContext 嫁接到 JUnit 4.4 测试框架上所提供的两个抽象测试用例类。

Spring 的 TestContext 测试框架不但可以整合到 JUnit 4.4 测试框架上,而且还可以整合到 JUnit 3.8 以及 TestNG 等测试框架上。目前已经提供了对 JUnit 3.8 以及 TestNG 的支持,你可以分别在 org.springframework.test.context.junit38 和 org.springframework.test.context.testng 包下找到整合的帮助类。



参考资料

学习

获得产品和技术


关于作者

陈雄华照片

陈雄华,2002 年毕业于厦门大学计算机与信息工程学院,获硕士学位。是宝宝淘科技有限公司的创始人之一(http://www.baobaotao.com),这是一个服务于全国母婴用户的综合性网站,作者负责网站整体框架设计以及核心代码开发的工作。技术开发之余,常将经验所得行诸于文字,作者是国内多个著名技术网站的专栏作者,在各大技术网站、报刊杂志发表过数十篇技术文章,广受读者好评。于 2005 年出版《精通 JBuilder 2005》,于2007年出版《精通 Spring 2.x--企业应用开发详解》,其新作《EXT 2.x开发详解――AJAX和Web页面布局王者至尊》即将出版。


2009年5月13日星期三

eclipse 插件安装

eclipse 插件安装

Spring IDE for Eclipse在线安装网址:





http://springide.org/updatesite/

Ibator Automatic Eclipse Install

If you've already installed a
prior version of Ibator, simply run the Eclipse Update tool and the new
version will be found automatically.

If you've not previously installed Ibator, use the built in Eclipse install support by following these steps:

  1. Take the "Help>Software Updates..." Menu Option
  2. Select the "Available Software" Tab
  3. Press the "Add Site" button
  4. Enter the following information: Location:http://ibatis.apache.org/tools/ibator
  5. Press OK
  6. Check the box next to "Apache iBATIS Ibator Feature"
  7. Press the "Install" button
  8. Follow the remainder of the install wizard

Ibator Manual Eclipse Install

The automatic install is much
preferred, but you can also install Ibator manually if you desire. To
install manually, download the file IbatorForEclipse1.2.1.zip and unzip the file to some convenient location. After unzipping the update site archive, follow these steps in Eclipse:

  1. Take the "Help>Software Updates..." Menu Option
  2. Select the "Available Software" Tab
  3. Press the "Add Site" button
  4. Press the "Local" button
  5. Navigate to the location where you unzipped the site archive
  6. Press OK
  7. Check the box next to "Apache iBATIS Ibator Feature"
  8. Press the "Install" button
  9. Follow the remainder of the install wizard

2009年5月11日星期一

电饭煲蛋糕

电饭煲蛋糕

2005-12-12

材料:低筋面粉60g,糖60g,泡打粉约4g,牛奶30g,油30g,鸡蛋3个,醋几滴(忘了拍了,后来加上的)
   我没有秤和量杯,就用了普通的一次性杯子,125ml的作为测量工具,大家可以从图中看到大约的量,面粉3/4杯多,糖
  
  半杯多一点,泡打粉就是在面粉上面的小勺子里,牛奶1/4杯,油比重小于牛奶,所以大约有1/3杯
  
  8月2日修改:真是很对不起大家,我把一次性杯子的容量搞错了,应当是205ml的,但是我当时的用量的确是这个样子的,做出来感觉稍微油了一点点。

  

点击在新窗口中查看该图片












作者:白梨儿
  回复日期:2005-12-12 21:13:00




  蛋白和蛋黄分开,放到两个较大的无油无水的容器中,我用的是两个吃面的大碗,没有分蛋器,可以鸡蛋从中间打开,左右各
  
  倒手一次就行了,一定要小心,我今天就不小心弄破了一个蛋黄,结果虽然用勺子把它从蛋清中捞出来了,但是仅剩的一点残
  
  余还是让我今天打蛋比上次多费了不少力气
  看看这个破碎的蛋黄,旁边的碗里是蛋清,不太清楚
  

点击在新窗口中查看该图片





作者:白梨儿
  回复日期:2005-12-12 21:14:00




  把蛋黄,油,牛奶,1/3的糖搅拌均匀,有的说要打发,我也不清楚什么样就是打发了,就直接搅匀完事(左图)
  面粉要筛,但是我没有筛子,也就直接放进去了,分三次加入蛋黄中,轻快的搅匀(见右图),很多方子(比如狐狸的)中说
  
  不能搅拌,但是因为面粉没筛,和到一起后会有面疙瘩,我就用打蛋器搅了,不过也不是划圈的,是上下搅得
  

点击在新窗口中查看该图片





作者:白梨儿
  回复日期:2005-12-12 21:15:00




  接下来,最艰难的过程,打蛋清,因为今天犯了严重错误,打蛋时间比上次增加了一倍,上次用了20分,这次一边打一边看阿
  
  拉蕾,看了两集才打好,不过也是因为看动画片不专心的原因
  注意,打蛋清时候的打蛋器要干净,上一步如果用过,一定要洗干净吸干水分,我偷懒,是打完蛋清才和面粉的,呵呵,大家
  
  不要学我偷懒阿
  蛋清加醋达到起大泡的时候(左上),加剩余糖的1/3,打,再加1/3,打,再加1/3,打,到最后成了硬性发泡就可以了,初学者可
  
  能不知道什么是硬性发泡,我第一次也是很疑惑呢,所以就拍了一个软性发泡的(右上)和一个硬性发泡的(左下)给大家作
  
  个比较,就是用打蛋器挑一个尖角,角直立的才是硬性发泡
  

点击在新窗口中查看该图片





作者:白梨儿
  回复日期:2005-12-12 21:48:00




  然后把打好的的蛋清分三次倒入蛋黄面糊液中,轻快的搅拌均匀,就是这个样子了,
  做这一步之前可以先预热电饭锅了,并且在上面抹一点油,因为上次没抹油,最后有一点皮沾到锅上了,我这次抹了黄油,事
  
  实证明黄油不管用,下面就可以看到了
  把上一步做好的东东倒入电饭锅,按下加热档,等跳上去之后过半小时再开盖,这时候一定要有耐心,不能着急打开看,不然
  
  会塌下去成了一张大饼的
  当然不同的电饭锅用的时间不一样,我的电饭锅用的是慢煮档,平时要使做两个人吃的饭要用一个小时呢,大家可以参照不同
  
  情况自己试试看。
  
  最后,左上,在电饭锅里的样子,右上,倒扣出来,我的电饭锅是圆底的,美中不足,这时大家可以看到此次的金黄表皮全被锅沾住了,不可理解阿,希望大家
  
  以我为戒,左下,切开的(普通刀切的,不好),右下,掰开的细节

点击在新窗口中查看该图片



 步骤:
  原料:2个大碗   
   鸡蛋4个    
   蛋糕粉(偶用的是两小包)   
  
白砂糖(越细越好,用量差不多是汤勺6勺)   
   炼奶少许   
   黄油少许(因为没有黄油所以偶用的是橄榄油)   
  
纯牛奶4勺
  1、先将鸡蛋蛋白和蛋黄分开装到两个碗中。

  2、蛋黄里加入牛奶、少许橄榄油和两勺白糖,滴入3滴左右的白醋,放少许盐,打匀,并分几次放入蛋糕粉,搅成糊状。搅拌好后放入温水泡着备用。

  3、接下来就是最关键的也是最累人的活——打蛋清~~~。打蛋清时放入少许的盐,就好打多了,打蛋清的过程中要分三次加入白糖。接下来就是不停的打!打!打!直到把蛋清打成干性发泡,把筷子立在里面不倒就行啦。

  4、将打好的蛋清分三次倒入蛋黄面糊里,偶用电饭煲的塑料勺子从下到上搅拌均匀,不要搅拌,然后就成了偶需要的蛋糕糊大。

  5、在电饭煲里涂一层橄榄油,这样蛋糕成型时就比较容易脱膜。然后将蛋糕糊倒入电饭煲中,轻轻的敦几下就可以大。按电饭煲的煮饭档,约几分钟左右就跳到保温了,等过10分钟左右再按下煮饭档,几分钟后又跳到保温档,这时不能马上开盖,必须要等30分钟左右后再打开,这时你就可以看到漂亮的蛋糕啦.

2009年4月30日星期四

iBATIS的代码生成工具-iBATOR 试用

iBATIS的代码生成工具-iBATOR
发表时间:2008-06-24

前两天在javaeye上闲逛,无意间看到iBATIS也有代码生成的工具,这两天一直没抽着时间试试,今天利用15分钟时间试用了下,感觉还是不错的,很简单也很实用。

    iBATOR下载:http://ibatis.apache.org/ibator.html

它提供了多种格式的下载,大家有兴趣可以逐一下载研究,我用的是eclipse的插件。eclipse安装插件大家应该都明白了。呵呵

装完之后,新建一个Java
Project名为:Ibatis。工程建好好在此工程中新建配置文件:abatorConfig.xml。具体为:File-New-Abator For
iBATIS ConfigurationFile.
根据需要修改此文件。我的配置为:
<?xml version="1.0"
encoding="UTF-8" ?>
<!DOCTYPE abatorConfiguration PUBLIC "-//Apache
Software Foundation//DTD Abator for iBATIS Configuration 1.0//EN"
"http://ibatis.apache.org/dtd/abator-config_1_0.dtd" >

<abatorConfiguration >
  <abatorContext >
   
<jdbcConnection driverClass="org.gjt.mm.mysql.Driver"
connectionURL="jdbc:mysql://localhost:3306/fsc" userId="root"
password="password3401" >
      <classPathEntry
location="D:\mysql-connector-java-5.0.6-bin.jar" />
   
</jdbcConnection>
    <javaModelGenerator
targetPackage="test.model" targetProject="Ibatis\src" />
   
<sqlMapGenerator targetPackage="test.xml" targetProject="Ibatis\src" />

   
    <table schema="fsc" tableName="test" >
     
<generatedKey column="id" sqlStatement="MySQL" identity="true" />

      <columnOverride column="address" property="addr" />
   
</table>
  </abatorContext>
</abatorConfiguration>

到此,一切准备工作ok
下面生成model及各种配置文件。
在abatorConfig.xml文件上鼠标右键,“Generate
iBATIS Artifacts”即可。
这样会在你指定的路径下生成model文件。
唯一遗憾的是不支持annotiation。

总的来说感觉还是不错的。

官方文档:http://ibatis.apache.org/docs/tools/abator/
-------------------------------------------------------------------

Introduction to iBATOR


iBATOR is a code generator for iBATIS. iBATOR will introspect a database table (or many tables)
and will generate iBATIS artifacts that can be used to access the table(s). This
abates some of the initial nuisance of setting up objects and configuration
files to interact with database tables. iBATOR seeks
to make a major impact on the large percentage of database operations that are
simple CRUD (Create, Retrieve, Update, Delete). You will still need to hand code
SQL and objects for custom queries, or stored procedures.


iBATOR will generate:


  • SqlMap XML Files
  • Java Classes to match the primary key and fields of the table(s)
  • DAO Classes that use the above objects (optional)

iBATOR can run as a standalone JAR file, or as an
Ant task, or as an Eclipse plugin.


iBATOR is currently under development. The legacy
version (Abator) is still available. If you have suggestions for the future of
iBATOR, please feel free to send them to the Java
user's mailing list..


About the Name


iBATOR is an iBATIS stylized version of the English word "abator". Abator
means "one who abates a nuisance".


iBATOR
News


(April 14, 2008) Due to a trade registration dispute, Abator is renamed to
iBATOR. iBATOR is currently under development. The initial source code drop can
be checked out from SVN at
http://svn.apache.org/repos/asf/ibatis/trunk/java/tools/ibator/


(March 20, 2008) Updated Abator and the Eclipse plugin to version 1.1.0. This
is an extensive update that includes quite a few minor enhancements, two major
enhancements (two new methods can be generated), and a few bug fixes. See the
What's New? section of the online documentation for full details.


(August 20, 2006) Updated Abator and the Eclipse plugin to version 1.0.0.
This is an extensive update that includes many new features including the
ability to generate code for Java 5, generate different types of domain models,
and hugely improved "by example" methods. See the "What's New?" section of the
online documentation for full details.


iBATOR Development


iBATOR is currently under development. iBATOR will not be 100% compatible
with Abator, but will be very close. Known differences include:



Legacy
Abator Software Downloads and Documentation


Download the standalone JAR if you are using an IDE other than Eclipse. The
standalone JAR includes an Ant task to run Abator, or you can run Abator from
the command line of from Java code.



Documentation for the core functions of Abator is available online. This
documentation set is also included in the downloads, and is integrated into the
Eclipse help system if you are using the Eclipse plugin.


Documentation for the Eclipse specific features is integrated into the
Eclipse help system and is not available online.



Eclipse Plugin


When run as an Eclipse plugin, Abator will persist the generated Java classes
and SqlMap files in Eclipse projects. Abator can be run iteratively multiple
time as the database design matures - and any hand coded additions to generated
Java classes or SqlMap files will remain undisturbed.


Documentation for Abator is integrated into the Eclipse help system.


Requirements



Automatic Eclipse
Install


If you've already installed a prior version of Abator, simply run the Eclipse
Install/Update tool and the new version will be found automatically.


If you've not already installed Abator, then you can use the built in Eclipse
install support by following these steps:


  1. Take the "Help>Software Updates>Find and Install" Menu Option
  2. Select the "Search for new features to install" radio button, press "Next"
  3. Press the "New Remote Site" button
  4. Enter the following information: Name:Abator for Eclipse Update
    SiteURL:
    http://ibatis.apache.org/tools/abator
  5. Press OK
  6. Check the box next to "Abator for Eclipse Update Site"
  7. Follow the remainder of the install wizard

Manual Eclipse
Install


The automatic install is much preferred, but you can also install Abator
manually if you desire. To install manually, download the file
AbatorForEclipse1.1.0.zip and unzip the file to some convenient location. After
unzipping the update site archive, follow these steps in Eclipse:


  1. Take the "Help>Software Updates>Find and Install" Menu Option
  2. Select the "Search for new features to install" radio button, press "Next"
  3. Press the "New Local Site" button
  4. Navigate to the location where you unzipped the file.
  5. Press OK
  6. Follow the remainder of the install wizard


配置文件abatorConfig.xml示例


<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE
abatorConfiguration PUBLIC "-//Apache Software Foundation//DTD Abator for iBATIS
Configuration 1.0//EN"
 
"http://ibatis.apache.org/dtd/abator-config_1_0.dtd">


<abatorConfiguration>
  <abatorContext>    <!-- TODO: Add
Database Connection Information -->
    <jdbcConnection
driverClass="oracle.jdbc.driver.OracleDriver"
       
connectionURL="jdbc:oracle:thin:@192.168.0.17:1521/fcg"
       
userId="fcg"
        password="fcg">
      <classPathEntry
location="E:\Tomcat6.0\lib\ojdbc14-10.2.0.1.0.jar" />
   
</jdbcConnection>


     <javaTypeResolver >
      <property name="forceBigDecimals"
value="false" />
    </javaTypeResolver>


    <!--
    <javaModelGenerator targetPackage="abator"
targetProject="FCG\test">
      <property name="enableSubPackages"
value="true" />
      <property name="trimStrings" value="true"
/>
    </javaModelGenerator>


    <sqlMapGenerator targetPackage="abator" 
targetProject="FCG\test">
      <property name="enableSubPackages"
value="true" />
    </sqlMapGenerator>


    <daoGenerator type="SPRING" targetPackage="abator" 
targetProject="FCG\test">
      <property name="enableSubPackages"
value="true" />
    </daoGenerator>


    <table schema="fcg" tableName="users" domainObjectName="User"
>
       <property name="useActualColumnNames"
value="true"/>    
     
      <generatedKey column="ID"
sqlStatement="DB2" identity="true" />
      <columnOverride
column="DATE_FIELD" property="startDate" />
      <ignoreColumn
column="FRED" />
      <columnOverride column="LONG_VARCHAR_FIELD"
jdbcType="VARCHAR" />
    </table>-->
    <!-- 
-->
    <javaModelGenerator targetPackage="abator"
targetProject="FCG\test" />   
      <sqlMapGenerator
targetPackage="abator" targetProject="FCG\test" />   
    <daoGenerator
type="SPRING" targetPackage="abator" targetProject="FCG\test" />  
    
<!--
    <table tableName="USERS" />   
    <table
tableName="COMPONENTS" />   
    <table tableName="ROLES" /> 
   
<table tableName="RESOURCES" />-->
    <table
tableName="import_railroad_fee_check" />
 
</abatorContext>
</abatorConfiguration>


1下载插件for eclipse


2将配置文件放入src根目录


3更改数据库路径,ojbdc路径


4在test目录下建立abator目录


5 tableName修改为需要自动生成代码的表名


6 在配置文件上右键,会出现生成代码的选项


2009年4月11日星期六

基于XFire实施WS-Security

基于XFire实施WS-Security
http://www.builder.com.cn/2007/0530/405080.shtml

概述


Web Service是安全的吗?鉴于安全性涉及诸多方面(例如身份验证和授权、数据隐私和完整性等),而 SOAP 规范中根本没有提及安全性这一事实,所以我们不难理解人们为什么认为答案是否定的。


很少有不需要某种形式的安全性保证的企业级系统。在 Web Service中,处理Web Service安全的过程比处理其他领域应用的安全问题更为复杂,因为Web Service具有分布式、无状态的特性。


WS-Security是解决Web Service安全问题的规范,大多数商业的Java
EE应用服务器都实现了WS-Security规范,Apache
WSS4J是WS-Security的开源实现,WSS4J通过SOAP中WS-Security相关的信息对SOAP报文进行验证和签名,XFire通
过WSS4J对WS-Security提供了支持。你可以从http://ws.apache.org/wss4j了解更多关于WSS4J的信息。


认识WS-Security


2002 年 4 月,IBM、Microsoft 和 VeriSign 在他们的 Web 站点上提议建立 Web Services
Security
(WS-Security)规范。此规范包括安全凭证、XML签名和XML加密的安全性问题。此规范还定义了用户名凭证和已编码的二进制安全性凭证的格
式。


2002 年 6 月,OASIS 从 IBM、Microsoft 和 Verisign 接收到了提议的WS-Security安全性规范。不久之后就在 OASIS 成立了“Web Service 安全性技术委员会”(WSS TC)。


2006年2月15日,OASIS通过了WS-Security
1.1安全规范,1.1规范突出了对安全权标支持、消息附件和权限管理的增强。1.1规范包括WS-Security核心规范及用户名权标规范1.1、
X.509权标规范1.1、Kerberos权标规范1.1、SAML权标规范1.1、权限表达(REL)权标规范1.1、带附件的SOAP(SWA)规
范1.1和模式1.1。


也许读者会提出这样的问题:SSL也具有完整性和机密性,为什么还需要另外一个WS-Security规范呢?之所以要制定WS-Security规范,是SSL存在以下的问题:


  • 端对端的通信,脱离传输层就无法保证安全性;
  • 消息必须全部加密/或者全部签名,而不能针对消息的某部分,没有考虑XML处理。

SSL对应OSI的传输层,前面我们提到过Web Service是和传输层无关的,将安全问题依附在SSL上就违反了Web Serivce与传输层无关的原则。而WS-Security对应于OSI的应用层,建立消息层SOAP之上。


针对不同领域的细分问题,OASIS
在WS-Security的基础上又制定了几十个规范,其中包括WS-SecureConversation、WS-Federation、
WS-Authorisation、WS-Policy、WS-Trust、WS-Privacy等,形成了一个庞大Web
Service安全性协议家族。


基于XFire实施WS-Security(第一部分)


图1 WS-Security所在位置


有了WS-Security规范,用户就拥有在Web Service应用中实施完整性、机密性和身份验证等安全需求的规范方法。


XFire应用WS-Security的总体方案


XFire通过Apache的WSS4J对WS-Security提供支持,XFire完整发布包中包含了WSS4J的类包。我们知道XFire在
发送和接收SOAP报文前拥有多个阶段,每个阶段都可以注册Handler,对SOAP报文进行前置和后置处理的加工操作。XFire即通过
Handler实施WSS4J,当发送SOAP报文时,通过注册一系列OutHandler,对SOAP报文进行加密、签名、添加用户身份信息等后置处理
操作。而在接收SOAP报文时,则通过注册一系列的InHandler对SOAP进行解密、验证签名,用户身份认证等前置操作。


基于XFire实施WS-Security(第一部分)


图2 XFire应用WS-Security的方案


请求和响应的SOAP在发送之前可以通过注册的OutHanlder进行加工处理,让SOAP转换为WS-Security的保护格式。而服务端和
客户端的接收SOAP 报文之前,可以通过注册的InHandler,将WS-Security格式的SOAP转换正常的SOAP进行处理。


由于XFire在SOAP收发过程中定义了多个不同的生命阶段,所以可以在发送前和接收前完成SOAP报文安全处理的工作,这些操作完全独立于业务处理逻辑,实施WS-Security对于Web Service的业务操作是透明的。


使用WS-Security


在前面内容中,我们通过各种方式将BbtForum中的方法以BbtForumSerivice窄接口开放为Web
Service服务,但个Web Service是没有任何安全性可言的,任何拿到WSDL的人都可以轻松地构造客户端程序访问我们的Web
Service服务。在这节里,我们将解决这个问题,对BbtForumSerivice添加不同的安全功能。


准备工作


在使用XFire的WS-Security之前,必须做一些准备性的工作:包括搭建安全环境,创建密钥对和证书等内容。


安装Java策略文件


策略文件被JDK使用,用以控制加密的强度和算法。确认已经安装对应JDK 版本的Unlimited Strength
Jurisdiction策略文件,这是一个无限制的安全控制文件。你可以从http://java.sun.com/j2se/1.5.0
/download.jsp 或
http://java.sun.com/j2se/1.4.2/download.html页面的底部找到下载的链接。否则在使用WS-
Security时,可以会抛出java.security.InvalidKeyException: Illegal key size的错误信息。


策略文件包括local_policy.jar和US_export_policy.jar文件,将其拷贝到<JAVA_HOME>/jre/lib/security目录下。为了方便读者,我们在光盘resources/jce_policy-1_5_0拥有该策略文件的拷贝。


你也许会问:为何Sun不把它集成到JDK中去,而单独“损人不利己”地弄一个链接出来给人下载?这是因为每个国家,尤其是美国,对涉及密码的软件
产品控制非常严格,在美国国内,很多密码算法长度都作了限制,而且某些算法在某些国家没有申请专利,可以随意使用,而在某些国家却做了明确限制,不准使
用,因此Sun必须按照惯例行事。


安装SecurityProvider


WSS4J使用了BouncyCastle的SecurityProvider,所以需要事先在java.security文件中进行配置,否则运
行加密模式的XFire认证时,会抛出以下的出错信息:org.apache.ws.security.WSSecurityException:
An unsupported signature or encryption algorithm was used unsupported
key


在java.security文件中(位于<JAVA_HOME>/jre/lib/security目录中)添加BouncyCastleProvider的配置:



security.provider.1=sun.security.provider.Sun


security.provider.2=sun.security.rsa.SunRsaSign


security.provider.3=com.sun.net.ssl.internal.ssl.Provider


security.provider.4=com.sun.crypto.provider.SunJCE


security.provider.5=sun.security.jgss.SunProvider


security.provider.6=com.sun.security.sasl.Provider


security.provider.7=org.bouncycastle.jce.provider.BouncyCastleProvider



XFire发布包中包含了BouncyCastle SecurityProvider的类包,位于<XFIRE_HOME>/lib
/bcprov-jdk15-133.jar下。必须将bcprov-jdk15-133.jar加入到类路径中。你可以在http:
//docs.safehaus.org/display/PENROSE/Installing+Security+Provider中获取更多关于安
装BouncyCastle SecurityProvider的帮助。


创建密钥对和数字证书


签名和加密需要使用到数字证书和密钥对,可以使用JDK提供的KeyTool工具创建密钥对和数字证书。我们分别为服务端和客户端创建RSA密钥
对,并生成各自的X509数字证书(包含公钥和数字签名)。服务端和客户端拥有各自的密钥库JKS文件,服务端的密钥库保存服务端的密钥对和客户端的数字
证书,而客户端的密钥库保存客户端的密钥对和服务端的数字证书。


下面,我们来完成创建服务端和客户端密钥库的工作:


  • 编写一个用于创建RSA密钥对和generateKeyPair.bat批处理文件:

rem @echo off


#接受参数


echo alias %1


echo keypass %2


echo keystoreName %3


echo KeyStorePass %4


echo keyName %5


①创建RSA密钥对


keytool -genkey -alias %1 -keypass %2 -keystore %3 -storepass %4-dname "cn=%1" -keyalg RSA


keytool -selfcert -alias %1 -keystore %3 -storepass %4 -keypass %2 ②使用私钥进行自签名


keytool -export -alias %1 -file %5 -keystore %3 -storepass %4 ③导出数字证书


  • 编写一个使用generateKeyPair.bat创建服务端和客户端的密钥库的generateKeyStore.bat批处理文件:

①下面两行命名分别调用generateKeyPair.bat批处理文件为服务端和客户端生成密钥对


call generateKeyPair.bat server serverpass serverStore.jks storepass serverKey.rsa


call generateKeyPair.bat clientclientpassclientStore.jks storepass clientKey.rsa


②将服务端的数字证书导入客户端的密钥库


keytool -import -alias server -file serverKey.rsa -keystore clientStore.jks -storepass storepass -noprompt


③将客户端的数字证书导入服务端的密钥库


keytool -import -alias client -file clientKey.rsa -keystore serverStore.jks -storepass storepass -noprompt


运行该批处理文件后,将分别为服务端和客户端生成一个Java密钥库文件,它们分别拥有一个自己的密钥对和对方的数字证书。我们通过表1对两者密钥库文件的内容进行说明:


1密钥库说明






























服务端Java密钥库


客户端Java密钥库


对应密钥库文件


serverStore.jks


clientStore.jks


密钥库密码


storepass


storepass


库中包含的内容


server密钥对、client数字证书


client密钥对、server数字证书


密钥对别名


server


client


密钥对私钥的保护密码


serverpass


clientpass


  • 将serverStore.jks和clientStore.jks拷贝到<工程目录>/src/META-INF/xfire的目录下,以便后面的实例代码使用。



2009年4月9日星期四

如何正确地在Axis、Axis2和Apache CXF之间抉择?


2007-09-30


新一代的 Web Services 框架如 Axis2、CXF 都是由现有的项目中逐渐演化而来的,Axis2 是由大家熟悉的 Axis 1.x 系列演化过来,而 Apache CXF 则是由 Celtix 和 XFire 项目整合而生,并且刚刚发布了 2.0.2 的最新版本,不过仍是 Apache 的一个孵化项目。



Axis2 是对 Axis 进行了彻底的重写的一个新项目了,它使用了新的模块化架构,更方便于功能性的扩展等等。

Apache CXF 则是由 XFire 和 Celtix 两个现有的项目进行了重组。



问题:如果现有的应用程序是基于 Axis 1.x、XFire 或者 Celtix 的话,那应该怎么办?都迁移到这些新的框架上去吗?但是即使是要迁移,那应该迁移到哪个框架上去呢?

如果是编写一个新的 Web Services 应用程序的话,就不存在迁移的问题了,但是哪个框架是你应当选择进行使用的呢?哪个比哪个更好呢?



对于现在的应用程序的迁移,如果你的应用程序是稳定而成熟的,并且在可预知的未来的情况下,只要很少的一些需求变更要做的话,那么保存你的体力,不要去做“劳民伤财“的迁移工作了。

如果你的现有应用程序BUG缠身,性能,功能等等都一片糟糕的话,那就要考虑迁移了,那选哪个框架呢?先比较一下它们的不同之处:



  1、Apache CXF 支持 WS-Addressing、WS-Policy、WS-RM、WS-Security和WS-I BasicProfile

  2、Axis2 支持 WS-Addressing、WS-RM、WS-Security和WS-I BasicProfile,WS-Policy将在新版本里得到支持

  3、Apache CXF 是根据Spring哲学来进行编写的,即可以无缝地与Spring进行整合

  4、Axis2 不是

  5、Axis2 支持更多的 data bindings,包括 XMLBeans、JiBX、JaxMe 和 JaxBRI,以及它原生的 data binding(ADB)。

  6、Apache CXF 目前仅支持 JAXB 和 Aegis,并且默认是 JAXB 2.0,与 XFire 默认是支持 Aegis 不同,XMLBeans、JiBX 和 Castor 将在 CXF 2.1 版本中得到支持,目前版本是 2.0.2

  7、Axis2 支持多种语言,它有 C/C++ 版本。

  8、Apache CXF 提供方便的Spring整合方法,可以通过注解、Spring标签式配置来暴露Web Services和消费Web Services



如何抉择:

1、如果应用程序需要多语言的支持,Axis2 应当是首选了;

2、如果应用程序是遵循 Spring 哲学路线的话,Apache CXF 是一种更好的选择,特别对嵌入式的 Web Services 来说;

3、如果应用程序没有新的特性需要的话,就仍是用原来项目所用的框架,比如 Axis1,XFire,Celtrix 或 BEA 等等厂家自己的 Web Services 实现,就别劳民伤财了。

Axis和CXF的比较

Axis和CXF的比较


在SOA领域,我们认为Web Service是SOA体系的构建单元(building
block)。对于服务开发人员来说,AXIS和CXF一定都不会陌生。这两个产品都是Apache孵化器下面的Web Service开源开发工具。
Axis2的最新版本是1.3.CXF现在已经到了2.0版本。

这两个框架
都是从已有的开源项目发展起来的。Axis2是从Axis1.x系列发展而来。CXF则是XFire和Celtix项目的结合产品。Axis2是从底层全
部重新实现,使用了新的扩展性更好模块架构。 CXF也重新的深化了XFire和Celtix这两个开发工具。


新产品的退出导致了几个问题。是不是现有的使用Axis
1.x,XFire和Celix的应用需要迁移的新的版本上。如果一个开发人员确定要迁移它的应用到新的框架上,那么他应该选择哪一个呢?相反的,如果一
个开发者决定从头开发一个新的Web Service,他应该使用哪个呢? 这两个框架哪一个更好一些呢?


对于系统迁移来说,也许迁移到新的框架并不难。Axis和CXF都提供了迁移的指导。能够给开发者一些迁移的技巧和经验。但是对于这样迁移,这两个开源项
目都没有提供迁移的工具。对于这样的迁移工作,尽管很值得去寻找所有的可行方案。Axis2和CXF都有各自不同的WebService开发方法,每个方
法都有相当数量拥护者。

通过一个比较矩阵来比较Axis2和CXF变得有现实的意义。这两个项目都开发不够成熟,但是最主要的区别在以下几个方面:

1.CXF支持 WS-Addressing,WS-Policy, WS-RM, WS-Security和WS-I Basic Profile。Axis2不支持WS-Policy,但是承诺在下面的版本支持。

2. CXF可以很好支持Spring。Axis2不能

3. AXIS2支持更广泛的数据并对,如XMLBeans,JiBX,JaxMe和JaxBRI和它自定义的数据绑定ADB。注意JaxME和JaxBRI都还是试验性的。CXF只支持JAXB和Aegis。在CXF2.1

4. Axis2支持多语言-除了Java,他还支持C/C++版本。


比较这两个框架的Web Service开发方法与比较它们的特性同样重要。 从开发者的角度,两个框架的特性相当的不同。
Axis2的开发方式类似一个小型的应用服务器,Axis2的开发包要以WAR的形式部署到Servlet容器中,比如Tomcat,通过这些容器可以对
工作中的Web Service进行很好的监控和管理。Axis2 的Web
administrion模块可以让我们动态的配置Axis2.一个新的服务可以上载,激活,使之失效,修改web服务的参数。管理UI也可以管理一个或
者多个处于运行状态的服务。这种界面化管理方式的一个弊端是所有在运行时修改的参数没有办法保存,因为在重启动之后,你所做的修改就会全部失效。


Axis2允许自己作为独立的应用来发布Web Service,并提供了大量的功能和一个很好的模型,这个模型可以通过它本身的架构(modular
architecture)不断添加新的功能。有些开发人员认为这种方式对于他们的需求太过于繁琐。这些开发人员会更喜欢CXF。


CXF更注重开发人员的工效(ergonomics)和嵌入能力(embeddability)。大多数配置都可以API来完成,替代了比较繁琐的XML
配置文件, Spring的集成性经常的被提及,CXF支持Spring2.0和CXF's
API和Spring的配置文件可以非常好的对应。CXF强调代码优先的设计方式(code-first
design),使用了简单的API使得从现有的应用开发服务变得方便。


不过你选择Axis2还是CXF,你都可以从开源社区得到大量的帮助。这两个框架都有商业公司提供服务,WSO2提供AXIS2的支持,Iona提供
CXF的支持。这两公司都有很活跃的开发者社区。
Axis2出现的时间较早,CXF的追赶速度快。我的建议是:如果你需要多语言的支持,你应该选择AXIS2。如果你需要把你的实现侧重JAVA并希望和
Spring集成,CXF就是更好的选择,特别是把你的Web
Service嵌入其他的程序中。如果你觉得这两个框架的新特性对于你并没有太大的用处,你会觉得Axis1也是不错的选择,你应该继续使用它知道你有充
分的理由去更换它。

2009年4月5日星期日

究竟什么是POJO?






究竟什么是POJO?


http://www.diybl.com/course/3_program/java/javashl/200845/108451.html


      POJOPlain Old Java Object)这种叫法Martin FowlerRebecca ParsonsJosh MacKenzie2000年的一次演讲的时候提出来的。
     
我在做J2EE培训中发现我的很多学生问我什么是POJO,后来我在写书(《Spring2初学者实践教材》和《Spring3初学者实践教材》)的时候
发现POJO这个概念无法回避。现在网上对于POJO的解释很多,但是很多都是有错误的或者不够准确。对此我一开始也是存在误区的,我原来是这样理解的:
        POJO是这样的一种“纯粹的”JavaBean,在它里面除了JavaBean规范的方法和属性没有别的东西,即private属性以及对这个属性方法的publicgetset方法。我们会发现这样的JavaBean很“单纯”,它只能装载数据,作为数据存储的载体,而不具有业务逻辑处理的能力。
    所以下面的代码被认为是POJO了。

package com.tongking.spring;

public class DbHello implements Hello {

       private DictionaryDAO dao;

       public void setDao(DictionaryDAO dao) {

              this.dao = dao;

       }

}

        其实,这样的认为是错误的,我仔细阅读了《POJOs in Action》这本书的有关部分和
POJO的最原始的出处http://martinfowler.com/bliki/POJO.html,
   
    The term was coined while Rebecca Parsons, Josh MacKenzie and I
were preparing for a talk at a conference in September 2000. In the
talk we were pointing out the many benefits of encoding business logic
into regular java objects rather than using Entity Beans. We wondered
why people were so against using regular objects in their systems and
concluded that it was because simple objects lacked a fancy name. So we
gave them one, and it''s caught on very nicely.

基本的意思是我们要给具有业务逻辑处理的规则的Java对象(regular java objects)起了一个名字——POJO,这些Java对象不是EntityBeans(EJB的一种)。

        我又在http://www.webopedia.com/TERM/P/POJO.htm查到解释如下:

POJO, or Plain Old Java Object, is a normal Java object class (that is, not a JavaBean,
EntityBean etc.)  and does not serve any other special role nor does it
implement any special interfaces of any of the Java frameworks. This
term was coined by Martin Fowler, Rebbecca Parsons and Josh MacKenzie
who believed that by creating the acronym POJO, such objects would have
a "fancy name", thereby convincing people that they were worthy of use.
        基本意思是说POJO一个正规的Java对象(不是JavaBean,EntityBean等),也不担当任何的特殊的角色,也不实现任何Java框架指定的接口。
   
   
我觉得上面的解释很准确,POJO应该不是我们开始认为的JavaBean,当然更不是EJB,它不应该依赖于框架即继承或实现某些框架类或接口。例
如:Struts1中的Action和ActionForm当然不属于POJO了,而在Struts2中的Action由于可以不继承任何的接口,所以在
这种情况下Action是POJO,但是Struts2中的Action也可以继承ActionSupport类就不再属于POJO了。POJO里面是可
以包含业务逻辑处理和持久化逻辑,也可以包含类似与JavaBean属性和对属性访问的set和get方法的。
       最后,我们总结一下给一个定义把,POJO是一个简单的、正规Java对象,它包含业务逻辑处理或持久化逻辑等,但不是JavaBean、EntityBean等,不具有任何特殊角色和不继承或不实现任何其它Java框架的类或接口。


2009年4月2日星期四

金钱草

  • 金钱草

  • 【金钱草的功效介绍】:

    【中文名】金钱草(《纲目拾遗》)


    【类 别】全草类


    【异名】遍地香(《祝穆试效方》),地钱几(《救荒野谱》),钹儿草(《救生苦海》),连钱草(《质问本草》),铜钱草(《慈航活人书》),白耳
    草、乳香藤、九里香、半池莲、千年冷、遍地金钱(《纲目拾遗》),金钱艾(《本草求取》),马蹄草、透骨消(《植物名实图考》),透骨风,过墙风、巡骨风
    (《分类草药性》),蛮子草(《天宝本草》),胡薄荷(《现代实用中药》),穿墙草(《经效实验单方》),团经药、风草(《贵州民间方药集》),肺风草、
    金钱薄荷、十八块草(《福建民间草药》),江苏金钱草(《中药通报》5(1):27,1959),透骨草、一串钱(《民间常用草药汇编》),四方雷公根、
    钱凿草、钱凿王(《陆川本草》),大叶金钱草、野薄荷(《江西民间草药》),马蹄筋骨草、破铜钱(《四川中药志》)。
       


    【来源】为唇形科植物活血丹的全草或带根全草。
       


    【植物形态】活血丹(《植物名实图考》)
    多年生草本。
       根茎短。
       茎细,具四棱,上升或直立,通常单一,基部带紫色,被细毛。
       叶对生;叶柄较长;叶片肾状心形、圆状心形或心形,长达2.5厘米,宽与长略相等,先端钝或稍尖,边缘具圆齿,被细毛,下面有透明腺点。
       花腋生,2至数朵;萼筒状,被刺毛,具5齿,先端芒状尖突;花冠淡紫色,筒状漏斗形,长约18~25毫米,花冠管狭长,为萼的2~3倍长,外面被细毛,先端2唇形,喉部膨大,上唇近平坦,下唇3裂;雄蕊4,2强,花丝顶端2歧;子房4裂,柱头2歧。
       小坚果,长圆形,平滑。
       花期5月。
       果期6月。
       
    生于阔叶林间、灌丛、河畔、田野、路旁。
       分布东北、华北、华东等地。
       


    【采集】4~5月采收,晒干。
       


    【药材】干燥全草多皱缩成团,茎细长,方形,常扭曲,具纵棱线,灰绿色或微带紫色,有短毛,断面中空。
       叶多卷缩,肾形或心形,边缘具圆钝齿,灰绿色,质脆易碎。
       叶柄长4~44毫米,多扭曲。
       花、果通常不见。
       气微香,味辛凉。
       
    主产江苏、广东、四川、广西。
       此外,浙讧、湖南、福建等地亦产。
       

    各地称金钱草供药用的植物,除本种外尚有下列几种:

    ①报春花科过路黄,详大金钱草条。
       

    ②旋花科马蹄金,详小金钱草条。
       

    ③伞形科白毛天胡荽和天胡荽,详江西金钱草条。
       

    ④豆科金钱草,详广东金钱草条。
       


    【化学成分】金钱草有芳香型和非芳香型两类。
       芳香型含多量单萜酮,其主要成分是l-蒎莰酮、l-薄荷酮和l-胡薄荷酮;尚含α-蒎烯、β-蒎烯、柠檬烯、对-聚伞花素、异薄荷酮、异蒎莰酮、芳樟醇、薄荷醇、α-松油醇。
       除上述挥发油成分外,尚含熊果酸、β-谷甾醇、棕榈酸、琥珀酸、多种氨基酸、鞣质、苦味质、胆碱、硝酸钾等。
       地下部分含水苏糖。
       


    【药理作用】用金钱草煎剂20克(生药)/公斤给大鼠灌胃,有显著的利尿作用,连续应用则利尿作用逐渐降低。
       在麻醉家兔的急性试验中,以10克(生药)/公斤灌胃,也有明显的利尿作用,这与其所含之灰分或钾盐有关,是否尚有其它有效成分,尚待研究。
       其酊剂无利尿作用。
       对猫、大鼠无利胆作用,对肝胆疾患的良好影响,可能与其所含的游离氨基酸有关。
       

    本品毒性很低,煎剂给大鼠灌胃,每天20克/公斤,共用6天,并未死亡,犬1次灌胃100克,对血压无大影响。
       


    【性味】苦辛,凉。
       

    ①《纲目拾遗》:味微甘,性微寒。
       

    ②《岭南采药录》:味涩,气香,性平。
       

    ③《现代实用中药》:苦,寒。
       


    【功用主治-金钱草的功效】清热,利尿,镇咳,消肿,解毒。
       治黄疸,水肿,膀胱结石,疟疾,肺痈,咳嗽,吐血,淋浊,带下,风湿痹痛,小儿疳积,惊痫,痈肿,疮癣,湿疹。
       

    ①《百草镜》:治跌打损伤,疟疾,产后惊风,肚痈,便毒,痔漏;擦鹅掌风;汁漱牙疼。
       

    ②王安卿《采药志》:发散头风风邪。
       治脑漏,白浊热淋,玉茎肿痛,捣汁冲酒吃。
       

    ③《纲目拾遗》:去风散毒。
       煎汤洗一切疮疥。
       

    ④《本草求原》:祛风湿,止骨痛。
       浸酒舒筋活络,止跌打闪伤(痛),取汁调酒更效。
       

    ⑤《植物名实图考》:治吐血、下血。
       

    ⑥《中国植物图鉴》:可作强壮剂。
       治慢性肺炎。
       

    ⑦《现代实用中药》:解热,镇咳,止渴,止血,利尿。
       治小儿痫热,疳病,瘰疬;研汁点暴赤眼;以盐揉贴肿毒并风癣。
       

    ⑧《安徽药材》:治膀胱结石。
       

    ⑨《民间常用草药汇编》:鲜草捣汁外敷撑耳寒(腮腺炎)。
       

    ⑩《陆川本草》:消肿止痛,破积。
       治妇人小腹痛。
       

    ⑾《贵阳民间药草》:治红崩带下,肺结核。
       

    ⑿《浙江民间草药》:治高血压。
       

    ⒀《四川中药志》:治风湿麻木,筋骨疼痛,黄疸,肺痈。
       


    【用法与用量】内服:煎汤,3~5钱(鲜者1~2两);或浸洒,捣汁。
       外用:捣敷或绞汁涂。
       


    【宜忌】《福建民间草药》:凡阴疽诸毒,脾虚泄泻者,忌捣汁生服。
       


    【选方】①治黄疸、臌胀:连钱草七至八钱,白茅根、车前草各四至五钱,荷包草五钱。
       共煎服。
       (《浙江民间草药》)

    ②治肾炎水肿:连钱草、萹蓄草各一两,荠菜花五钱。
       煎服。
       (《上海常用中草药》)

    ③利小便,治膀胱结石:连钱草、龙须草、车前草各五钱。
       煎服。
       (《浙江民间草药》)

    ④治疟疾:㈠疟发前用连钱草七叶为丸塞鼻中。
       (《质问本草》)

    ㈡连钱草一两五钱至三两。
       水煎,分两次服,每日一剂,连服三天。
       (《单方验方调查资料选编》)

    ⑤治伤风咳嗽:鲜连钱草五至八钱(干的三至五钱)(洗净),冰糖半两。
       酌加开水,炖一小时,日服二次。
       (《福建民间草药》)

    ⑥治胎咳、子肿:团经药、尖惊药、大苋菜、花蝴蝶各三至五钱。
       炖肉或鸡吃。
       

    ⑦治白带:团经药五钱,杜仲三钱,木通一钱五分。
       煎水加白糖服。
       

    ⑧治月经不调,小腹作胀:团经药、对叶莲各三钱,大叶艾二钱。
       泡酒吃。
       

    ⑨治风湿性关节炎:团经药,捶绒酒炒热,外敷。
       (⑥方以下出《贵阳民间药草》)

    ⑩治小儿疳积:连钱草三钱,加动物肝脏适量,炖汁服。
       (《上海常用中草药》)

    ⑾治疮疖、腮腺炎、皮肤撞伤青肿:鲜连钱草捣烂外敷。
       (《上海常用中草药》)

    ⑿治白虎丹:鲜车前草、遍地香。
       洗净捣烂,少加白酒,绞取汁,鹅毛蘸搽患处。
       (《祝穆试效方》)

    ⒀治湿疹、脓庖疮。
       稻田皮炎:鲜连钱草、野菊花各半斤。
       加水煮沸,乘热反复擦洗患处(有脓疱者必须挑破脓疱),再用痱子粉或牙粉撒布溃破处,每天一次。
       如三次见效不显,可加木槿皮或叶半斤同煎洗。
       (《江苏省中草药新医疗法展览资料选编》)

    ⒁治疮疥:钹儿草,加盐少许,搓熟频擦,全化,然后洗浴。
       若用煎冼,反不见效。
       (《救生苦海》)

    ⒂治蛇咬:连钱草生药鲜吃,并捣烂敷伤口。
       (《浙江民间草药》)


    【临床应用】①治疗腮腺炎
    将连钱草洗净,加少量食盐捣烂,敷于肿处,不论一侧或两侧腮腺肿大,均须两侧同时敷药。
       治疗50例,全部治愈;腮腺肿大消退及体温下降平均为12小时。
       

    ②治疗烧伤
    新鲜连钱草1把,洗净,用较厚的黄草纸包2~3层,水中浸湿后置旺火中烤熟,约20~30分钟取出,去纸,乘热将药草揉烂绞汁,盛于杯中,用消毒鸭毛蘸药
    汁涂搽伤面,每天搽数次至数十次,以保持伤面湿润为度;伤势严重的,药汁中加入适量冰片或麝香(研成细粉),可加速痊愈(但加麝香每易遗留瘢痕);如创面
    感染化脓,须先经清洗消毒处理,然后搽药。
       治疗Ⅱ、Ⅲ度烧伤30例,烧伤面积1~30%不等,其中已感染化脓者17例,引起全身症状者3例。
       结果均治愈,且无功能障碍。
       制药时要注意掌握火候,药草既要充分烤熟,但亦不能烤焦,否则将无法绞汁。
       治疗时创面要暴露,不能覆盖,也不能和其它药物混合施治;涂药汁时最好用鸭毛,如用棉花,其纤维每易脱落,可能影响创面愈合。
       在治疗期间,忌食豆荚、丝瓜、鸡蛋、鱼类等食物。

金钱草为蓼科金钱草属植物,亦称"过路黄"、"大金钱草"等,为临床常用中药,是治疗胆、肾和膀胱结石症的首选药物.本品已在临床上广泛应用,但由于历史
原因及各地的用药习惯不同,同名异物者较多,四川的金钱草又名大金钱草,为正品.小金钱草为旋花科马蹄金属植物马蹄金.江苏和上海一带的金钱草为唇形科连
钱草属植物连钱草.广东、广西的金钱草为豆科山蚂蟥属植物广金钱草.江西的金钱草为伞形科天胡荽属植物天胡荽.此外,有的地区尚有以伞形科积雪草属植物积
雪草的全草称金钱草者.上述诸药,其药效相似,但又有不同,一般认为治疗肝胆结石以过路黄疗效为佳,治疗泌尿系结石,以连钱草较好.





按照人体器官24小时工作表作息






按照人体器官24小时工作表作息可养生长寿

  月有阴晴圆缺,人体的机能状态在一天24小时里同样有规律可循。中国中医科学院西苑医院杨力教授通过媒体介绍了人体器官24小时工作表。



  1∶00 人体进入浅睡阶段,易醒。此时头脑较清楚,熬夜者想睡反而睡不着。



  2∶00 绝大多数器官处于一天中工作最慢的状态,肝脏却在紧张工作,生血气为人体排毒。



  3∶00 进入深度睡眠阶段,肌肉完全放松。



  4∶00 "黎明前的黑暗"时刻,老年人最易发生意外。血压处于一天中最低值,糖尿病病人易出现低血糖,心脑血管患者易发生心梗等。



  5∶00 阳气逐渐升华,精神状态饱满。



  6∶00 血压开始升高,心跳逐渐加快。高血压患者得吃降压药了。



  7∶00 人体免疫力最强。吃完早饭,营养逐渐被人体吸收。



  8∶00 各项生理激素分泌旺盛,开始进入工作状态。



  9∶00 适合打针、手术、做体检等。此时人体气血活跃,大脑皮层兴奋,痛感降低。



  10∶00 工作效率最高。10∶00-11∶00属于人体的第一个黄金时段。心脏充分发挥其功能,精力充沛,不会感到疲劳。



  12∶00 紧张工作一上午后,需要休息。12∶00-13∶00是最佳"子午觉"时间。不宜疲劳作战,最好躺着休息半小时至一小时。

  14∶00 反应迟钝。易有昏昏欲睡之感,人体应激能力降低。



  15∶00 午饭营养吸收后逐渐被输送到全身,工作能力开始恢复。15∶00-17∶00为人体第二个黄金时段。最适宜开会、公关、接待重要客人。



  16∶00 血糖开始升高,有虚火者此时表现明显。阳虚、肺结核等患者的脸部最红。



  17∶00 工作效率达到午后时间的最高值,也适宜进行体育锻炼。



  18∶00 人体敏感度下降,痛觉随之再度降低。



  19∶00 最易发生争吵。此时是人体血压波动的晚高峰,人们的情绪最不稳定。



  20∶00 人体进入第三个黄金阶段。记忆力最强,大脑反应异常迅速。20∶00-21∶00适合做作业、阅读、创作、锻炼等。



  22∶00 适合梳洗。呼吸开始减慢,体温逐渐下降。最好在十点半泡脚后上床,能很快入睡。



  23∶00 阳气微弱,人体功能下降,开始逐渐进入深度睡眠,一天的疲劳开始缓解。



  24∶00 气血处于一天中的最低值,除了休息,不宜进行任何活动。



麻疹

麻疹


概述
麻疹是由麻疹病毒引起的急性呼吸道传染病。临床特征为发热、流涕、咳嗽、眼结合膜炎、口腔粘膜斑及全身皮肤斑丘疹。
进入麻疹专题


病因
   (一)传染源:患者为唯一传染源。一般认为出疹前后5天均有传染性。
   (二)传播途径:患者咳嗽、喷嚏时,病毒随飞沫排出,直接到达易感者的呼吸道或眼结合膜而致感染。间接传播很少。
   (三)易感人群:未患过麻疹,也未接种麻疹疫苗者均为易感者。病后有较持久的免疫力。


症状
    潜伏期为10~14天。本病典型经过分三期。
   (一)前驱期:又称出疹前驱期,持续2~4天,但体弱,重症或滥用退热剂者可延至7~8天。主要表现为上呼吸道炎症,急起发热,咳嗽、流涕、喷嚏、畏光流泪,结膜充血、眼睑浮肿。咳嗽逐日加重。少数病人病初1~2日在颈、胸、腹部出现风疹样或猩红热样皮疹或荨麻疹,数小时即退,称为前驱疹。此时在悬雍垂、扁桃体、咽后壁、软腭处亦可见到红色斑点,出疹期才消退。
   (二)出疹期:于第4病日左右开始出疹,一般持续3~5天。皮疹首先开始耳后发际,渐及前额、面颈、躯干与四肢,待手脚心见疹时,则为“出齐”或“出透”。皮疹初为稀疏淡红色斑丘疹,直径2--4mm,逐渐皮疹增多,融合呈卵园形或不规则形,疹间可见正常皮肤,皮疹出透后转为暗棕色。病情严重时,皮疹可突然隐退。
    本期全身中毒症加重,体温高达40℃,精神萎糜、嗜睡,有时谵妄抽搐。面部浮肿,皮诊,眼分泌物增多,甚至粘连眼睑不易睁开,流浓涕,上述表现之面貌称为麻疹面容。
   (三)恢复期:皮疹出齐后,中毒症状明显缓解,体温下降,约1~2日降至正常。精神食欲好转,呼吸道炎症迅速减轻,皮疹按出疹顺序消退并留有糠麸样细小脱屑及淡褐色色素沉着,以驱干为多,1~2周退净。若无并发症的典型麻疹全程10~14天。


检查
    1.鼻咽部、眼分泌物或尿沉渣涂片染色查找多核巨细胞(含核5~80个)。前驱期及出疹期均可发现,出疹前2日阳性率最高,有早期诊断价值,尿沉渣镜检可发现单核细胞浆内包涵体。
    2.荧光抗体染色检查:取鼻、咽、眼分泌物及尿沉淀物涂片,以荧光抗体染色,可在脱落细胞内查及麻疹病毒抗原,阳性率更高。有早期诊断价值。
    3.血清学检查:用酶联免疫吸附试验或免疫荧光技术检测病人血清抗麻疹IgM;以血凝抑制试验,中和试验,补体结合试验检测麻疹抗体IgG,急性期和恢复期血清呈4倍升高,均有诊断价值。


治疗
   (一)一般治疗及护理:
    1.呼吸道隔离 患者应在家隔离、治疗至出疹后5天。有并发症患者应住院隔离治疗,隔离期延长5天。
    2.保持室内温暖及空气流通,给予易消化营养丰富的流质或半流质饮食,水分要充足;保持皮肤及眼、鼻、口、耳的清洁,用温热水洗脸,生理盐水漱口;用抗生素(红霉素)眼膏或(氯霉素,诺氟沙星)眼药水保护眼睛,防止继发感染。
   (二)对症治疗。
   (三)并发症治疗:
    1.肺炎。
    2.喉炎。
    3.心血管功能不全。


预防女人最容易长的5种斑






预防女人最容易长的5种斑


文章来源:www.9939.com    录入时间:2008-09-19 16:16:35


    女人长斑的主要原因是紫外线照射、内分泌失调、遗传因素,此外还与氧自由基、微量元素的含量、局部微生态环境、
化妆品、光毒性药物、抗癫痫药等有关。



    紫外线相关性皮肤病


  黄褐斑


  黄褐斑亦称“肝斑”、“蝴蝶斑”,多发于面、额、鼻、唇周部位,常左右对称,好发于妇女。主要原因是紫外线照射、内分泌失调、遗传因素,此外还与氧自由基、微量元素的含量、局部微生态环境、
化妆 品、光毒性药物、抗癫痫药等有关。


  预防宝典:


  1、不要长时间在阳光下暴晒,外出时对暴露部位涂防晒霜。


  2、如果怀疑黄褐斑是某些药物及化妆品引起的,应该停用。


  3、避免服用光敏性药物:如避孕药、治疗高血压、冠心病的抗血压药物、非甾体类消炎药、利尿剂和一些抗生素等。


  4、多吃新鲜水果蔬菜:如芹菜、黄花菜、黑木耳、藕、苹果、梨、西瓜等。


  5、少食辛辣等刺激性食物:如咖啡、可可、葱蒜、桂皮、辣椒、花椒等。


  雀斑


  “雀斑”是常见于面部特别是鼻部及眼眶下的棕色点状色素沉着斑。紫外线照射、内分泌失调、长期压力过大及新陈代谢紊乱可促发本病。夏季由于紫外线照射可使其加重。


  预防宝典:


  1、户外活动时应戴上遮阳用具,涂抹防晒霜。


  2、注意劳逸结合,避免过度紧张。


  3、多吃西红柿。因为西红柿中含有丰富的谷胱甘肽,谷胱甘肽可抑制黑色素,从而使沉着的色素减褪或消失。


  日光性皮炎


  俗称“晒斑”,其表现为暴晒后数小时内暴露部位的皮肤出现水肿性红斑,可起水疱,多伴有烧灼感、痒感或刺痛。轻者数天后皮疹逐渐消褪;重者可伴有类感冒症状,如发烧、乏力、全身不适等,约一周左右即可恢复。肤色浅者易患此病,以女性较多见。


  预防宝典:


  1、避免在阳光下长时间暴晒;室外活动时,要戴遮阳帽,穿长衣衫。


  2、避免光感食物如泥螺、苋菜、荠菜、芥菜、马兰头、菠菜、莴苣、木耳、荞麦等。


  3、多食新鲜果蔬,因为维生素C和B12能阻止和减弱对紫外光的敏感,并促进黑色素的消褪,且可恢复皮肤的弹性。


  高温导致的皮肤病


  痱子


  痱子一般可分为红痱和白痱。红痱表现为红色的疱疹,不易破溃,自觉瘙痒。白痱表现为针尖大小的水疱,疱液清澈透亮、易破裂,常见于额部、颈、胸背上部、手臂曲侧等处,一般不痒。


  预防宝典:


  1、通风降温,保持皮肤清洁干燥,勤扑痱子粉,勤换衣服,衣服宜松软宽大。


  2、洗澡最好用温水,少用肥皂,可选择碱性小的沐浴露,以减少刺激。


  3、多吃清淡、清凉食品如绿豆汤、冬瓜汤等;多吃新鲜蔬菜、水果。


  夏季皮炎


  发生于四肢伸侧,尤其是两小腿的前方,有时躯干亦可发生。初起为粟米粒大小,比较密集的红斑、丘疹或丘疱疹,瘙痒并伴有灼热感。


  预防宝典:


  1、关键是防晒、防热,特别是对阳光照射比较敏感的人,外出时一定要采取防护措施。


  2、少吃一些辛辣刺激的东西,多吃蔬菜水果等清凉的食物如苦瓜、丝瓜、冬瓜、生藕、豆菜、西瓜等。


  3、注意室内通风、降温,穿透气性好的衣服,如棉质类衣服。


五谷豆浆











五谷豆浆

爱的早餐--五谷豆浆+五谷豆渣煎饼


设备:九阳豆浆机

用料:1.干黄豆 1杯

   2.干大米、干小米、干小麦 、干高梁米、干荞麦、干玉米渣 共1杯

做法:

1.将黄豆预先充分浸泡一晚并洗净备用。

2.将材料2洗净,和黄豆混合放入杯体中,加水至下下水位线之间,接通电源,按“五谷豆浆”键,十几分钟后即可自动制成经典五谷豆浆。

营养特色:自家磨的豆浆营养非常丰富,含有丰富的优质植物质蛋白质,8种人体必需的氨基酸。

附件:




五彩一周,完美进补——做个全能美人

        一年之计在于春,春季正是进补的黄金时节,春季进补,每天一杯五谷豆浆,全面满足人体所需多种营养,更能让您做个活力健康、光彩四射的全能美人!



红色星期一,神清气爽:

        周一早上喝一杯红豆制成的豆浆会让人神采飞扬而精力充沛。红豆含有多种无机盐和微量元素,食用时口感绵甜,味道甘美。



紫色星期二,悠然一刻:

        中医强调紫菜中具有活血化淤、化痰化淤瘀、清热解毒、利水消肿的功效。那在制好的黄豆豆浆中加入紫菜,调制出一款清新的紫色豆浆,让心情放松,享受一刻悠然。



绿色星期三,清新舒适:

        清晨一杯飘着淡淡清香的绿色豆浆会让你倍感清新,可以立即释放连续工作的疲惫之感。绿豆有解毒功效,含丰富淀粉、脂肪、蛋白质和维生素,是美容养颜、靓丽肌肤的佳品。



橙色星期四,灿烂明媚

        喝一杯混有胡萝卜的橙色豆浆,体内注入的活力立刻焕然成灿烂明媚之心情大好。将胡萝卜与黄豆一同制成混合豆浆,食用后立刻增加人体的维生素A,注入美丽新活力。

黑色星期五,轻松滋养

        黑豆豆浆也许并不美丽,却有滋养健血、补虚黑发的作用。含丰富蛋白质、维生素B族,微量元素等营养成分,一杯黑豆豆浆,立刻让你在周末PARTY上大放光彩,活力无限!



编辑推荐:春季进补,五谷食品配合大豆能很好地发挥蛋白质的营养互补作用,使五谷豆浆营养更均衡,更利于人体吸收。

自制经典五谷豆浆轻松三部曲

用料:干黄豆、干大米、干小米、干小麦仁、干玉米碴按比例混合均匀

制作:

        1 将预先浸泡好的各种配料混合放入杯中。

        2 加水至上下水位线间,接通电源。

        3 按“五谷豆浆”键,十几分钟自动做好熟豆浆。



        营养健康的五谷豆浆,色彩缤纷而美味诱人,九阳豆浆机,全自动智能控制,只需轻松按键,甜美浓醇的五谷豆浆,便即刻享有!自制豆浆,卫生新鲜,有效补充营养、增强体质,常饮更令肌肤红润,光彩照人!


『豆浆食谱』


滋补保健类:

『黄豆豆浆』

『用料』黄豆70克、水1200毫升

『制法』 1、将黄豆浸泡6—16小时,备用;
   
2、将泡好的黄豆装入豆浆机网罩中,往杯体内加入清水,启动豆浆机,十几分钟后做出熟豆浆。

『功效』 滋阴润燥、宽中和脾、利水下气。

『五豆豆浆』

『用料』 黄豆30克、黑豆10克、青豆10克、豌豆10克、花生米10克、水1200毫升
『制法』
1、将五种豆类浸泡6—16小时,备用
   2、将浸泡好的五豆装入豆浆机网罩中,往杯体内加入清水,启动豆浆机,十几分钟后豆浆煮熟,报警即成。

『功效』降脂降压、强筋健脾、保护心血管。

『五豆?红枣豆浆』

『用料』黄豆26克、黑豆9克、青豆9克、豌豆9克、花生米9克、红枣13克、清水适量。

『制法』
1、将黄豆、黑豆、青豆豌豆、花生米一起浸泡6—16小时,备用;
    2、将红枣洗净去核;
   
3、将红枣和浸泡好的五豆装入LB豆浆机网罩中,杯体内按规定加入清水,接通电源十几分钟五豆?红枣豆浆就做好了。


『功效』降脂降糖降压、补虚益气、健脾和胃。
『枸杞豆浆』

『用料』
黄豆60克、枸杞10克、清水1200毫升

『制法』 1、将黄豆浸泡6—16小时,备用;
   
2、将泡好的黄豆和枸杞装入LB豆浆机网罩内,杯体内加入清水,启动豆浆机,十几分钟豆浆煮熟即成。

『功效』 滋补肝肾、益精明目、增强免疫能力。


『红枣枸杞豆浆』

『用料』 黄豆45克、红枣15克、枸杞10克、清水1200毫升

『制法』
1、将黄豆浸泡6—16小时;
    2、将红枣洗净去核,枸杞洗净备用;
   
3、将泡好的黄豆、红枣和枸杞装入LB豆浆机网罩内,杯体内加入清水,启动豆浆机,十几分钟豆浆煮熟即可。

『功效』
补虚益气、安神补肾、改善心肌营养、防治心血管疾病。

『红枣莲子浆』

『用料』
红枣(去核)15克、莲子肉15克、黄豆50克、白糖50克、清水适量。


『制法』 1、将黄豆浸泡6—16小时;
   
2、将莲子肉泡至发软;
    3、将红枣洗净与莲子肉、黄豆一并装入LB豆浆机网罩内,杯体内加入清水,启动豆浆机,十几分钟豆浆煮熟。
   
4、趁热往杯体内加入白糖,搅匀即成;不愿喝甜的也可以不加糖。

『功效』 滋阴益气、养血安神、补脾胃、清热解毒。

『花生豆浆』

『用料』花生30克、黄豆40克、水1200毫升

『制法』
1、将黄豆、花生浸泡6—16小时,备用;
    2、将泡好的黄豆和花生装入豆浆机网罩内,将清水装入杯体,启动豆浆机,十几分钟后即成。


『功效』 补血益气、滋阴润肺、适用于体虚瘦弱、大病初愈及健康人养生保健。
『黑豆芝麻浆』

『用料』
黑豆50克、花生15克、黑芝麻5-10克、水适量

『制法』 1、将黄豆、花生浸泡6—16小时;
   
2、将泡好的黑豆、花生和黑芝麻一起装入LB豆浆机网罩内,杯体内加入清水,启动豆浆机,十几分钟后豆浆煮熟。

『功效』
乌发养颜、解表清热、滋养健体。
『百合莲子浆』

『用料』
百合10克、莲子肉10克、银耳10克、绿豆40克、冰糖50克、清水适量。

『制法』
1、将百合用开水泡至发软,将莲子肉用开水浸泡至发软;
    2、将银耳洗净,用温水浸泡至发软,摘成小朵;
   
3、将绿豆浸泡6-16小时;
    4、将绿豆、百合、莲子、银耳一并装入LB豆浆机网罩内,杯体内加入冰糖和适量清水,启动机器,十几分钟后浆煮熟即成。


『功效』 清火滋阴,养心安神、补脑抗衰。

『备注』 网罩中的渣加白糖调制成豆沙,爽脆可口。

解暑降火类: 


『绿豆豆浆』

『用料』 绿豆80克、白糖50克、清水适量。

『制法』
1、将绿豆洗净,浸泡6—16小时。
    2、将泡好的绿豆放入LB豆浆机网罩中,杯体中加入清水,启动机器,十几分钟后豆浆煮熟。
   
3、趁热往杯体内加入白糖,不愿喝甜的也可不加糖。

『功效』 清热解暑、利水消肿、润喉止渴、明目降压。

『备注』
进行温补者不宜饮用,以免失去温补功效;脾胃虚寒者不宜过多饮用,以防腹泻。网罩中的豆渣加白糖调成豆沙,十分可口。
『消暑二豆饮』

『用料』
黄豆45克、绿豆30克、白糖50克、清水适量。

『制法』 1、将黄豆、绿豆浸泡6—16小时。
   
2、将泡好的二豆装入LB豆浆机网罩中,杯体中加入清水,启动机器,十几分钟后豆浆煮熟。
   
3、趁热往杯体内加入白糖,调匀即成,不愿喝甜的也可不加糖。

『功效』 消暑止渴、清热败火。
『二豆蜜浆』

『用料』
红豆20克、绿豆80克、蜂蜜50克、清水适量。

『制法』
1、将红豆、绿豆浸泡6—16小时。
   2、将泡好的红豆、绿豆放入LB豆浆机网罩中,杯体中加入清水,启动机器,十几分钟后豆浆煮熟,稍凉后调入蜂蜜即成。
   3、趁热往杯体内加入白糖,不愿喝甜的也可不加糖。

『功效』
清热利水、健脾润肺、清热解毒。

『备注』 网罩中的豆渣加白糖调成豆沙,十分可口。
『“三加一”健康豆浆』

『用料』
青豆40克、黄豆20克、绿豆15克、清水适量、白糖适量。

『制法』 1、将三豆浸泡6—16小时。
   
2、将泡好的三豆放入LB豆浆机网罩中,杯体中按规定加入清水和白糖,启动机器, 十几分钟后豆浆煮熟。

『功效』 清热解暑。

『红枣绿豆豆浆』

『用料』 红枣(去核)15克、绿豆20克、黄豆40克、白糖50克、清水适量。

『制法』  
1、将绿豆、黄豆浸泡6—16小时;
   
2、将红枣洗净与绿豆、黄豆一并放入LB豆浆机网罩中,杯体中加入清水,启动机器,十几分钟后豆浆煮熟;
   
3、趁热往杯体内加入白糖,搅匀即成,不愿喝甜的也可不加糖。

『功效』 补气提神,消暑凉血。

『蜂蜜豆浆』

『用料』
黄豆40克、绿豆35克、蜂蜜4克、清水适量。

『制法』 1、将黄豆、绿豆浸泡6—16小时。
   
2、将泡好的黄豆、绿豆装入LB豆浆机网罩中,杯体内放足清水,启动机器,十几分钟后豆浆煮熟,稍凉后调入蜂蜜即成。

『功效』
滋润五脏、美容润肠、补气益血、解暑止渴。

健脑益智类:
 
『益智豆浆』

『用料』
黄豆55克、核桃仁10克、黑芝麻5克、清水适量。

『制法』 1、将黄豆浸泡6—16小时。
   
2、将泡好的黄豆与核桃仁、黑芝麻一起装入LB豆浆机网罩中,杯体内加入足量清水,启动机器,十几分钟后豆浆煮熟。

『功效』 益智健脑。

『核桃杏仁露』

『用料』 杏仁40克、核桃40克、冰糖少许,清水适量。

『制法』
1、将杏仁、核桃装入LB豆浆机网罩中,杯体内按规定加入清。
    2、启动机器, 十几分钟后豆浆煮熟,加适量冰糖即可。

『功效』
养颜益智。
『花生乳』

『用料』 花生60克、清水适量。

『制法』 1、将花生浸泡6-12小时,备用。
   
2、将泡好的花生装入豆浆机网罩中,将水装入杯体,启动机器,十几分钟后花生乳即成。

『功效』 补脑、健身、益智。

消暑冷饮


『香蕉奶昔』

『用料』香蕉100克;鲜奶1升(1000毫升)香草冰淇淋50克;白糖适量。

『制法』香蕉去皮洗净切块一同放入网罩(豆浆网或米糊网)内,往杯体内加入鲜奶1升(1000毫升),装好米糊机,启动“粉碎”键数次后,放入冰淇淋,即可。

『特点』香滑爽口,甜而不腻;营养丰富,富含维生素。

『备注』放入冰箱内冰冻后效果会更好。

『草莓奶昔』

『用料』草莓100克;鲜奶1升(1000毫升)香草冰淇淋50克;白糖适量。

『制法』将草莓洗净切块一同放入网罩(豆浆网或米糊网)内,往杯体内加入鲜奶1升(1000毫升),装好米糊机,启动“粉碎”键数次后,放入冰淇淋,即可。

『特点』色泽红润,口感冰爽,夏日食用,可解暑润肺。

『备注』放入冰箱内冰冻后效果会更好。

『香橙苹果什饮』

『用料』橙子50克苹果100克;鲜奶1升(1000毫升)蜂蜜若干。

『制法』将香橙,苹果洗净切块一同放入网罩(豆浆网或米糊网)内,往杯体内加入鲜奶1升(1000毫升),蜂蜜若干装好米糊机,启动“粉碎”键数次后,即可。

『特点』酸甜绵软,口感细滑。

『备注』放入冰箱内冰冻后效果会更好。

『蜜桃鲜蛋液』

『用料』牛奶1升(1000毫升)鸡蛋2只,新鲜或罐装蜜桃2个,蜜桃冰淇淋适量。

『制法』将鸡蛋打碎,新鲜洗净,或罐装蜜桃切块一同放入网罩(豆浆网或米糊网)内,往杯体内加入牛奶1升(1000毫升),装好米糊机启动“粉碎”键数次后,放入冰淇淋即可饮用。

『特点』营养丰富,最适合早餐饮用。

『备注』用同样的制法,可随便配以自己喜爱的鲜果、冰淇淋,制美味饮料。

『消暑酸奶』

『用料』绿豆50,香蕉50克;酸奶1升(1000毫升)白糖适量。

『制法』将绿豆浸泡(6-16)小时备用,将泡好的绿豆,洗净香蕉切块一同放入网罩(豆浆网或米糊网)内,往杯体内加入酸奶1升(1000毫升),装好米糊机,启动“粉碎”键数次后,放入糖即可。

『特点』营养丰富、口感好,可解渴降温,是夏日最好的饮品。

『备注』放入冰箱内冰冻后效果会更好。


营养食物纤维

『小豆腐』

『用料』豆渣适量、葱、姜沫、鸡蛋2个、盐、味精、油等

『制法』用油、葱花蒸锅后加入豆渣翻炒两下,打入鸡蛋,继续翻炒三五分钟,加入盐、味精等调味品即可。

『作用』含丰富的营养,常吃能健身补脑。


『豆渣丸子』

『用料』豆渣适量、瘦肉1-2两、鸡蛋2个、青菜少许、面粉适量、食盐适量

『制法』将瘦肉和表菜切碎,和豆渣、鸡蛋、面粉一块搅和,调入食盐,做成丸子,入锅煮熟即可。

『作用』营养丰富全面,适于补虚。


『豆渣蛋饼』

『用料』 鸡蛋3个、豆渣100克、葱花、盐、食油适量

『制法』
1、将豆渣装入盆中,打入鸡蛋,并将盐葱花等加入其中搅拌均匀。
   
2、将少许食油倒入炒勺内,待油热后将准备好的豆渣鸡蛋倒入其中,摊平四五分钟后即可食用。
  
『特点』
做出的豆渣蛋饼色黄味香,含有丰富的蛋白质。尤其适合厌食、肥胖或营养不良的儿童和老人食用。


『五豆窝头』

『用料』五豆豆渣100克、玉米面40克、水少许

『制法』将五豆豆渣放入盆中,加入玉米面,搅拌均匀,捏成窝头,入锅蒸十分钟即可。

『特点』五豆窝头有丰富的营养,具有降脂补脑降压等多种作用,中老年人经常食用对保健养生大有益处。

测试Google的Analytics功能





测试Google的Analytics功能
能知道访问者统计信息

指定目录的图片2值化

```python # -*- coding: utf-8 -*- """指定目录的图片,自适应2值化 """ import os from PIL import Image import numpy as np imp...