1 下載發送mail需要的jar包
activation.jar 與 mail.jar
2 創建 SendMail 類
3 代碼如下
import java.util.Date;
import java.util.Properties;
import javax.mail.Address;
import javax.mail.Message;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
import cn.founder.common.globals.Constants;
public class SendMail {
public int send(String tfrom, String tto, String ttitle, String tcontent) {
Properties props = new Properties();
props.put("mail.smtp.host", "smtp.263.net");//自己到網上查找網易發郵件的smtp服務地址 你的發件郵箱如果是163 你就查找163的發件服務器
props.put("mail.smtp.auth", "true");
Session s = Session.getInstance(props, null);
s.setDebug(true);
Message message = new MimeMessage(s);
try {
Address from = new InternetAddress(tfrom);
message.setFrom(from);
Address to = new InternetAddress(tto);
message.setRecipient(Message.RecipientType.TO, to);
sun.misc.BASE64Encoder enc = new sun.misc.BASE64Encoder();
message.setSubject("=?utf-8?B?"+enc.encode(ttitle.getBytes("utf-8"))+"?=");
message.setContent(tcontent, "text/html;charset=utf-8");
message.setSentDate(new Date());
message.saveChanges();
Transport transport = s.getTransport("smtp");
//第一個參數是發件服務器 第二個是你發件的郵箱名 第三個是你發件郵箱的密碼
transport.connect("smtp.263.net",”發件郵箱”,”發件郵箱密碼”);
transport.sendMessage(message, message.getAllRecipients());
transport.close();
return 0;
} catch (Exception e) {
e.printStackTrace();
return 1;
}
}
/**
* getEmailServiceIp
* @return EmailServiceIp
*/
public static void main(String[] args) {
//第一個參數 發件郵箱 第二個收件郵箱 第三個 郵件內容
new SendMail().send("yunlong090614@163.com", "1063342004@qq.com", "更改密碼校驗", "尊敬的用戶你好,您的校驗碼為:65432</br>xxxx");
}
運行中 輸入regedit
沒有修改注冊表,解決辦法是:
重新安裝JDK時注冊表中\HKEY_LOCAL_MACHINE\SOFTWARE\JavaSoft\Java Runtime Environemt\1.6 項目下的JavaHome和RuntimeLib設置沒有更新,將這兩個項目更正即可.
public class FileDownLoadTest {
private static final int TCOUNT = 10;
private CountDownLatch latch = new CountDownLatch(TCOUNT);
private long completeLength = 0;
private long fileLength;
/**
* @param args
* @throws Exception
*/
public static void main(String[] args) throws Exception {
new FileDownLoadTest().download("http://localhost:8080/test/IESSAction.docx");
}
public void download(String address) throws Exception{
ExecutorService service = Executors.newFixedThreadPool(TCOUNT);
URL url = new URL(address);
URLConnection cn = url.openConnection();
cn.setRequestProperty("Referer", "http://www.test.com");
fileLength = cn.getContentLength();
long packageLength = fileLength/TCOUNT;
long leftLength = fileLength%TCOUNT;
RandomAccessFile file = new RandomAccessFile("d:\\test.docx","rw");
//計算每個線程請求文件的開始和結束位置
long pos = 0;
long endPos = pos + packageLength;
for(int i=0; i<TCOUNT; i++){
if(leftLength >0){
endPos ++;
leftLength--;
}
service.execute(new DownLoadThread(url, file, pos, endPos));
pos = endPos;
endPos = pos + packageLength;
}
System.out.println("waiting........................................");
long begin = System.currentTimeMillis();
latch.await();
file.close();
System.out.println("end........................................");
System.out.println(System.currentTimeMillis() - begin + "ms");
service.shutdown();
}
class DownLoadThread implements Runnable{
private URL url;
private RandomAccessFile file;
private long from;
private long end;
DownLoadThread(URL url, RandomAccessFile file, long from, long end){
this.url = url;
this.file = file;
this.from = from;
this.end = end;
}
public void run() {
long pos = from;
byte[] buf = new byte[512];
try {
HttpURLConnection cn = (HttpURLConnection) url.openConnection();
cn.setRequestProperty("Range", "bytes=" + from + "-" + end);
if(cn.getResponseCode() != 200 && cn.getResponseCode()!=206){
run();
return;
}
BufferedInputStream bis = new BufferedInputStream(cn.getInputStream());
int len ;
while((len = bis.read(buf)) != -1){
// synchronized(file){
file.seek(pos);
file.write(buf, 0, len);
// }
pos += len;
completeLength +=len;
System.out.println("threadName: " + Thread.currentThread().getName()
+ "persent: " + completeLength * 100 /fileLength + "%");
}
cn.disconnect();
latch.countDown();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
/**
* @Author:何云龍
* @Version: 2012-11-16 下午03:45:16
* @Description:
*/
import jxl.*;
import java.io.*;
import jxl.write.*;
/**
* <p>
* java讀取Excel表格,復制、更新Excel工作薄
* </p>
*/
public class Test {
public static void main(String[] args) {
jxl.Workbook rwb = null;
try {
// 構建Workbook對象 只讀Workbook對象
// 直接從本地文件創建Workbook
// 從輸入流創建Workbook
InputStream is = new FileInputStream("D://Book1.xls");
rwb = Workbook.getWorkbook(is);
// Sheet(術語:工作表)就是Excel表格左下角的Sheet1,Sheet2,Sheet3但在程序中
// Sheet的下標是從0開始的
// 獲取第一張Sheet表
Sheet rs = rwb.getSheet(0);
// 獲取Sheet表中所包含的總列數
int rsColumns = rs.getColumns();
// 獲取Sheet表中所包含的總行數
int rsRows = rs.getRows();
// 獲取指這下單元格的對象引用
for (int i = 0; i < rsRows; i++) {
for (int j = 0; j < rsColumns; j++) {
Cell cell = rs.getCell(j, i);
System.out.print(cell.getContents() + " ");
}
System.out.println();
}
// 利用已經創建的Excel工作薄創建新的可寫入的Excel工作薄
jxl.write.WritableWorkbook wwb = Workbook.createWorkbook(new File(
"D://Book2.xls"), rwb);
// 讀取第一張工作表
jxl.write.WritableSheet ws = wwb.getSheet(0);
// 獲取第一個單元格對象
jxl.write.WritableCell wc = ws.getWritableCell(0, 0);
// 決斷單元格的類型,做出相應的轉化
if (wc.getType() == CellType.LABEL) {
Label l = (Label) wc;
l.setString("The value has been modified.");
}
// 寫入Excel對象
wwb.write();
wwb.close();
} catch (Exception e) {
e.printStackTrace();
} finally {
// 操作完成時,關閉對象,翻譯占用的內存空間
rwb.close();
}
}
}
使用JavaSEAPI讀取Properties文件的六種方法
1。使用java.util.Properties類的load()方法
示例:InputStreamin=lnewBufferedInputStream(newFileInputStream(name));
Propertiesp=newProperties();
p.load(in);
2。使用java.util.ResourceBundle類的getBundle()方法
示例:ResourceBundlerb=ResourceBundle.getBundle(name,Locale.getDefault());
3。使用java.util.PropertyResourceBundle類的構造函數
示例:InputStreamin=newBufferedInputStream(newFileInputStream(name));
ResourceBundlerb=newPropertyResourceBundle(in);
4。使用class變量的getResourceAsStream()方法
示例:InputStreamin=JProperties.class.getResourceAsStream(name);
Propertiesp=newProperties();
p.load(in);
5。使用class.getClassLoader()所得到的java.lang.ClassLoader的getResourceAsStream()方法
示例:InputStreamin=JProperties.class.getClassLoader().getResourceAsStream(name);
Propertiesp=newProperties();
p.load(in);
6。使用java.lang.ClassLoader類的getSystemResourceAsStream()靜態方法
示例:InputStreamin=ClassLoader.getSystemResourceAsStream(name);
Propertiesp=newProperties();
p.load(in);
補充
Servlet中可以使用javax.servlet.ServletContext的getResourceAsStream()方法
示例:InputStreamin=context.getResourceAsStream(path);
Propertiesp=newProperties();
p.load(in);
public class JDBCUtil {
Connection conn=null;
Statement stmt=null;
ResultSet rs=null;
String url="jdbc:mysql://localhost:3306/theatermanagement";
String user="root";
String psw="root";
static{
try {
Class.forName("com.mysql.jdbc.Driver");
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public Connection getConn(){
try {
conn=DriverManager.getConnection(url, user, psw);
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return conn;
}
public int update(String sql){
try {
stmt=this.getConn().createStatement();
return stmt.executeUpdate(sql);
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
return -1;
}finally{
release();
}
}
public LinkedList<Map<String,Object>> query(String sql){
LinkedList<Map<String,Object>> list=new LinkedList<Map<String,Object>>();
try {
stmt=getConn().createStatement();
rs=stmt.executeQuery(sql);
ResultSetMetaData rsmd=rs.getMetaData();
int count=rsmd.getColumnCount();
while(rs.next()){
Map<String,Object> map=new TreeMap<String,Object>();
for (int i = 0; i < count; i++) {
String key=rsmd.getColumnName(i+1);
String keyy="";
if(key.equals("")){// 聚合函數bug
System.out.println("聚合函數bug"+key);
keyy="count";
Object value=rs.getObject(1);
map.put(keyy, value);
}else{
Object value=rs.getObject(key);
map.put(key, value);
}
}
list.add(map);
}
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally{
release();
}
return list;
}
/**批量更新*/
public void excuteBatch(String[] sqls){
conn=this.getConn();
/**設置提交模式為手動提交*/
try{
conn.setAutoCommit(false);
stmt=conn.createStatement();
for(String sql:sqls){
stmt.addBatch(sql);
}
stmt.executeBatch();
/**手動提交*/
conn.commit();//事務
}catch(SQLException e){
e.printStackTrace();
}finally{
release();
}
}
/**釋放資源*/
public void release(){
if(rs!=null){
try {
rs.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if(stmt!=null){
try {
stmt.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if(conn!=null){
try {
conn.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}
public class TestCall {
public static void main(String[] args) {
try{
Connection conn=null;
CallableStatement cs=null;
Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver");
String url="jdbc:sqlserver://127.0.0.1:1433;databaseName=studentdb";
conn=DriverManager.getConnection(url,"sa","sqlserver");
String sql="{call s_insert(?,?)}";
cs=conn.prepareCall(sql);
cs.setString(1,"張三");
cs.setInt(2, 12);
int num=-1;
num=cs.executeUpdate();
System.out.println("num:"+num);
}catch (Exception e) {
e.printStackTrace();
}
}
}
}
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ParameterMetaData;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
/**
* 用戶數據庫訪問的類
*@作者Administrator
*@createTime 2011-12-5 上午11:55:18
*@version 1.0
*/
public class DButil1 {
private Connection conn;
private Statement st;
private PreparedStatement pps;
private ResultSet rs;
public String url="jdbc:oracle:thin:@localhost:1521:orcl";
private String user="hyl";
private String password="hyl";
//加載驅動、放在靜態代碼塊中,保證驅動在整個項目中只加載一次,提高效率
static{
try {
Class.forName("oracle.jdbc.driver.OracleDriver");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
/**
* 獲取連接的方法
* @return Connection 一個有效的數據庫連接
*/
public Connection getConnection()
{
try {
//注意鏈接時,要換成自己的數據庫名,數據庫用戶名及密碼
Connection con=DriverManager.getConnection(url,user,password);
return con;
} catch (SQLException e) {
e.printStackTrace();
}
return null;
}
/**
* 用于執行更新的方法,包括(insert delete update)操作
* @param sql String 類型的SQL語句
* @return Integer 表示受影響的行數
*/
public int update(String sql)
{
//定義變量用來判斷更新操作是否成功,如果返回-1說明沒有影響到更新操作的數據庫記錄條數,即更新操作失敗
int row=-1;
try {
//如果數據庫鏈接被關閉了,就要既得一個新的鏈接
if(conn==null||conn.isClosed()){
conn=getConnection();
}
//使用Connection對象conn的createStatement()創建Statement(數據庫語句對象)st
st=conn.createStatement();
//執行更新操作,返回影響的記錄條數row
row=st.executeUpdate(sql);
} catch (SQLException e) {
e.printStackTrace();
}
finally{
close();
}
return row;
}
/**
* 基于PreparedStatement的修改方法 PreparedStatement:表示預編譯的 SQL 語句的對象
* @param sql String 類型的SQL語句(insert delete update)
* @param obj 存放動態參數的數組
* @return Integer 表示受影響的行數
*/
public int update(String sql,Object ...obj)
{
try {
//獲取鏈接
if(conn==null||conn.isClosed()){
conn=getConnection();
}
//創建預編譯的 SQL 語句對象
pps=conn.prepareStatement(sql);
//定義變量length代表數組長度,也就是預處理的sql語句中的參數個數
int length=0;
//ParameterMetaData:用于獲取關于 PreparedStatement 對象中每個參數的類型和屬性信息的對象
ParameterMetaData pmd=pps.getParameterMetaData();
length=pmd.getParameterCount();
//循環將sql語句中的?設置為obj數組中對應的值,注意從1開始,所以i要加1
for(int i=0;i<length;i++)
{
pps.setObject(i+1, obj[i]);
}
//執行更新操作
return pps.executeUpdate();
} catch (SQLException e) {
e.printStackTrace();
}finally{
close();
}
return -1;
}
/**
* 獲取一條記錄的方法,要依賴于下面的queryToList方法,注意泛型的使用
* @param sql
* @return Map<String,Object>
*/
public Map<String,Object> getOneRow(String sql)
{
//執行下面的queryToList方法
List<Map<String,Object>> list=queryToList(sql);
//三目運算,查詢結果list不為空返回list中第一個對象,否則返回null
return list.size()>0?list.get(0):null;
}
/**
* 返回查詢結果列表,形如:[{TEST_NAME=aaa, TEST_NO=2, TEST_PWD=aaa}, {TEST_NAME=bbb, TEST_NO=3, TEST_PWD=bbb}...]
* @param sql
* @return List<Map<String,Object>>
*/
public List<Map<String,Object>> queryToList(String sql)
{
//創建集合列表用以保存所有查詢到的記錄
List<Map<String, Object>> list=new LinkedList<Map<String, Object>>();
try {
if(conn==null||conn.isClosed()){
conn=getConnection();
}
st=conn.createStatement();
rs=st.executeQuery(sql);
//ResultSetMetaData 是結果集元數據,可獲取關于 ResultSet 對象中列的類型和屬性信息的對象 例如:結果集中共包括多少列,每列的名稱和類型等信息
ResultSetMetaData rsmd=rs.getMetaData();
//獲取結果集中的列數
int columncount=rsmd.getColumnCount();
//while條件成立表明結果集中存在數據
while(rs.next())
{
//創建一個HashMap用于存儲一條數據
HashMap<String, Object> onerow=new HashMap<String, Object>();
//循環獲取結果集中的列名及列名所對應的值,每次循環都得到一個對象,形如:{TEST_NAME=aaa, TEST_NO=2, TEST_PWD=aaa}
for(int i=0;i<columncount;i++)
{
//獲取指定列的名稱,注意orcle中列名的大小寫
String columnName=rsmd.getColumnName(i+1);
onerow.put(columnName, rs.getObject(i+1));
}
//將獲取到的對象onewrow={TEST_NAME=aaa, TEST_NO=2, TEST_PWD=aaa}放到集合列表中
list.add(onerow);
}
}catch (SQLException e) {
e.printStackTrace();
}
finally{
close();
}
return list;
}
/**
* 返回查詢結果列表,使用的是預編繹SQL 語句對象PreparedStatement
* 形如:[{TEST_NAME=aaa, TEST_NO=2, TEST_PWD=aaa}, {TEST_NAME=bbb, TEST_NO=3, TEST_PWD=bbb}]
* @param sql
* @param paramValues
* @return List<Map<String,Object>>
*/
public List<Map<String,Object>> queryWithParam(String sql,Object ...paramValues){
//創建集合列表用以保存所有查詢到的記錄
List<Map<String, Object>> list=new LinkedList<Map<String, Object>>();
try {
if(conn==null||conn.isClosed()){
conn=getConnection();
}
pps = conn.prepareStatement(sql);
for (int i = 0; i < paramValues.length; i++) {
pps.setObject(i + 1, paramValues[i]);
}
rs = pps.executeQuery();
//ResultSetMetaData 是結果集元數據,可獲取關于 ResultSet 對象中列的類型和屬性信息的對象 例如:結果集中共包括多少列,每列的名稱和類型等信息
ResultSetMetaData rsmd=rs.getMetaData();
//獲取結果集中的列數
int columncount=rsmd.getColumnCount();
//while條件成立表明結果集中存在數據
while (rs.next()) {
//創建一個HashMap用于存儲一條數據
HashMap<String, Object> onerow=new HashMap<String, Object>();
//循環獲取結果集中的列名及列名所對應的值,每次循環都得到一個對象,形如:{TEST_NAME=aaa, TEST_NO=2, TEST_PWD=aaa}
for(int i=0;i<columncount;i++)
{
//獲取指定列的名稱,注意orcle中列名的大小寫
String columnName=rsmd.getColumnName(i+1);
onerow.put(columnName, rs.getObject(i+1));
}
//將獲取到的對象onewrow={TEST_NAME=aaa, TEST_NO=2, TEST_PWD=aaa}放到集合列表中
list.add(onerow);
}
}catch (SQLException e) {
e.printStackTrace();
}
finally{
close();
}
return list;
}
/**
* 實現oracle分頁功能
* @param sql
* @param pagesize
* @param pagenow
* @return PageBean
*/
public PageBean getPage(String sql,int pagesize,int pagenow)
{
PageBean pb=new PageBean();
int end=pagenow*pagesize;
int start=end-pagesize+1;
String exesql="select a.* from (select t.*,rownum as rowindex from ("+sql+") t where rownum<="+end+" ) a where a.rowindex>="+start;
String countsql="select count(*) as rowcount from ("+sql+")";
pb.setResult(queryToList(exesql));
pb.setPagenow(pagenow);
pb.setPagesize(pagesize);
Map<String,Object> map=this.getOneRow(countsql);
int rows=Integer.parseInt(map.get("ROWCOUNT").toString());
pb.setRows(rows);
int pages=rows%pagesize==0?rows/pagesize:rows/pagesize+1;
pb.setPages(pages);
pb.setSql(sql);
return pb;
}
/**
* 關閉數據庫各種資源Connection Statement PreparedStatement ResultSet的方法
*/
private void close()
{
if(rs!=null)
{
try {
rs.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if(st!=null)
{
try {
st.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if(pps!=null){
try {
pps.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
try {
if(conn!=null&&!conn.isClosed())
{
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
} catch (SQLException e) {
e.printStackTrace();
}
}
}
一、什么是log4j
Log4j 是Apache的一個開放源代碼項目,通過使用Log4j,我們可以控制日志信息輸送的目的地是控制臺、文件、GUI組件、甚至是套接口服務器、NT的事件記錄器、UNIX Syslog守護進程等;我們也可以控制每一條日志的輸出格式;通過定義每一條日志信息的級別,我們能夠更加細致地控制日志的生成過程。最令人感興趣的就是,這些可以通過一個配置文件來靈活地進行配置,而不需要修改應用的代碼。
二、日志簡介
日志指在程序中插入語句以提供調試信息。使用日志能夠監視程序的執行。例如,用戶利用日志可以獲得關于應用程序故障的完整信息。用戶可以將調試語句(如 System.out.println)插入到程序中以獲得詳細的調試信息。
三、項目中為什么要用log4j
大家在編程時經常不可避免地要使用到一些日志操作,比如開發階段的調試信息、運行時的日志記錄及審計。調查顯示,日志代碼占代碼總量的4%。通常大家可以簡單地使用System.out.println()語句輸出日志信息,但是往往會有一些判斷,比如:
if (someCondition)
{
System.out.println("some information.");
}
這些判斷造成正常的程序邏輯中混雜了大量的輸出語句。而在開發階段寫下的這些判斷僅為了調試的語句,在開發完成時需要查找并移除。部署運行后,尤其是在一些企業應用系統中,還經常需要進一步調試,這時就遇到了更大的麻煩。所以,我們需要一套完備的、靈活的、可配置的日志工具log4J就是優秀的選擇。
四、log4j組件
Log4j 由 logger、appender 和 layout 三個組件組成。可以通過同名的 Java 類訪問 Log4j 的這三個組件。
Logger - 在執行應用程序時,接收日志語句生成的日志請求。它是一種重要的日志處理組件, 可以通過 log4j API 的 logger 類對其進行訪問。它的方法有:debug、info、warn、error、fatal 和 log。這些方法用于記錄消息。
Appender - 管理日志語句的輸出結果。執行日志語句時,Logger 對象將接收來自日志語句的記錄請求。此請求是通過 logger 發送至 appender 的。然后,Appender 將輸出結果寫入到用戶選擇的目的地。對于不同的日志目的地,提供不同的 appender 類型。這些 appender 包括:用于文件的 file appender、用于數據庫的 JDBC appender 和用于 SMTP 服務器的 SMTP appender。
Layout - 用于指定 appender 將日志語句寫入日志目的地所采用的格式。appender 可以用來格式化輸出結果的各種布局包括:簡單布局、模式布局和 HTML 布局。
import org.apache.commons.lang.StringUtils;
/**
* 身份證工具類
*
* @author June
* @version 1.0, 2010-06-17
*/
public class IdcardUtils extends StringUtils {
/** 中國公民身份證號碼最小長度。 */
public static final int CHINA_ID_MIN_LENGTH = 15;
/** 中國公民身份證號碼最大長度。 */
public static final int CHINA_ID_MAX_LENGTH = 18;
/** 省、直轄市代碼表 */
public static final String cityCode[] = {
"11", "12", "13", "14", "15", "21", "22", "23", "31", "32", "33", "34", "35", "36", "37", "41",
"42", "43", "44", "45", "46", "50", "51", "52", "53", "54", "61", "62", "63", "64", "65", "71",
"81", "82", "91"
};
/** 每位加權因子 */
public static final int power[] = {
7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2
};
/** 第18位校檢碼 */
public static final String verifyCode[] = {
"1", "0", "X", "9", "8", "7", "6", "5", "4", "3", "2"
};
/** 最低年限 */
public static final int MIN = 1930;
public static Map<String, String> cityCodes = new HashMap<String, String>();
/** 臺灣身份首字母對應數字 */
public static Map<String, Integer> twFirstCode = new HashMap<String, Integer>();
/** 香港身份首字母對應數字 */
public static Map<String, Integer> hkFirstCode = new HashMap<String, Integer>();
static {
cityCodes.put("11", "北京");
cityCodes.put("12", "天津");
cityCodes.put("13", "河北");
cityCodes.put("14", "山西");
cityCodes.put("15", "內蒙古");
cityCodes.put("21", "遼寧");
cityCodes.put("22", "吉林");
cityCodes.put("23", "黑龍江");
cityCodes.put("31", "上海");
cityCodes.put("32", "江蘇");
cityCodes.put("33", "浙江");
cityCodes.put("34", "安徽");
cityCodes.put("35", "福建");
cityCodes.put("36", "江西");
cityCodes.put("37", "山東");
cityCodes.put("41", "河南");
cityCodes.put("42", "湖北");
cityCodes.put("43", "湖南");
cityCodes.put("44", "廣東");
cityCodes.put("45", "廣西");
cityCodes.put("46", "海南");
cityCodes.put("50", "重慶");
cityCodes.put("51", "四川");
cityCodes.put("52", "貴州");
cityCodes.put("53", "云南");
cityCodes.put("54", "西藏");
cityCodes.put("61", "陜西");
cityCodes.put("62", "甘肅");
cityCodes.put("63", "青海");
cityCodes.put("64", "寧夏");
cityCodes.put("65", "新疆");
cityCodes.put("71", "臺灣");
cityCodes.put("81", "香港");
cityCodes.put("82", "澳門");
cityCodes.put("91", "國外");
twFirstCode.put("A", 10);
twFirstCode.put("B", 11);
twFirstCode.put("C", 12);
twFirstCode.put("D", 13);
twFirstCode.put("E", 14);
twFirstCode.put("F", 15);
twFirstCode.put("G", 16);
twFirstCode.put("H", 17);
twFirstCode.put("J", 18);
twFirstCode.put("K", 19);
twFirstCode.put("L", 20);
twFirstCode.put("M", 21);
twFirstCode.put("N", 22);
twFirstCode.put("P", 23);
twFirstCode.put("Q", 24);
twFirstCode.put("R", 25);
twFirstCode.put("S", 26);
twFirstCode.put("T", 27);
twFirstCode.put("U", 28);
twFirstCode.put("V", 29);
twFirstCode.put("X", 30);
twFirstCode.put("Y", 31);
twFirstCode.put("W", 32);
twFirstCode.put("Z", 33);
twFirstCode.put("I", 34);
twFirstCode.put("O", 35);
hkFirstCode.put("A", 1);
hkFirstCode.put("B", 2);
hkFirstCode.put("C", 3);
hkFirstCode.put("R", 18);
hkFirstCode.put("U", 21);
hkFirstCode.put("Z", 26);
hkFirstCode.put("X", 24);
hkFirstCode.put("W", 23);
hkFirstCode.put("O", 15);
hkFirstCode.put("N", 14);
}
/**
* 將15位身份證號碼轉換為18位
*
* @param idCard
* 15位身份編碼
* @return 18位身份編碼
*/
public static String conver15CardTo18(String idCard) {
String idCard18 = "";
if (idCard.length() != CHINA_ID_MIN_LENGTH) {
return null;
}
if (isNum(idCard)) {
// 獲取出生年月日
String birthday = idCard.substring(6, 12);
Date birthDate = null;
try {
birthDate = new SimpleDateFormat("yyMMdd").parse(birthday);
} catch (ParseException e) {
e.printStackTrace();
}
Calendar cal = Calendar.getInstance();
if (birthDate != null)
cal.setTime(birthDate);
// 獲取出生年(完全表現形式,如:2010)
String sYear = String.valueOf(cal.get(Calendar.YEAR));
idCard18 = idCard.substring(0, 6) + sYear + idCard.substring(8);
// 轉換字符數組
char[] cArr = idCard18.toCharArray();
if (cArr != null) {
int[] iCard = converCharToInt(cArr);
int iSum17 = getPowerSum(iCard);
// 獲取校驗位
String sVal = getCheckCode18(iSum17);
if (sVal.length() > 0) {
idCard18 += sVal;
} else {
return null;
}
}
} else {
return null;
}
return idCard18;
}
/**
* 驗證身份證是否合法
*/
public static boolean validateCard(String idCard) {
String card = idCard.trim();
if (validateIdCard18(card)) {
return true;
}
if (validateIdCard15(card)) {
return true;
}
String[] cardval = validateIdCard10(card);
if (cardval != null) {
if (cardval[2].equals("true")) {
return true;
}
}
return false;
}
/**
* 驗證18位身份編碼是否合法
*
* @param idCard 身份編碼
* @return 是否合法
*/
public static boolean validateIdCard18(String idCard) {
boolean bTrue = false;
if (idCard.length() == CHINA_ID_MAX_LENGTH) {
// 前17位
String code17 = idCard.substring(0, 17);
// 第18位
String code18 = idCard.substring(17, CHINA_ID_MAX_LENGTH);
if (isNum(code17)) {
char[] cArr = code17.toCharArray();
if (cArr != null) {
int[] iCard = converCharToInt(cArr);
int iSum17 = getPowerSum(iCard);
// 獲取校驗位
String val = getCheckCode18(iSum17);
if (val.length() > 0) {
if (val.equalsIgnoreCase(code18)) {
bTrue = true;
}
}
}
}
}
return bTrue;
}
/**
* 驗證15位身份編碼是否合法
*
* @param idCard
* 身份編碼
* @return 是否合法
*/
public static boolean validateIdCard15(String idCard) {
if (idCard.length() != CHINA_ID_MIN_LENGTH) {
return false;
}
if (isNum(idCard)) {
String proCode = idCard.substring(0, 2);
if (cityCodes.get(proCode) == null) {
return false;
}
String birthCode = idCard.substring(6, 12);
Date birthDate = null;
try {
birthDate = new SimpleDateFormat("yy").parse(birthCode.substring(0, 2));
} catch (ParseException e) {
e.printStackTrace();
}
Calendar cal = Calendar.getInstance();
if (birthDate != null)
cal.setTime(birthDate);
if (!valiDate(cal.get(Calendar.YEAR), Integer.valueOf(birthCode.substring(2, 4)),
Integer.valueOf(birthCode.substring(4, 6)))) {
return false;
}
} else {
return false;
}
return true;
}
/**
* 驗證10位身份編碼是否合法
*
* @param idCard 身份編碼
* @return 身份證信息數組
* <p>
* [0] - 臺灣、澳門、香港 [1] - 性別(男M,女F,未知N) [2] - 是否合法(合法true,不合法false)
* 若不是身份證件號碼則返回null
* </p>
*/
public static String[] validateIdCard10(String idCard) {
String[] info = new String[3];
String card = idCard.replaceAll("[\\(|\\)]", "");
if (card.length() != 8 && card.length() != 9 && idCard.length() != 10) {
return null;
}
if (idCard.matches("^[a-zA-Z][0-9]{9}$")) { // 臺灣
info[0] = "臺灣";
System.out.println("11111");
String char2 = idCard.substring(1, 2);
if (char2.equals("1")) {
info[1] = "M";
System.out.println("MMMMMMM");
} else if (char2.equals("2")) {
info[1] = "F";
System.out.println("FFFFFFF");
} else {
info[1] = "N";
info[2] = "false";
System.out.println("NNNN");
return info;
}
info[2] = validateTWCard(idCard) ? "true" : "false";
} else if (idCard.matches("^[1|5|7][0-9]{6}\\(?[0-9A-Z]\\)?$")) { // 澳門
info[0] = "澳門";
info[1] = "N";
// TODO
} else if (idCard.matches("^[A-Z]{1,2}[0-9]{6}\\(?[0-9A]\\)?$")) { // 香港
info[0] = "香港";
info[1] = "N";
info[2] = validateHKCard(idCard) ? "true" : "false";
} else {
return null;
}
return info;
}
/**
* 驗證臺灣身份證號碼
*
* @param idCard
* 身份證號碼
* @return 驗證碼是否符合
*/
public static boolean validateTWCard(String idCard) {
String start = idCard.substring(0, 1);
String mid = idCard.substring(1, 9);
String end = idCard.substring(9, 10);
Integer iStart = twFirstCode.get(start);
Integer sum = iStart / 10 + (iStart % 10) * 9;
char[] chars = mid.toCharArray();
Integer iflag = 8;
for (char c : chars) {
sum = sum + Integer.valueOf(c + "") * iflag;
iflag--;
}
return (sum % 10 == 0 ? 0 : (10 - sum % 10)) == Integer.valueOf(end) ? true : false;
}
/**
* 驗證香港身份證號碼(存在Bug,部份特殊身份證無法檢查)
* <p>
* 身份證前2位為英文字符,如果只出現一個英文字符則表示第一位是空格,對應數字58 前2位英文字符A-Z分別對應數字10-35
* 最后一位校驗碼為0-9的數字加上字符"A","A"代表10
* </p>
* <p>
* 將身份證號碼全部轉換為數字,分別對應乘9-1相加的總和,整除11則證件號碼有效
* </p>
*
* @param idCard 身份證號碼
* @return 驗證碼是否符合
*/
public static boolean validateHKCard(String idCard) {
String card = idCard.replaceAll("[\\(|\\)]", "");
Integer sum = 0;
if (card.length() == 9) {
sum = (Integer.valueOf(card.substring(0, 1).toUpperCase().toCharArray()[0]) - 55) * 9
+ (Integer.valueOf(card.substring(1, 2).toUpperCase().toCharArray()[0]) - 55) * 8;
card = card.substring(1, 9);
} else {
sum = 522 + (Integer.valueOf(card.substring(0, 1).toUpperCase().toCharArray()[0]) - 55) * 8;
}
String mid = card.substring(1, 7);
String end = card.substring(7, 8);
char[] chars = mid.toCharArray();
Integer iflag = 7;
for (char c : chars) {
sum = sum + Integer.valueOf(c + "") * iflag;
iflag--;
}
if (end.toUpperCase().equals("A")) {
sum = sum + 10;
} else {
sum = sum + Integer.valueOf(end);
}
return (sum % 11 == 0) ? true : false;
}
/**
* 將字符數組轉換成數字數組
*
* @param ca
* 字符數組
* @return 數字數組
*/
public static int[] converCharToInt(char[] ca) {
int len = ca.length;
int[] iArr = new int[len];
try {
for (int i = 0; i < len; i++) {
iArr[i] = Integer.parseInt(String.valueOf(ca[i]));
}
} catch (NumberFormatException e) {
e.printStackTrace();
}
return iArr;
}
/**
* 將身份證的每位和對應位的加權因子相乘之后,再得到和值
*
* @param iArr
* @return 身份證編碼。
*/
public static int getPowerSum(int[] iArr) {
int iSum = 0;
if (power.length == iArr.length) {
for (int i = 0; i < iArr.length; i++) {
for (int j = 0; j < power.length; j++) {
if (i == j) {
iSum = iSum + iArr[i] * power[j];
}
}
}
}
return iSum;
}
/**
* 將power和值與11取模獲得余數進行校驗碼判斷
*
* @param iSum
* @return 校驗位
*/
public static String getCheckCode18(int iSum) {
String sCode = "";
switch (iSum % 11) {
case 10:
sCode = "2";
break;
case 9:
sCode = "3";
break;
case 8:
sCode = "4";
break;
case 7:
sCode = "5";
break;
case 6:
sCode = "6";
break;
case 5:
sCode = "7";
break;
case 4:
sCode = "8";
break;
case 3:
sCode = "9";
break;
case 2:
sCode = "x";
break;
case 1:
sCode = "0";
break;
case 0:
sCode = "1";
break;
}
return sCode;
}
/**
* 根據身份編號獲取年齡
*
* @param idCard
* 身份編號
* @return 年齡
*/
public static int getAgeByIdCard(String idCard) {
int iAge = 0;
if (idCard.length() == CHINA_ID_MIN_LENGTH) {
idCard = conver15CardTo18(idCard);
}
String year = idCard.substring(6, 10);
Calendar cal = Calendar.getInstance();
int iCurrYear = cal.get(Calendar.YEAR);
iAge = iCurrYear - Integer.valueOf(year);
return iAge;
}
/**
* 根據身份編號獲取生日
*
* @param idCard 身份編號
* @return 生日(yyyyMMdd)
*/
public static String getBirthByIdCard(String idCard) {
Integer len = idCard.length();
if (len < CHINA_ID_MIN_LENGTH) {
return null;
} else if (len == CHINA_ID_MIN_LENGTH) {
idCard = conver15CardTo18(idCard);
}
return idCard.substring(6, 14);
}
/**
* 根據身份編號獲取生日年
*
* @param idCard 身份編號
* @return 生日(yyyy)
*/
public static Short getYearByIdCard(String idCard) {
Integer len = idCard.length();
if (len < CHINA_ID_MIN_LENGTH) {
return null;
} else if (len == CHINA_ID_MIN_LENGTH) {
idCard = conver15CardTo18(idCard);
}
return Short.valueOf(idCard.substring(6, 10));
}
/**
* 根據身份編號獲取生日月
*
* @param idCard
* 身份編號
* @return 生日(MM)
*/
public static Short getMonthByIdCard(String idCard) {
Integer len = idCard.length();
if (len < CHINA_ID_MIN_LENGTH) {
return null;
} else if (len == CHINA_ID_MIN_LENGTH) {
idCard = conver15CardTo18(idCard);
}
return Short.valueOf(idCard.substring(10, 12));
}
/**
* 根據身份編號獲取生日天
*
* @param idCard
* 身份編號
* @return 生日(dd)
*/
public static Short getDateByIdCard(String idCard) {
Integer len = idCard.length();
if (len < CHINA_ID_MIN_LENGTH) {
return null;
} else if (len == CHINA_ID_MIN_LENGTH) {
idCard = conver15CardTo18(idCard);
}
return Short.valueOf(idCard.substring(12, 14));
}
/**
* 根據身份編號獲取性別
*
* @param idCard 身份編號
* @return 性別(M-男,F-女,N-未知)
*/
public static String getGenderByIdCard(String idCard) {
String sGender = "N";
if (idCard.length() == CHINA_ID_MIN_LENGTH) {
idCard = conver15CardTo18(idCard);
}
String sCardNum = idCard.substring(16, 17);
if (Integer.parseInt(sCardNum) % 2 != 0) {
sGender = "男";
} else {
sGender = "女";
}
return sGender;
}
/**
* 根據身份編號獲取戶籍省份
*
* @param idCard 身份編碼
* @return 省級編碼。
*/
public static String getProvinceByIdCard(String idCard) {
int len = idCard.length();
String sProvince = null;
String sProvinNum = "";
if (len == CHINA_ID_MIN_LENGTH || len == CHINA_ID_MAX_LENGTH) {
sProvinNum = idCard.substring(0, 2);
}
sProvince = cityCodes.get(sProvinNum);
return sProvince;
}
/**
* 數字驗證
*
* @param val
* @return 提取的數字。
*/
public static boolean isNum(String val) {
return val == null || "".equals(val) ? false : val.matches("^[0-9]*$");
}
/**
* 驗證小于當前日期 是否有效
*
* @param iYear
* 待驗證日期(年)
* @param iMonth
* 待驗證日期(月 1-12)
* @param iDate
* 待驗證日期(日)
* @return 是否有效
*/
public static boolean valiDate(int iYear, int iMonth, int iDate) {
Calendar cal = Calendar.getInstance();
int year = cal.get(Calendar.YEAR);
int datePerMonth;
if (iYear < MIN || iYear >= year) {
return false;
}
if (iMonth < 1 || iMonth > 12) {
return false;
}
switch (iMonth) {
case 4:
case 6:
case 9:
case 11:
datePerMonth = 30;
break;
case 2:
boolean dm = ((iYear % 4 == 0 && iYear % 100 != 0) || (iYear % 400 == 0))
&& (iYear > MIN && iYear < year);
datePerMonth = dm ? 29 : 28;
break;
default:
datePerMonth = 31;
}
return (iDate >= 1) && (iDate <= datePerMonth);
}
}