标签:
工欲善其事,必先利其器。下面我们来介绍一下在项目中要使用的小工具(itcast-tools-1.4.jar)。这个小工具底层使用了:
· c3p0数据库连接池;
· common-beanutils;
·common-dbutils;
· javaMail;
CommonUtils类就两个方法:
·String uuid():生成长度32的随机字符,通常用来做实体类的ID。底层使用了UUID类完成;
·T toBean(Map, Class<T>):把Map转换成指定类型的Bean对象。通常用来获取表单数据(request.getParameterMap())封装到JavaBean中,底层使用了common-beanutils。注意,本方法要求map中键的名称要与Bean的属性名称相同才能完成映射,否则不能完成映射。
/** * 随机生成32位长的字符串,通常用来做实体类的ID
* 或者是订单号 */ @Test public void testUuid() { String s = CommonUtils.uuid();//生成随机32位长的字符串 System.out.println(s); } /** * 把Map类型映射成Bean类型。 * 要求map中键的名称与Person类的属性名称相同。 * 即map的key分别为:pid、name、age、birthday,person的属性名称也是pid、name、age、birthday
* map的key与属性名一一对应 */ @Test public void testToBean() { Map<String,String> map = new HashMap<String,String>(); /* * map的key:pid、age、birthday、myname * person的属性:pid、age、birthday、name * map中没有名为name的键值,而多出一个名为myname的键值,所以映射后的person对象的name属性值为null。 * map中的age和birthday都是字符串类型,而person的age是int类型、birthday是Date类型,但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); }
JdbcUtils用来获取Connection对象,以及开启和关闭事务。
· Connection getConnection():从c3p0连接池获取Connection对象,所以需要提供c3p0-config.xml配置文件;
· beginTransaction():为当前线程开启事务;
· commitTransaction():提交当前线程的事务;
· rollbackTransaction():回滚当前线程的事务;
· releaseConnection(Connection):如果参数连接对象不是当前事务的连接对象,那么关闭它,否则什么都不做;《.close方法是一定关》
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();//提交事务 } }
TxQueryRunner类是common-dbutils下QueryRunner类的子类(用法与其父类相似,区别是其支持事务),用来简化JDBC操作。TxQueryRunner类内部使用了JdbcUtils.getConnection()类来获取连接对象,以及使用JdbcUtils.releaseConnection()关闭连接。
三种方法:update()
query()
batch()
· int[] batch(String sql, Object[][] params):执行批处理,参数sql是SQL语句模板,params为参数;
· T query(String sql, ResultSetHandler<T> rh):执行查询,执行查询,参数sql为要执行的查询语句模板,rh是结果集处理,用来把结果集映射成你想要的结果;
· T query(String sql, ResultSetHandler<T> rh, Object… params):执行查询,参数sql为要执行的查询语句模板,rh是结果集处理,用来把结果集映射成你想要的结果,params是sql语句的参数;
· int update(String sql):执行增、删、改语句,参数sql是要执行的SQL语句;
· int update(Stringsql, Object param):执行增、删、改语句,参数sql是要执行的SQL语句,参数param是参数(一个参数);
· 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); } }
MailUtils是用来发邮件的小工具,底层使用JavaMail完成,所以它这件事mail.jar和activaion.jar。
MailUtilsTest.java
/** * 测试发送普通邮件 * @throws IOException * @throws MessagingException */ @Test public void fun() throws MessagingException, IOException { Session session = MailUtils.createSession("smtp.163.com", "itcast_cxf", "itcastitcast");[创建session] Mail mail = new Mail("itcast_cxf@163.com", "itcast_cxf@126.com", "测试MailUtils", "这是正文!");[创建邮箱对象,参数分别为:发件人、收件人、主题、正文] MailUtils.send(session, mail);[发送邮件] }
BaseServlet是用来作为其它Servlet父类的,它有如下两个优点:
一个Servlet多个处理方法
BaseServlet的作用是用来简化Servlet。通过我们需要为每个功能编写一个Servlet,例如用户注册写一个RegistServlet,用户登录写一个LoginServlet。如果使用BaseServlet,那么我们可以只写一个UserServlet,然后让UserServlet去继承BaseServlet,然后在UserServlet给出两个请求处理方法,一个方法叫regist(),一个叫login()。
BaseServlet来简化了Servlet中请求转发和重定向的代码。
简化了请求转发和重定向的代码
BaseServlet中的请求处理方法有一个String类型的返回值,返回值表示转发或重定向的目标页面。例如:
· f:/index.jsp:其中f:表示转发,即forward的意思,/index.jsp表示转发到/index.jsp页面;
· r:/index.jsp:其中r:表示重定向,即redirect的意思,/index.jsp表示重定向到/index.jsp页面。
· null:表示不转发也不重定向;
因为BaseServlet中可以有多个请求处理方法,所以在访问BaseServlet时一定要给出名为method的参数来指定要请求的方法名称。
AServlet.java
public class AServlet extends BaseServlet { /** * 请求处理方法的参数都与doGet()和doPost()相同,即request和response * 但请求处理方法有String类型的返回值,而doGet()和doPost()没有返回值。 * 在请求本方法时需要给出method=regist参数! */ public String regist[访问本方法的URL为http://localhost:8080/day01/AServlet?method=regist](HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { System.out.println("AServlet regist()..."); return "f:/index.jsp";[转发到/index.jsp页面] } /** * 在请求本方法时需要给出method=login参数! */ public String login[访问本方法的URL为http://localhost:8080/day01/AServlet?method=login](HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { System.out.println("AServlet login()..."); return "r:/index.jsp"[重定向到/index.jsp]; } }
EncodingFilter用来处理请求编码问题。
我们知道,如果是POST请求,我们需要调用request.setCharacterEncoding(“utf-8”)方法来设计编码;如果是GET请求,我们需要自己手动来处理编码问题。如果我们使用了EncodingFilter,那么就处理了POST和GET请求的编码问题。
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[请求EncdoingServlet的test方法]&name=张三‘/>">点击这里发出GET请求</a><br/>
<form action="<c:url value=‘/EncodingServlet‘/>" method="post">
<input type="hidden" name="method" value="test"/>[请求EncodingServlet的test方法]
<input type="text" name="name" value="李四"/>
<input type="submit" value="请求这里发出POST请求"/>
</form>
EncodingServlet
/** * 测试EncodingFilter * @author qdmmy6 * */ public class EncodingServlet [因为添加了EncodingFilter过滤器,那么所有的Servlet都不用再去处理请求编码的问题了。]extends BaseServlet { /** * 可以使用POST和GET两种方式请求test()方法!查看输出是否为乱码! */ public String test(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String name = request.getParameter("name"); System.out.println(name); return null; } }
通过在表单中总是需要使用一次性验证码,这一问题可以使用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‘/>"[让<img>的src指向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>[导入jquery] <script type="text/javascript"> function change[在点击“换一张”时会调用本方法]() { $("#img").attr("src", "<c:url value=‘/VerifyCodeServlet?‘/>" + new Date().getTime());[指定<img>元素的src属性值为VerifyCodeServlet,并且追加参数为当前时间毫秒,它是不会重复的值,所以浏览器不会使用缓存,而是访问服务器。] } </script> … <form action="<c:url value=‘/UserServlet‘/>" method="post"> <input type="hidden" name="method" value="regist"/> 验证码:<input type="text" name="verifyCode"/> <img id="img"[指定id为img,方法使用jquery来查找该元素。] src="<c:url value=‘/VerifyCodeServlet‘/>" border="1"/> <a href="javascript:change();">换一张</a>[点击该超链接会调用change()方法] <br/> <input type="submit" value="注册"/> </form>
当用户在表单中填写了验证码,而且提交了表单,到达UserServlet的regist()方法,在regist() 方法中需要比较用户在表单中输入的验证码,与验证码图片上的文本是否相同。
· 获取用户输入的验证码:request.getParameter(“verifyCode”);
· 获取图片上的验证码:session.getAttribute(“vCode”);
标签:
原文地址:http://www.cnblogs.com/zjfjava/p/5954379.html