• 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>

  • 相关阅读:
    python访问mysql和redis
    南昌PHP程序员的工资水平据说可达到8000了
    Android开发总是难以入门
    AppCan可以视为Rexsee的存活版
    像我这样的人搞程序开发
    PHPWind 8.7中插件金币竞价插件的漏洞
    混合式APP开发中中间件方案Rexsee
    看到一份名单发现很多公司都和自己发生了或多或少的联系
    PhpWind 8.7中禁止后台管理员随意修改会员用户名功能
    个人前途
  • 原文地址:https://www.cnblogs.com/nextgg/p/7641933.html
Copyright © 2020-2023  润新知