1. 程式人生 > 實用技巧 >專案01-JavaWeb網上書城01之工具類

專案01-JavaWeb網上書城01之工具類

1.專案中用到的小工具

1.CommonUtils

  CommonUtils類就兩個方法:

    1.String uuid():生成長度32的隨機字元,通常用來做實體類的ID。底層使用了UUID類完成;

    2.T toBean(Map, Class<T>):把Map轉換成指定型別的Bean物件。通常用來獲取表單資料(request.getParameterMap())封裝到JavaBean中,底層使用了common-beanutils。注意,本方法要求map中鍵的名稱要與Bean的屬性名稱相同才能完成對映,否則不能完成對映;

  1.原始碼

 1 import java.util.Map;
2 import java.util.UUID; 3 4 import org.apache.commons.beanutils.BeanUtils; 5 import org.apache.commons.beanutils.ConvertUtils; 6 7 /** 8 * 小工具 9 * 10 * 11 */ 12 public class CommonUtils { 13 /** 14 * 返回一個不重複的字串 15 * @return 16 */ 17 public static String uuid() { 18 return
UUID.randomUUID().toString().replace("-", "").toUpperCase(); 19 } 20 21 /** 22 * 把map轉換成物件 23 * @param map 24 * @param clazz 25 * @return 26 * 27 * 把Map轉換成指定型別 28 */ 29 @SuppressWarnings("rawtypes") 30 public static <T> T toBean(Map map, Class<T> clazz) {
31 try { 32 /* 33 * 1. 通過引數clazz建立例項 34 * 2. 使用BeanUtils.populate把map的資料封閉到bean中 35 */ 36 T bean = clazz.newInstance(); 37 ConvertUtils.register(new DateConverter(), java.util.Date.class); 38 BeanUtils.populate(bean, map); 39 return bean; 40 } catch(Exception e) { 41 throw new RuntimeException(e); 42 } 43 } 44 }

  2.測試程式碼

 1     /**
 2      * 隨機生成32位長的字串,通常用來做實體類的ID
 3      */
 4     @Test
 5     public void testUuid() {
 6         String s = CommonUtils.uuid();//生成隨機32位長的字串
 7         System.out.println(s);
 8     }
 9     
10     /**
11      * 把Map型別對映成Bean型別。
12      * 要求map中鍵的名稱與Person類的屬性名稱相同。
13      * 即map的key分別為:pid、name、age、birthday,person的屬性名稱也是pid、name、age、birthday
14      */
15     @Test
16     public void testToBean() {
17         Map<String,String> map = new HashMap<String,String>();
18         /*
19          * map的key:pid、age、birthday、myname
20          * person的屬性:pid、age、birthday、name
21          * map中沒有名為name的鍵值,而多出一個名為myname的鍵值,所以對映後的person物件的name屬性值為null。
22          * map中的age和birthday都是字串型別,而person的age是int型別、birthday是Date型別,但toBean()方法會自動對Map中值進行型別轉換。
23          */
24         map.put("pid", CommonUtils.uuid());
25         map.put("age", "23");
26         map.put("birthday", "2014-01-30");
27         map.put("myname", "張三");
28         
29         Person p = CommonUtils.toBean(map, Person.class);
30         System.out.println(p);
31     }

=========================================================================================================================================

2.JdbcUtils

JdbcUtils用來獲取Connection物件,以及開啟和關閉事務。

  l Connection getConnection():從c3p0連線池獲取Connection物件,所以需要提供c3p0-config.xml配置檔案;

  l beginTransaction():為當前執行緒開啟事務;

  l commitTransaction():提交當前執行緒的事務;

  l rollbackTransaction():回滾當前執行緒的事務;

  l releaseConnection(Connection):如果引數連線物件不是當前事務的連線物件,那麼關閉它,否則什麼都不做;

  1.原始碼

 1 package cn.itcast.jdbc;
 2 
 3 import java.sql.Connection;
 4 import java.sql.SQLException;
 5 
 6 import javax.sql.DataSource;
 7 
 8 import com.mchange.v2.c3p0.ComboPooledDataSource;
 9 
10 /**
11  * 使用本類的方法,必須提供c3p0-copnfig.xml檔案
12  * @author qdmmy6
13  */
14 public class JdbcUtils {
15     // 餓漢式
16     private static DataSource ds = new ComboPooledDataSource();
17     
18     /**
19      * 它為null表示沒有事務
20      * 它不為null表示有事務
21      * 當開啟事務時,需要給它賦值
22      * 當結束事務時,需要給它賦值為null
23      * 並且在開啟事務時,讓dao的多個方法共享這個Connection
24      */
25     private static ThreadLocal<Connection> tl = new ThreadLocal<Connection>();
26     
27     public static DataSource getDataSource() {
28         return ds;
29     }
30     
31     /**
32      * dao使用本方法來獲取連線
33      * @return
34      * @throws SQLException
35      */
36     public static Connection getConnection() throws SQLException {
37         /*
38          * 如果有事務,返回當前事務的con
39          * 如果沒有事務,通過連線池返回新的con
40          */
41         Connection con = tl.get();//獲取當前執行緒的事務連線
42         if(con != null) return con;
43         return ds.getConnection();
44     }
45     
46     /**
47      * 開啟事務
48      * @throws SQLException 
49      */
50     public static void beginTransaction() throws SQLException {
51         Connection con = tl.get();//獲取當前執行緒的事務連線
52         if(con != null) throw new SQLException("已經開啟了事務,不能重複開啟!");
53         con = ds.getConnection();//給con賦值,表示開啟了事務
54         con.setAutoCommit(false);//設定為手動提交
55         tl.set(con);//把當前事務連線放到tl中
56     }
57     
58     /**
59      * 提交事務
60      * @throws SQLException 
61      */
62     public static void commitTransaction() throws SQLException {
63         Connection con = tl.get();//獲取當前執行緒的事務連線
64         if(con == null) throw new SQLException("沒有事務不能提交!");
65         con.commit();//提交事務
66         con.close();//關閉連線
67         con = null;//表示事務結束!
68         tl.remove();
69     }
70     
71     /**
72      * 回滾事務
73      * @throws SQLException 
74      */
75     public static void rollbackTransaction() throws SQLException {
76         Connection con = tl.get();//獲取當前執行緒的事務連線
77         if(con == null) throw new SQLException("沒有事務不能回滾!");
78         con.rollback();
79         con.close();
80         con = null;
81         tl.remove();
82     }
83     
84     /**
85      * 釋放Connection
86      * @param con
87      * @throws SQLException 
88      */
89     public static void releaseConnection(Connection connection) throws SQLException {
90         Connection con = tl.get();//獲取當前執行緒的事務連線
91         if(connection != con) {//如果引數連線,與當前事務連線不同,說明這個連線不是當前事務,可以關閉!
92             if(connection != null &&!connection.isClosed()) {//如果引數連線沒有關閉,關閉之!
93                 connection.close();
94             }
95         }
96     }
97 }

 

 2.測試程式碼

c3p0-config.xml

 1 <?xml version="1.0" encoding="UTF-8" ?>
 2 <c3p0-config>
 3     <default-config> 
 4         <property name="jdbcUrl">jdbc:mysql://localhost:3306/mydb1</property>
 5         <property name="driverClass">com.mysql.jdbc.Driver</property>
 6         <property name="user">root</property>
 7         <property name="password">root</property>
 8  
 9         <property name="acquireIncrement">3</property>
10         <property name="initialPoolSize">10</property>
11         <property name="minPoolSize">2</property>
12         <property name="maxPoolSize">10</property>
13     </default-config>
14 </c3p0-config>
 1 /**
 2  * 測試JdbcUtils類
 3  * 
 4  *
 5  */
 6 public class JdbcUtilsTest {
 7     /**
 8      * 通過C3P0連線池獲取連線物件
 9      * @throws SQLException
10      */
11     @Test
12     public void testGetConnection() throws SQLException {
13         Connection con = JdbcUtils.getConnection();//獲取連線
14         System.out.println(con);
15         JdbcUtils.releaseConnection(con);//如果引數con不是當前執行緒的連線物件,那麼關閉之
16     }
17     
18     /**
19      * 當開始事務後,呼叫getConnection()會為當前執行緒建立Connection,而且多次呼叫getConnection()返回的是同一個物件
20      * @throws SQLException 
21      */
22     @Test
23     public void testTansaction() throws SQLException {
24         JdbcUtils.beginTransaction();//開啟事務
25         Connection c1 = JdbcUtils.getConnection();//第一次獲取當前執行緒的事務連線物件
26         Connection c2 = JdbcUtils.getConnection();//第二次獲取當前執行緒的事務連線物件
27         Assert.assertEquals(true, c1 == c2);//比較兩次是否相同
28         JdbcUtils.commitTransaction();//提交事務
29     }
30 }

=========================================================================================================================================

3.TxQueryRunner

TxQueryRunner類是common-dbutils下QueryRunner類的子類,用來簡化JDBC操作。TxQueryRunner類內部使用了JdbcUtils.getConnection()類來獲取連線物件,以及使用JdbcUtils.releaseConnection()關閉連線。

  l int[] batch(String sql, Object[][] params):執行批處理,引數sql是SQL語句模板,params為引數;

  l T query(String sql, ResultSetHandler<T> rh):執行查詢,執行查詢,引數sql為要執行的查詢語句模板,rh是結果集處理,用來把結果集對映成你想要的結果;

  l T query(String sql, ResultSetHandler<T> rh, Object… params):執行查詢,引數sql為要執行的查詢語句模板,rh是結果集處理,用來把結果集對映成你想要的結果,params是sql語句的引數;

  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類中的方法。

  1.原始碼

 1 package cn.itcast.jdbc;
 2 
 3 import java.sql.Connection;
 4 import java.sql.SQLException;
 5 
 6 import org.apache.commons.dbutils.QueryRunner;
 7 import org.apache.commons.dbutils.ResultSetHandler;
 8 
 9 public class TxQueryRunner extends QueryRunner {
10 
11     @Override
12     public int[] batch(String sql, Object[][] params) throws SQLException {
13         Connection con = JdbcUtils.getConnection();
14         int[] result = super.batch(con, sql, params);
15         JdbcUtils.releaseConnection(con);
16         return result;
17     }
18 
19     @Override
20     public <T> T query(String sql, ResultSetHandler<T> rsh, Object... params)
21             throws SQLException {
22         Connection con = JdbcUtils.getConnection();
23         T result = super.query(con, sql, rsh, params);
24         JdbcUtils.releaseConnection(con);
25         return result;
26     }
27     
28     @Override
29     public <T> T query(String sql, ResultSetHandler<T> rsh) throws SQLException {
30         Connection con = JdbcUtils.getConnection();
31         T result = super.query(con, sql, rsh);
32         JdbcUtils.releaseConnection(con);
33         return result;
34     }
35 
36     @Override
37     public int update(String sql) throws SQLException {
38         Connection con = JdbcUtils.getConnection();
39         int result = super.update(con, sql);
40         JdbcUtils.releaseConnection(con);
41         return result;
42     }
43 
44     @Override
45     public int update(String sql, Object param) throws SQLException {
46         Connection con = JdbcUtils.getConnection();
47         int result = super.update(con, sql, param);
48         JdbcUtils.releaseConnection(con);
49         return result;
50     }
51 
52     @Override
53     public int update(String sql, Object... params) throws SQLException {
54         Connection con = JdbcUtils.getConnection();
55         int result = super.update(con, sql, params);
56         JdbcUtils.releaseConnection(con);
57         return result;
58     }
59 }

  2.測試程式碼

Person.java

1 public class Person {
2     private String pid;
3     private String name;
4     private int age;
5     private Date birthday;
6 7 }

PersonDao.java

 1 /**
 2  * 測試TxQueryRunner
 3  *  4  *
 5  */
 6 public class PersonDao {
 7     private QueryRunner qr = new TxQueryRunner();
 8     
 9     public void add(Person person) throws SQLException {
10         String sql = "insert into t_person values(?,?,?,?)";
11         Object[] params = {person.getPid(), 
12                 person.getName(), 
13                 person.getAge(), 
14                 new java.sql.Date(person.getBirthday().getTime())};
15         qr.update(sql, params);
16     }
17     
18     public void edit(Person person) throws SQLException {
19         String sql = "update t_person set name=?,age=?,birthday=? where pid=?";
20         Object[] params = { 
21                 person.getName(), 
22                 person.getAge(), 
23                 new java.sql.Date(person.getBirthday().getTime()),
24                 person.getPid()};
25         qr.update(sql, params);
26     }
27     
28     public void delete(String pid) throws SQLException {
29         String sql = "delete from t_person where pid=?";
30         qr.update(sql, pid);
31     }
32     
33     public Person load(String pid) throws SQLException {
34         String sql = "select * from t_person where pid=?";
35         return qr.query(sql, new BeanHandler<Person>(Person.class), pid);
36     }
37     
38     public List<Person> findAll() throws SQLException {
39         String sql = "select * from t_person";
40         return qr.query(sql, new BeanListHandler<Person>(Person.class));
41     }
42 }

PersonDaoTest.java

 1 public class PersonDaoTest {
 2     @Test
 3     public void testAdd() throws SQLException {
 4         Person p1 = new Person(CommonUtils.uuid(), "張三", 18, new Date());
 5         Person p2 = new Person(CommonUtils.uuid(), "李四", 81, new Date());
 6         Person p3 = new Person(CommonUtils.uuid(), "王五", 66, new Date());
 7         
 8         PersonDao dao = new PersonDao();
 9         dao.add(p1);
10         dao.add(p2);
11         dao.add(p3);
12     }
13     
14     @Test
15     public void testEdit() throws SQLException {
16         PersonDao dao = new PersonDao();
17         Person person = dao.load("2F371BE415984DE89781CCCA7B8734CB");
18         person.setAge(88);
19         dao.edit(person);
20     }
21     
22     @Test
23     public void testDelete() throws SQLException {
24         PersonDao dao = new PersonDao();
25         dao.delete("2F371BE415984DE89781CCCA7B8734CB");
26     }
27     
28     @Test
29     public void testFindAll() throws SQLException {
30         PersonDao dao = new PersonDao();
31         List<Person> list = dao.findAll();
32         System.out.println(list);
33     }
34 }

=========================================================================================================================================

4.MailUtils

MailUtils是用來發郵件的小工具,底層使用JavaMail完成,依賴mail.jar和activaion.jar。

  1.原始碼

MailUtils.java

 1 package cn.itcast.mail;
 2 
 3 import java.io.IOException;
 4 import java.util.List;
 5 import java.util.Properties;
 6 
 7 import javax.mail.Authenticator;
 8 import javax.mail.Message.RecipientType;
 9 import javax.mail.MessagingException;
10 import javax.mail.PasswordAuthentication;
11 import javax.mail.Session;
12 import javax.mail.Transport;
13 import javax.mail.internet.InternetAddress;
14 import javax.mail.internet.MimeBodyPart;
15 import javax.mail.internet.MimeMessage;
16 import javax.mail.internet.MimeMultipart;
17 import javax.mail.internet.MimeUtility;
18 
19 /**
20  * 
21  * @author itcast 本類只有這麼一個方法,用來發郵件!
22  */
23 public class MailUtils {
24     public static Session createSession(String host, final String username, final String password) {
25         Properties prop = new Properties();
26         prop.setProperty("mail.host", host);// 指定主機
27         prop.setProperty("mail.smtp.auth", "true");// 指定驗證為true
28 
29         // 建立驗證器
30         Authenticator auth = new Authenticator() {
31             public PasswordAuthentication getPasswordAuthentication() {
32                 return new PasswordAuthentication(username, password);
33             }
34         };
35         
36         // 獲取session物件
37         return Session.getInstance(prop, auth);
38     }
39     
40     /**
41      * 傳送指定的郵件
42      * 
43      * @param mail
44      */
45     public static void send(Session session, final Mail mail) throws MessagingException,
46             IOException {
47 
48         MimeMessage msg = new MimeMessage(session);// 建立郵件物件
49         msg.setFrom(new InternetAddress(mail.getFrom()));// 設定發件人
50         msg.addRecipients(RecipientType.TO, mail.getToAddress());// 設定收件人
51 
52         // 設定抄送
53         String cc = mail.getCcAddress();
54         if (!cc.isEmpty()) {
55             msg.addRecipients(RecipientType.CC, cc);
56         }
57 
58         // 設定暗送
59         String bcc = mail.getBccAddress();
60         if (!bcc.isEmpty()) {
61             msg.addRecipients(RecipientType.BCC, bcc);
62         }
63 
64         msg.setSubject(mail.getSubject());// 設定主題
65 
66         MimeMultipart parts = new MimeMultipart();// 建立部件集物件
67 
68         MimeBodyPart part = new MimeBodyPart();// 建立一個部件
69         part.setContent(mail.getContent(), "text/html;charset=utf-8");// 設定郵件文字內容
70         parts.addBodyPart(part);// 把部件新增到部件集中
71         
72         ///////////////////////////////////////////
73 
74         // 新增附件
75         List<AttachBean> attachBeanList = mail.getAttachs();// 獲取所有附件
76         if (attachBeanList != null) {
77             for (AttachBean attach : attachBeanList) {
78                 MimeBodyPart attachPart = new MimeBodyPart();// 建立一個部件
79                 attachPart.attachFile(attach.getFile());// 設定附件檔案
80                 attachPart.setFileName(MimeUtility.encodeText(attach
81                         .getFileName()));// 設定附件檔名
82                 String cid = attach.getCid();
83                 if(cid != null) {
84                     attachPart.setContentID(cid);
85                 }
86                 parts.addBodyPart(attachPart);
87             }
88         }
89 
90         msg.setContent(parts);// 給郵件設定內容
91         Transport.send(msg);// 發郵件
92     }
93 }

Mail.java  

  1 package cn.itcast.mail;
  2 
  3 import java.util.ArrayList;
  4 import java.util.List;
  5 
  6 /**
  7  * 表示郵件類,你需要設定:賬戶名和密碼、收件人、抄送(可選)、暗送(可選)、主題、內容,以及附件(可選)
  8  * 
  9  * 在建立了Mail物件之後
 10  * 可以呼叫它的setSubject()、setContent(),設定主題和正文
 11  * 也可以呼叫setFrom()和 addToAddress(),設定發件人,和新增收件人。
 12  * 也可以呼叫addAttch()新增附件
 13  * 建立AttachBean:new AttachBean(new File("..."), "fileName");
 14  */
 15 public class Mail {
 16     private String from;//發件人
 17     private StringBuilder toAddress = new StringBuilder();//收件人
 18     private StringBuilder ccAddress = new StringBuilder();//抄送
 19     private StringBuilder bccAddress = new StringBuilder();//暗送
 20     
 21     private String subject;//主題
 22     private String content;//正文
 23     
 24     // 附件列表
 25     private List<AttachBean> attachList = new ArrayList<AttachBean>();
 26     
 27     public Mail() {}
 28     
 29     public Mail(String from, String to) {
 30         this(from, to, null, null);
 31     }
 32     
 33     public Mail(String from, String to, String subject, String content) {
 34         this.from = from;
 35         this.toAddress.append(to);
 36         this.subject = subject;
 37         this.content = content;
 38     }
 39     
 40     /**
 41      * 返回發件人
 42      * @return
 43      */
 44     public void setFrom(String from) {
 45         this.from = from;
 46     }
 47     
 48     /**
 49      * 返回發件人
 50      * @return
 51      */
 52     public String getFrom() {
 53         return from;
 54     }
 55     
 56     /**
 57      * 返回主題
 58      */
 59     public String getSubject() {
 60         return subject;
 61     }
 62 
 63     /**
 64      * 設定主題
 65      */
 66     public void setSubject(String subject) {
 67         this.subject = subject;
 68     }
 69 
 70     /**
 71      * 獲取主題內容
 72      */
 73     public String getContent() {
 74         return content;
 75     }
 76 
 77     /**
 78      * 設定主題內容
 79      * @param content
 80      */
 81     public void setContent(String content) {
 82         this.content = content;
 83     }
 84 
 85     /**
 86      * 獲取收件人
 87      * @return
 88      */
 89     public String getToAddress() {
 90         return toAddress.toString();
 91     }
 92 
 93     /**
 94      * 獲取抄送
 95      * @return
 96      */
 97     public String getCcAddress() {
 98         return ccAddress.toString();
 99     }
100 
101     /**
102      * 獲取暗送
103      * @return
104      */
105     public String getBccAddress() {
106         return bccAddress.toString();
107     }
108 
109     /**
110      * 新增收件人,可以是多個收件人
111      * @param to
112      */
113     public void addToAddress(String to) {
114         if(this.toAddress.length() > 0) {
115             this.toAddress.append(",");
116         }
117         this.toAddress.append(to);
118     }
119 
120     /**
121      * 新增抄送人,可以是多個抄送人
122      * @param cc
123      */
124     public void addCcAddress(String cc) {
125         if(this.ccAddress.length() > 0) {
126             this.ccAddress.append(",");
127         }
128         this.ccAddress.append(cc);
129     }
130 
131     /**
132      * 新增暗送人,可以是多個暗送人
133      * @param bcc
134      */
135     public void addBccAddress(String bcc) {
136         if(this.bccAddress.length() > 0) {
137             this.bccAddress.append(",");
138         }
139         this.bccAddress.append(bcc);
140     }
141     
142     /**
143      * 新增附件,可以新增多個附件
144      * @param attachBean
145      */
146     public void addAttach(AttachBean attachBean) {
147         this.attachList.add(attachBean);
148     }
149     
150     /**
151      * 獲取所有附件
152      * @return
153      */
154     public List<AttachBean> getAttachs() {
155         return this.attachList;
156     }
157 }

2.測試程式碼

 1     /**
 2      * 測試傳送普通郵件
 3      * @throws IOException 
 4      * @throws MessagingException 
 5      */
 6     @Test
 7     public void fun() throws MessagingException, IOException {
 8         Session session = MailUtils.createSession("smtp.163.com", "itcast_cxf", "itcastitcast"); 
 9         Mail mail = new Mail("[email protected]", "[email protected]", "測試MailUtils", "這是正文!"); 
10         MailUtils.send(session, mail); 
11     }

=========================================================================================================================================

5.BaseServlet

  

  BaseServlet是用來作為其它Servlet父類的,它有如下兩個優點:

  一個Servlet多個處理方法

    BaseServlet的作用是用來簡化Servlet。通過我們需要為每個功能編寫一個Servlet,例如使用者註冊寫一個RegistServlet,使用者登入寫一個LoginServlet。如果使用BaseServlet,那麼我們可以只寫一個UserServlet,然後讓UserServlet去繼承BaseServlet,然後在UserServlet給出兩個請求處理方法,一個方法叫regist(),一個叫login()。

    BaseServlet來簡化了Servlet中請求轉發和重定向的程式碼。

  簡化了請求轉發和重定向的程式碼

    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的引數來指定要請求的方法名稱。