01-1项目所需小工具

 小工具

工欲善其事,必先利其器。下面我们来介绍一下在项目中要使用的小工具(itcast-tools-1.4.jar)。这个小工具底层使用了:

 小工具jar包的使用

l c3p0数据库连接池;

l common-beanutils

l common-dbutils

l javaMail

1 CommonUtils 之CommonUtils(1生成uuid,2Map转换成JavaBean)

字面意思 common  共有的 普通的  工具包

问题如何普通 普通在哪里?

第一个工具类的使用?该类的作用是什么? 该类使用需要导入jar包吗?

1.1导入jar包使用之前 需要导入 原始的jar

和该包依赖的两个jar

 

通过项目的buidpath导入项目需要的jar包

Itcast-tools-1.4.jar

2.工具包中方法的使用 

CommonUtils类就两个方法:

两个方法都是静态方法  将包导入后  直接类点  方法

l String uuid():生成长度32的随机字符,通常用来做实体类的ID。底层使用了UUID类完成; 该方法 返回值 32位的随机字符  该方法的作用 数据库表中的主键

该方法还能做什么? 作为 激活码使用  他永远不会重复

l T toBean(Map, Class<T>)

主要了解该方法怎么用?

Map转换成指定类型的Bean对象。通常用来获取表单数据(request.getParameterMap())封装到JavaBean中,底层使用了common-beanutils。注意,本方法要求map中键的名称要与Bean的属性名称相同才能完成映射,否则不能完成映射。

/**

 * 随机生成32位长的字符串,通常用来做实体类的ID

 */

@Test 测试类 不用main方法直接运行

public void testUuid() {

String s = CommonUtils.uuid();//生成随机32位长的字符串

System.out.println(s);

}

/**该方法的作用是:

 * Map类型 数据  映射成Bean类型。 javabean

 * 要求map中键的名称与Person类的属性名称相同。

 * mapkey分别为:pidnameagebirthdayperson的属性名称也是pidnameagebirthday

 */

@Test

public void testToBean() {

Map<String,String> map = new HashMap<String,String>();

/*

 * mapkeypidagebirthdaymyname

 * person的属性:pidagebirthdayname

 * map中没有名为name的键值,而多出一个名为myname的键值,所以映射后的person对象的name属性值为null

 * map中的agebirthday都是字符串类型,而personageint类型、birthdayDate类型,但toBean()方法会自动对Map中值进行类型转换。

 */

map.put("pid", CommonUtils.uuid());

map.put("age", "23");

map.put("birthday", "2014-01-30");

map.put("myname", "张三");

Person p = CommonUtils.toBean(map, Person.class);

System.out.println(p);

}

 一个map映射对象可以吗? 一个map包含了两个javabean的数据,用这个map分别生成这两个javabean

2 JdbcUtils    4.项目所需小工具之JdbcUtils(1获取Connection,2事务管理)

2.1 jadbUtils是用的用途? 需要jar 包吗? jar包中有哪里类 和类中的方法使用?

       简化对jdbc链接数据库驱动的操作   JdbcUtils用来获取Connection

  导入三个jar包

   底层使用了c3p0连接池!两个
  * * 还需要mysql驱动 一个

 2.2 工具包中的主要方法

JdbcUtils用来获取Connection对象,以及开启和关闭事务。

l Connection getConnection():从c3p0连接池获取Connection对象,所以需要提供c3p0-config.xml配置文件;

l beginTransaction():为当前线程开启事务;

l commitTransaction():提交当前线程的事务;

l rollbackTransaction():回滚当前线程的事务;

l releaseConnection(Connection):如果参数连接对象不是当前事务的连接对象,那么关闭它,否则什么都不做;

c3p0-config.xml

<?xml version="1.0" encoding="UTF-8" ?>

<c3p0-config>

<default-config> 

<property name="jdbcUrl">jdbc:mysql://localhost:3306/mydb1</property>

<property name="driverClass">com.mysql.jdbc.Driver</property>

<property name="user">root</property>

<property name="password">123</property>

<property name="acquireIncrement">3</property>

<property name="initialPoolSize">10</property>

<property name="minPoolSize">2</property>

<property name="maxPoolSize">10</property>

</default-config>

</c3p0-config>

JdbcUtilsTest.java

/**

 * 测试JdbcUtils

 * @author qdmmy6

 *

 */

public class JdbcUtilsTest {

/**

 * 通过C3P0连接池获取连接对象

 * @throws SQLException

 */

@Test

public void testGetConnection() throws SQLException {

Connection con = JdbcUtils.getConnection();//获取连接

System.out.println(con);

JdbcUtils.releaseConnection(con);//如果参数con不是当前线程的连接对象,那么关闭之

}

/**

 * 当开始事务后,调用getConnection()会为当前线程创建Connection,而且多次调用getConnection()返回的是同一个对象

 * @throws SQLException

 */

@Test

public void testTansaction() throws SQLException {

JdbcUtils.beginTransaction();//开启事务

Connection c1 = JdbcUtils.getConnection();//第一次获取当前线程的事务连接对象

Connection c2 = JdbcUtils.getConnection();//第二次获取当前线程的事务连接对象

Assert.assertEquals(true, c1 == c2);//比较两次是否相同

JdbcUtils.commitTransaction();//提交事务

}

}


/**
* 1.JdbcUtils用来获取Connection
* * 底层使用了c3p0连接池!
* * 还需要mysql驱动
* @author qdmmy6
*
*/
public class JdbcUtilsTest {
/**
* 底层使用了c3p0连接池,说明我们还要提供c3p0配置文件
* @throws SQLException
*/
@Test
public void testGetConnection() throws SQLException {
Connection con = JdbcUtils.getConnection();
System.out.println(con);;
JdbcUtils.releaseConnection(con);
System.out.println(con.isClosed());
}

/**
*2. JdbcUtilst还提供了与事务相关的功能
*
*/
@Test
public void testTransaction() {
try { //事物 需要 try catch
JdbcUtils.beginTransaction();//开启事务

// 多次操作

JdbcUtils.commitTransaction();//提交事务
} catch(Exception e) {
try {//出了异常回滚事务
JdbcUtils.rollbackTransaction();//回滚事务
} catch (SQLException e1) {
}
}
}

3 TxQueryRunner 5.项目所需小工具之TxQueryRunner(把JdbcUtils和dbUtils整合在一起)

导入包

TxQueryRunner类是common-dbutilsQueryRunner类的子类,用来简化JDBC操作TxQueryRunner类内部使用JdbcUtils.getConnection()类来获取连接对象,以及使用JdbcUtils.releaseConnection()关闭连接。

l int[] batch(String sql, Object[][] params):执行批处理,参数sqlSQL语句模板,params为参数

l T query(String sql, ResultSetHandler<T> rh):执行查询,执行查询,参数sql为要执行的查询语句模板,rh是结果集处理,用来把结果集映射成你想要的结果;

l T query(String sql, ResultSetHandler<T> rh, Object… params):执行查询,参数sql为要执行的查询语句模板,rh是结果集处理,用来把结果集映射成你想要的结果,paramssql语句的参数

l int update(String sql):执行增、删、改语句,参数sql是要执行的SQL语句;

l int update(Stringsql, Object param):执行增、删、改语句,参数sql是要执行的SQL语句,参数param是参数(一个参数)

l int update(String sql, Object… params):执行增、删、改语句,参数sql是要执行的SQL语句,参数params是参数(多个参数)

为了测试TxQueryRunner,我们在mydb1数据库下创建t_person表,然后再创建Person实体类,以及PersonDao类,最后测试PersonDao类中的方法。

t_person

字段

说明

pid

主键

name

姓名

age

年龄

birthday

生日

Person.java

public class Person {

private String pid;

private String name;

private int age;

private Date birthday;

}

PersonDao.java

/**

 * 测试TxQueryRunner

 * @author qdmmy6

 *

 */

public class PersonDao {

private QueryRunner qr = new TxQueryRunner();

public void add(Person person) throws SQLException {

String sql = "insert into t_person values(?,?,?,?)";

Object[] params = {person.getPid(),

person.getName(),

person.getAge(),

new java.sql.Date(person.getBirthday().getTime())};

qr.update(sql, params);

}

public void edit(Person person) throws SQLException {

String sql = "update t_person set name=?,age=?,birthday=? where pid=?";

Object[] params = {

person.getName(),

person.getAge(),

new java.sql.Date(person.getBirthday().getTime()),

person.getPid()};

qr.update(sql, params);

}

public void delete(String pid) throws SQLException {

String sql = "delete from t_person where pid=?";

qr.update(sql, pid);

}

public Person load(String pid) throws SQLException {

String sql = "select * from t_person where pid=?";

return qr.query(sql, new BeanHandler<Person>(Person.class), pid);

}

public List<Person> findAll() throws SQLException {

String sql = "select * from t_person";

return qr.query(sql, new BeanListHandler<Person>(Person.class));

}

}

PersonDaoTest.java

public class PersonDaoTest {

@Test

public void testAdd() throws SQLException {

Person p1 = new Person(CommonUtils.uuid(), "张三", 18, new Date());

Person p2 = new Person(CommonUtils.uuid(), "李四", 81, new Date());

Person p3 = new Person(CommonUtils.uuid(), "王五", 66, new Date());

PersonDao dao = new PersonDao();

dao.add(p1);

dao.add(p2);

dao.add(p3);

}

@Test

public void testEdit() throws SQLException {

PersonDao dao = new PersonDao();

Person person = dao.load("2F371BE415984DE89781CCCA7B8734CB");

person.setAge(88);

dao.edit(person);

}

@Test

public void testDelete() throws SQLException {

PersonDao dao = new PersonDao();

dao.delete("2F371BE415984DE89781CCCA7B8734CB");

}

@Test

public void testFindAll() throws SQLException {

PersonDao dao = new PersonDao();

List<Person> list = dao.findAll();

System.out.println(list);

}

}

 讲课源码


/**
* TxQueryRunner它是QueryRunner的子类!(commons-dbutils.jar) 方法都封装好了 直接用就行  原理 做完项目的时候在学
* 可用起来与QueryRunner相似的!
* 我们的类支持事务!它底层使用了JdbcUtils来获取连接
*
* 简化jdbc的操作
* QueryRunner的三个方法:
* * update() --> insert、update、delete
* * query() --> select
* * batch() --> 批处理
* @author qdmmy6
*
*/
public class TxQueryRunnerTest {
/** * 测试update()方法,用来执行insert、update、delete语句

* @throws SQLException
*/

@Test update()执行数据的插入操作

public void testUpdate() throws SQLException {
String sql = "insert into t_person(pid,pname,age,sex) values(?,?,?,?)";
Object[] params = {"1", "p1", 1, "男"};//给sql中对应的参数

QueryRunner qr = new TxQueryRunner();//我们没有给对象提供连接池
qr.update(sql, params);//执行sql,也不提供连接,它内部会使用JdbcUtils来获取连接  
}
成功插入


/**
* 使用事务 连续插入两条数据  第一条插入成功第二天没成功 回滚

保证数据一定插入成功 否则报错
* @throws SQLException
*/
@Test
public void testUpdate2() throws Exception {
try { 
JdbcUtils.beginTransaction();//开启事务

String sql = "insert into t_person(pid,pname,age,sex) values(?,?,?,?)";
QueryRunner qr = new TxQueryRunner();
Object[] params = {"2", "p2", 2, "女"};
qr.update(sql, params);//执行

if(false) {
throw new Exception();
}

params = new Object[]{"3", "p3", 3, "女"};
qr.update(sql, params);//执行

JdbcUtils.commitTransaction();//提交事务
} catch(Exception e) {
try {
JdbcUtils.rollbackTransaction();//回滚事务
} catch (SQLException e1) {
}
throw e;
}
}

/**
* 测试查询方法
* 我们知道JDBC查询的结果的是ResultSet
* 而QueryRunner查询的结果是通过ResultSet映射后的数据。
* * QueryRunner第一步是执行select,得到ResultSet
* * 把ResultSet转换成其他类型的
* 通过转换结果:
*    * javaBean:把结果集封装到javaBean中
* * Map:把结果集封装到Map中
* * 把结果集封装到Object中(结果集是单行单列)
* @throws SQLException
*
*
*/
/*
* 单行结果集映射到javaBean中
*/
@Test
public void testQuery1() throws SQLException {
String sql = "select * from t_person where pid=?";
QueryRunner qr = new TxQueryRunner();
/*
* 第二个参数类型为ResultSetHandler,它是一个接口,表示映射的结果类型。
*
* BeanHandler --> 它是ResultSetHandler的实现类,它的作用是把结果集封装到Person对象中
*/


Person p = qr.query(sql, new BeanHandler<Person>(Person.class), "1");
System.out.println(p);
}

/**
* 使用BeanListHandler
* 把多行结果集映射到List<Bean>,即多个JavaBean对象。

* 一行结果集记录对应一个javaBean对象,多行就对应List<Bean> list集合


* @throws SQLException
*/
@Test
public void testQuery2() throws SQLException {
String sql = "select * from t_person";
QueryRunner qr = new TxQueryRunner();
/*
* 第二个参数类型为ResultSetHandler,它是一个接口,表示映射的结果类型。
*
* BeanListHandler --> 它是ResultSetHandler的实现类,
* 它的作用是把结果集封装到List<Person>对象中
*/
List<Person> list = qr.query(sql, new BeanListHandler<Person>(Person.class));
System.out.println(list);
}

/**
* 使用MapHandler,把单行结果集封装到Map对象中
* @throws SQLException
*/


@Test
public void testQuery3() throws SQLException {
String sql = "select * from t_person where pid=?";
QueryRunner qr = new TxQueryRunner();
/*
* 第二个参数类型为ResultSetHandler,它是一个接口,表示映射的结果类型。
*
* BeanListHandler --> 它是ResultSetHandler的实现类,
* 它的作用是把结果集封装到List<Person>对象中
*/
Map<String, Object> map = qr.query(sql, new MapHandler(), "1");
System.out.println(map);
}

/** 
* 使用MapListHandler,把多行结果集封装到List<Map>中,即多个Map
* 一行对应一个Map,多行对应List<Map>
* @throws SQLException
*/
@Test
public void testQuery4() throws SQLException {
String sql = "select * from t_person";
QueryRunner qr = new TxQueryRunner();
/*
* 第二个参数类型为ResultSetHandler,它是一个接口,表示映射的结果类型。
*
* BeanListHandler --> 它是ResultSetHandler的实现类,
* 它的作用是把结果集封装到List<Person>对象中
*/
List<Map<String, Object>> mapList = qr.query(sql, new MapListHandler());
System.out.println(mapList);
}

/**
* 使用ScalarHandler,把单行单列的结果集封装到Object中
* @throws SQLException
*/
@Test
public void testQuery5() throws SQLException {
String sql = "select count(*) from t _person";//结果集是单行单列的
QueryRunner qr = new TxQueryRunner();

Object obj = qr.query(sql, new ScalarHandler());
/*
* 我们知道select count(1),结果一定是个整数!
* > Integer
* > Long
* > BigInteger
*
* 不同的驱动,结果不同!
* 无论是哪种类型,它都是Number类型!强转成Number一定不出错
*/
Number number = (Number)obj;
long cnt = number.longValue();
System.out.println(cnt);   //输出结果是个数字
}

/**
* 一行结果集中包含了两张表的列

 

 

两张表从属关系 , person是从表  address是主表 

一行结果集 对应两个对象

1.构建一个AddressBean对象  和person 对象

当写表和实体类之间映射的时候,一旦出现外键的时候不能写外键,通过外键找到类型写出来


* 使用MapHandler来处理

处理的过程:
* 1. 把结果集封装到map中
* 2. 使用map生成Person对象
* 3. 使用map生成address对象
* 4. 把两个实体对象建立关系
* @throws SQLException
*/


@Test
public void testQuery6() throws SQLException {
String sql = "SELECT * FROM t_person p, t_address a WHERE p.aid=a.aid AND p.pid=?";
QueryRunner qr = new TxQueryRunner();
/*
* 1. 得到Map
*/
Map map = qr.query(sql, new MapHandler(), "aaa");
/*
* 2. 把Map中部分数据封装到Person中
*/
Person p = CommonUtils.toBean(map, Person.class);
/*
* 3. 把Map中部分数据封装到Address中
*/
Address addr = CommonUtils.toBean(map, Address.class);
/*
* 4. 建立两个实体的关系
*/
p.setAddress(addr);

System.out.println(p);
}

 person类


public class Person {
private String pid;
private String pname;
private int age;
private String sex;

private Address address;

address类


public class Address {
private String aid;//主键
private String province;//省
private String city;//市
private String district;//区
private String street;//街道

源码部分

/**
* 一行结果集中包含了两张表的列
* 使用MapHandler来处理
* 1. 把结果集封装到map中
* 2. 使用map生成Person对象
* 3. 使用map生成address对象
* 4. 把两个实体对象建立关系
* @throws SQLException
*/
@Test
public void testQuery6() throws SQLException {
String sql = "SELECT * FROM t_person p, t_address a WHERE p.aid=a.aid AND p.pid=?";
QueryRunner qr = new TxQueryRunner();
/*
* 1. 得到Map
*/
Map map = qr.query(sql, new MapHandler(), "aaa");
/*
* 2. 把Map中部分数据封装到Person中
*/
Person p = CommonUtils.toBean(map, Person.class);
/*
* 3. 把Map中部分数据封装到Address中
*/
Address addr = CommonUtils.toBean(map, Address.class);
/*
* 4. 建立两个实体的关系
*/
p.setAddress(addr);

System.out.println(p);
}

 

4 MailUtils

MailUtils是用来发邮件的小工具,底层使用JavaMail完成,所以它这件事mail.jaractivaion.jar。 导入两个包

源码 主要用来激活 用户注册的时候 给邮箱发送一个激活邮件


/**
* 测试MailUtils,作用是发邮件,不收邮件
* 底层依赖的是javamail:mail.jar、activation.jar
* @author qdmmy6
*
*/
public class MailUtilsTest {
/**
* 发邮件
* @throws IOException
* @throws MessagingException
*/
@Test
public void send() throws MessagingException, IOException {
/*

发送邮件的步骤

* 1. 登录邮件服务器
* MailUtils.createSession(服务器地址, 登录名, 密码); 返回一个session对象
* 2. 创建邮件对象
* 发件人
* 收件人
* 主题
* 正文
* 3. 发
* 需要第一步得到的session、和第二步的邮件对象
*/

javaxmail下的session

smtp.163.com  smtp指的是邮件协议
Session session = MailUtils.createSession(".163.com", "itcast_cxf", "itcastitcast");

后期吧信息放在配置文件中 放在代码中 是不安全的

点击这里完成激活 

不建议使用带有邮箱验证的邮箱发送 ruqq

Mail mail = new Mail("itcast_cxf@163.com", "itcast_cxf@126.com", "测试邮件一封", "<a href='http://www.baidu.com'>百度</a>");

MailUtils.send(session, mail);
}
}

MailUtilsTest.java

/**

 * 测试发送普通邮件

 * @throws IOException

 * @throws MessagingException

 */

@Test

public void fun() throws MessagingException, IOException {

Session session = MailUtils.createSession("smtp.163.com", "itcast_cxf", "itcastitcast");

Mail mail = new Mail("itcast_cxf@163.com", "itcast_cxf@126.com", "测试MailUtils", "这是正文!");

MailUtils.send(session, mail);

}

log4j的配置 只提示警告以上的信息 和只打印给控制台  

 f1信息隐去

5 BaseServlet

导入包了已经 copy以上所有的jar包

BaseServlet是用来作为其它Servlet父类的,它有如下两个优点:

一个Servlet多个处理方法

BaseServlet的作用是用来简化Servlet。通过我们需要为每个功能编写一个Servlet,例如用户注册写一个RegistServlet,用户登录写一个LoginServlet。如果使用BaseServlet,那么我们可以只写一个UserServlet,然后让UserServlet去继承BaseServlet,然后在UserServlet给出两个请求处理方法,一个方法叫regist(),一个叫login()

BaseServlet来简化了Servlet中请求转发和重定向的代码。

 

 自己写的包

 源码

package cn.itcast.test.web.servlet;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import cn.itcast.servlet.BaseServlet;

/**
* 一般Servlet都是只有一个请求处理方法
* 登录:一个LoginServlet
* 注册:一个RegistServlet
* 修改密码:...
*
* 我们需要一个Servlet有多个请求处理方法
* login()
* regist()
* updatePassword()
*
* 让你的Servlet去继承BaseServlet
*
* -----------
*
* BaseServlet:
* 1. 可以有多个请求处理方法
* 2. 简化了转发和重定向的代码
*
* 请求处理方法格式:
* pubilc String regist(HttpServletRequest request, HttpServletResponse response)
* throws ServletException, IOException {
* }
*
* 请求BaseServlet中的某个方法:
* http://localhost:8080/tools/AServlet?method=regist 原来地址的基础上加上一个method=方法名
* http://localhost:8080/tools/AServlet?method=login
* @author qdmmy6
*
*/


public class AServlet extends BaseServlet {
public String regist(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {

//2. 简化了转发和重定向的代码 重定向到本网站的页面
System.out.println("regist()...");   return 返回值i
return "/index.jsp";//表示转发到index.jsp
// return "f:/index.jsp";//f前缀表示forward,即转发
// return "r:/index.jsp";//r前缀表示redirect,即重定向
// return null;//不转发,也不重定向
// return "";//不转发,也不重定向
// 想重定向到百度,return null,自己去重定向!百度不是项目中的页面
}

public String login(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
System.out.println("login()...");
return "r:/index.jsp";
}
}

简化了请求转发和重定向的代码

BaseServlet中的请求处理方法有一个String类型的返回值,返回值表示转发或重定向的目标页面。例如:

l f:/index.jsp:其中f:表示转发,即forward的意思,/index.jsp表示转发到/index.jsp页面; 转发地址不会改变

l r:/index.jsp:其中r:表示重定向,即redirect的意思,/index.jsp表示重定向到/index.jsp页面。 重定向才会改变输入栏 中地址

l null:表示不转发也不重定向;

因为BaseServlet中可以有多个请求处理方法,所以在访问BaseServlet时一定要给出名为method的参数来指定要请求的方法名称。

AServlet.java

public class AServlet extends BaseServlet {

/**

 * 请求处理方法的参数都与doGet()doPost()相同,即requestresponse

 * 但请求处理方法有String类型的返回值,而doGet()doPost()没有返回值。

 * 在请求本方法时需要给出method=regist参数!

 */

public String regist(HttpServletRequest req, HttpServletResponse resp)

throws ServletException, IOException {

System.out.println("AServlet regist()...");

return "f:/index.jsp";

}

/**

 * 在请求本方法时需要给出method=login参数!

 */

public String login(HttpServletRequest req, HttpServletResponse resp)

throws ServletException, IOException {

System.out.println("AServlet login()...");

return "r:/index.jsp";

}

}

 5.5项目设置自动的热加载 修改完servlet后不用重启tomcat

  tomcat conf---context.xml修改配置  reloadable="ture" 等一会  如果有缓存还是要重启的

6 EncodingFilter

EncodingFilter用来处理请求编码问题。

我们知道,如果是POST请求,我们需要调用request.setCharacterEncoding(“utf-8”)方法来设计编码;如果是GET请求,我们需要自己手动来处理编码问题。如果我们使用了EncodingFilter,那么就处理了POSTGET请求的编码问题。

web.xml

<filter>

<filter-name>EncdoingFilter</filter-name>

<filter-class>cn.itcast.filter.EncodingFilter</filter-class>

</filter>

<filter-mapping>

<filter-name>EncdoingFilter</filter-name>

<url-pattern>/*</url-pattern>

</filter-mapping>

index.jsp

<a href="<c:url value='/EncodingServlet?method=test&name=张三'/>">点击这里发出GET请求</a><br/>

<form action="<c:url value='/EncodingServlet'/>" method="post">

  <input type="hidden" name="method" value="test"/>

  <input type="text" name="name" value="李四"/>

  <input type="submit" value="请求这里发出POST请求"/>

</form>

EncodingServlet

/**

 * 测试EncodingFilter

 * @author qdmmy6

 *

 */

public class EncodingServlet extends BaseServlet {

/**

 * 可以使用POSTGET两种方式请求test()方法!查看输出是否为乱码!

 */

public String test(HttpServletRequest request, HttpServletResponse response)

throws ServletException, IOException {

String name = request.getParameter("name");

System.out.println(name);

return null;

}

}

 源码  在web.xml中进行filter的配置

<!-- 处理全站请求编码,无论是GET还是POST,默认是UTF-8 -->
<filter>
<filter-name>EncodingFilter</filter-name>
<filter-class>cn.itcast.filter.EncodingFilter</filter-class>     //包地址
  <init-param>     //初始化参数 设置 字符集可以是gbk
    <param-name>charset</param-name>
    <param-value>utf-8</param-value>
  </init-param>
</filter>


<filter-mapping>
<filter-name>EncodingFilter</filter-name>
<url-pattern>/*</url-pattern>   //全过滤
</filter-mapping>

7 VerifyCodeServlet(一次性验证码)

通过在表单中总是需要使用一次性验证码,这一问题可以使用VerifyCodeServlet来处理。让<img>元素的src指向VerifyCodeServlet即可在页面中生成一次性验证码。而且VerifyCodeServlet还会把验证码保存到session中,名称为:vCode,也就是说,你可以通过session来获取验证码文本:session.getAttribute(“vCode”)

web.xml

<servlet>

  <servlet-name>VerifyCodeServlet</servlet-name>

  <servlet-class>cn.itcast.vcode.servlet.VerifyCodeServlet</servlet-class>

</servlet>

<servlet-mapping>

  <servlet-name>VerifyCodeServlet</servlet-name>

  <url-pattern>/VerifyCodeServlet</url-pattern>

</servlet-mapping>

MyJsp.jsp

<form action="<c:url value='/UserServlet'/>" method="post">

<input type="hidden" name="method" value="regist"/>

验证码:<input type="text" name="verifyCode"/>

<img src="<c:url value='/VerifyCodeServlet'/>" border="1"/><br/>

<input type="submit" value="注册"/>

</form>

  因为用户可能看不清楚图片上的文本,所以我们需要给用户提供一个“换一张”超链接。其实实现这一步很简单,只需要使用javascript<img>元素src指向VerifyCodeServlet即可。但因为浏览器可能会缓存上一次生成的图片,所以我们还需要使用时间为参数“强迫”浏览器访问服务器,而不是使用缓存。

MyJsp.jsp

<script type="text/javascript" src="<c:url value='/js/jquery-1.5.1.js'/>"></script>

<script type="text/javascript">

function change() {

$("#img").attr("src", "<c:url value='/VerifyCodeServlet?'/>" + new Date().getTime());

}

</script>

<form action="<c:url value='/UserServlet'/>" method="post">

<input type="hidden" name="method" value="regist"/>

验证码:<input type="text" name="verifyCode"/>

<img id="img" src="<c:url value='/VerifyCodeServlet'/>" border="1"/>

<a href="javascript:change();">换一张</a>

<br/>

<input type="submit" value="注册"/>

</form>

当用户在表单中填写了验证码,而且提交了表单,到达UserServletregist()方法,在regist() 方法中需要比较用户在表单中输入的验证码,与验证码图片上的文本是否相同。

获取用户输入的验证码:request.getParameter(“verifyCode”)

获取图片上的验证码:session.getAttribute(“vCode”);

1.写一个页面 普通的注册页面 用户名 密码和验证框

 测试页面

想办法弄出验证码

2.让图片显示出来

web中配置已经写好的Servlet 先配置文件中配置 使用的工具包中的VerifyCodeServlet


<servlet>
<servlet-name>VerifyCodeServlet</servlet-name>
<servlet-class>cn.itcast.vcode.servlet.VerifyCodeServlet</servlet-class>
</servlet>

<servlet-mapping>
<servlet-name>VerifyCodeServlet</servlet-name>
<url-pattern>/VerifyCodeServlet</url-pattern>
</servlet-mapping>

通过javascript实现张图片的点击换一张

<script type="text/javascript">
function _hyz() {
/*
1. 获取<img>元素
2. 给它的src指向为/tools/VerifyCodeServlet
*/
var img = document.getElementById("imgVerifyCode");
// 需要给出一个参数,这个参数每次都不同,这样才能干掉浏览器缓存!
img.src = "${pageContext.requet.contextPath} /VerifyCodeServlet?a=" + new Date().getTime();
}
</script>


</head>

<body>
<%--
1. 写表单,其中包含图片(验证码)
2. 让图片显示出来:
  把<img>的src指向VerifyCodeServlet,你需要在web.xml中部署VerfiyCodeServlet
3. 换一张
--%>
<form action="/tools/LoginServlet" method="post">
<%-- 添加一个参数:method=login --%>
<input type="hidden" name="method" value="login">
用户名:<input type="text" name="name"/><br/>
密 码:<input type="password" name="pwd"/><br/>
验证码:<input type="text" name="verifyCode"/><br/>
<img src="/tools/VerifyCodeServlet" id="imgVerifyCode"/>
<a href="javascript:_hyz()">换一张</a>
<br/>
<input type="submit" value="提交"/>
</form>

Ie缓存的原因 同一个路径  第二次访问 不直接从缓存中取值   没有从服务器中取值

表单的验证

表单传参数 访问自定义的Servlet

${pageContext.request.contextPath}   获取项目名,通过el标签

*/
public class AServlet extends BaseServlet {
public String regist(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
System.out.println("regist()...");
return "/index.jsp";//表示转发到index.jsp
// return "f:/index.jsp";//f前缀表示forward,即转发
// return "r:/index.jsp";//r前缀表示redirect,即重定向
// return null;//不转发,也不重定向
// return "";//不转发,也不重定向
// 想重定向到百度,return null,自己去重定向!
}

public String login(HttpServletRequest request, HttpServletResponse response)

throws ServletException, IOException {
System.out.println("login()...");
return "r:/index.jsp";
}

总结这个BaseServlet 很鸡助 可以不使用
}

将AServlet注册 到web中  在高版本中通过注解来使用Servlet

<servlet>
<servlet-name>AServlet</servlet-name>
<servlet-class>文件加.类名</servlet-class>
</servlet>

<servlet-mapping>
<servlet-name>AServlet</servlet-name>
<url-pattern>/AServlet</url-pattern>
</servlet-mapping>

原文地址:https://www.cnblogs.com/nextgg/p/7641933.html