Pages

2011年8月13日 星期六

自動擷取憑證與Https頁面資料

在寫JSP使用Redirect的時候,如果是導向HTTPS頁面,也可能發生某些異常。
1. java.net.MalformedURLException: unknown protocol https
ANS: 使用的方法不是 HTTPS 的方式,將jce.jar與jsse.jar導入classpath,在使用https連線函式
2. 頁面停留過久
ANS: 就像打開IE一樣,會叫你點選接受憑證,這時用程式跑就自動停住了,居然不會timeout

<%@ page import="java.net.URL"%>
<%@ page import="java.net.URLEncoder"%>
<%@ page import="java.net.URLConnection"%>

<%@ page import="javax.net.ssl.HttpsURLConnection"%>
<%@ page import="javax.net.ssl.HostnameVerifier"%>
<%@ page import="javax.net.ssl.HttpsURLConnection"%>
<%@ page import="javax.net.ssl.SSLContext"%>
<%@ page import="javax.net.ssl.SSLSession"%>
<%@ page import="javax.net.ssl.TrustManager"%>
<%@ page import="javax.net.ssl.X509TrustManager"%>
<%@ page import="javax.security.cert.X509Certificate"%>
<%@ page import="javax.security.cert.CertificateException"%>
<%@ page import="java.security.SecureRandom"%>

/***
* more code
* skip
*/

/***********憑證擷取開始**************/
TrustManager[] trustAllCerts = new TrustManager[] { new X509TrustManager() {
  public java.security.cert.X509Certificate[] getAcceptedIssuers() {
    return null;
  }

  public void checkClientTrusted(java.security.cert.X509Certificate[] certs,String authType) {
  }

  public void checkServerTrusted(java.security.cert.X509Certificate[] certs,String authType) {
  }
} };

HostnameVerifier dummyHostnameVerifier = new HostnameVerifier() {
  public boolean verify(String hostname, SSLSession session) {
    return true;
  }
};
SSLContext sc = SSLContext.getInstance("SSL");
sc.init(null, trustAllCerts, new SecureRandom());
HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
HttpsURLConnection.setDefaultHostnameVerifier(dummyHostnameVerifier);
/***********憑證擷取結束**************/

/***********擷取HTTPS頁面開始**************/
String httpsURL = "<https網址>"
try{
  url = new URL(httpsURL);

  Httpshurlconnection hurlc = (Httpshurlconnection) url.openConnection();
  hurlc.setRequestMethod("POST");
  InputStream inputStream = hurlc.getInputStream();
  LineNumberReader reader = new LineNumberReader(new InputStreamReader(inputStream));
  while (true) {
    tmp = reader.readLine();
    if (tmp == null)
      break;
    out.print(tmp);
  }
} catch (Exception e) {
  e.printStack();
}
/***********憑證擷取結束**************/

/***
* more code
* skip
*/

【CMD】建立以日期為主的資料夾

Windows XP & 2003   system
c:\> md d:\%Date:~0,4%%Date:~5,2%%Date:~8,2%

Windows 2k system
c:\> md d:\%Date:~4,4%%Date:~9,2%%Date:~12,2%



Microsoft JDBC 連接 URL 範例


在下列範例中,範例程式碼會在連接 URL 中設定各種連接屬性,然後呼叫 DriverManager 類別的 getConnection 方法,以傳回SQLServerConnection 物件。
接著,範例程式碼會使用 SQLServerConnection 物件的 createStatement 方法建立 SQLServerStatement 物件,然後呼叫 executeQuery方法來執行 SQL 陳述式。
最後,範例會使用從 executeQuery 方法傳回的 SQLServerResultSet 物件,重複執行 SQL 陳述式所傳回的結果。


import java.sql.*;

public class connectURL {

   public static void main(String[] args) {

      // Create a variable for the connection string.
      String connectionUrl = "jdbc:sqlserver://localhost:1433;" +
         "databaseName=AdventureWorks;user=UserName;password=*****";

      // Declare the JDBC objects.
      Connection con = null;
      Statement stmt = null;
      ResultSet rs = null;

      try {
         // Establish the connection.
         Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver");
         con = DriverManager.getConnection(connectionUrl);

         // Create and execute an SQL statement that returns some data.
         String SQL = "SELECT TOP 10 * FROM Person.Contact";
         stmt = con.createStatement();
         rs = stmt.executeQuery(SQL);

         // Iterate through the data in the result set and display it.
         while (rs.next()) {
            System.out.println(rs.getString(4) + " " + rs.getString(6));
         }
         rs.close();
         rs = null;
         stmt.close();
         stmt = null;
         con.close();
         con = null;
      }

      // Handle any errors that may have occurred.
      catch (Exception e) {
         e.printStackTrace();
      }
      finally {
         if (rs != null) try { rs.close(); } catch(Exception e) {}
         if (stmt != null) try { stmt.close(); } catch(Exception e) {}
         if (con != null) try { con.close(); } catch(Exception e) {}
      }
   }
}

Microsoft JDBC for MS SQL Server 系統需求



JDBC
for SQL Server 2000
JAR
msbase.jar

mssqlserver.jar

msutil.jar
jar
類別庫會提供 MSSQL2000 JDBC DRIVER 的支援。




JDBC
Driver支援 JRE 1.4,但連到SQL 2005 或 2008會出現異常。



JDBC
2.0 for SQL Server 2005
JAR
sqljdbc.jar sqljdbc.jar

類別庫會提供 JDBC 2.0 的支援。


sqljdbc.jar
類別庫需要使用 Java Runtime Environment (JRE) 5.0 版。 如果您在 JRE 6.0 上使用
sqljdbc.jar,將會在連接至資料庫時擲回例外狀況。


注意:

JDBC
Driver 不支援 JRE 1.4。 使用 JDBC Driver0 時,您必須將 JRE 1.4 升級為 JRE 5.0 或更新版本。
在某些情況下,您可能必須重新編譯應用程式,因為它可能與 JDK 5.0 或更新版本不相容。 如需詳細資訊,請參閱 Sun
Microsystems 網站上的文件。



JDBC
3.0 for SQL Server 2008
JAR
sqljdbc.jar sqljdbc.jar
類別庫會提供 JDBC 3.0 的支援。


sqljdbc.jar

類別庫需要使用 Java Runtime Environment (JRE) 5.0 版。 如果您在 JRE 6.0 上使用
sqljdbc.jar,將會在連接至資料庫時擲回例外狀況。


注意:

JDBC
Driver 不支援 JRE 1.4。 使用 JDBC Driver0 時,您必須將 JRE 1.4 升級為 JRE 5.0 或更新版本。
在某些情況下,您可能必須重新編譯應用程式,因為它可能與 JDK 5.0 或更新版本不相容。 如需詳細資訊,請參閱 Sun
Microsystems 網站上的文件。
sqljdbc4.jar sqljdbc4.jar
類別庫會提供 JDBC 4.0 的支援。 它包括
sqljdbc.jar

的所有功能以及新增的 JDBC 4.0 方法。


sqljdbc4.jar

類別庫需要使用 Java Runtime Environment (JRE) 6.0 版或更新版本。 在 JRE 1.4 或 5.0 上使用
sqljdbc4.jar將會擲回例外狀況。


意:


當您的應用程式必須在 JRE 6.0 上執行時,請使用 sqljdbc4.jar,即使應用程式並未使用 JDBC 4.0 功能也一樣。


以開發來說,當然是越新版功能越強。
但是如果需要可以跨所有SQL Server版本的JDBC驅動,可以安裝JTDS來符合需求。

目前幾乎都是用jtds來開發會比較方便,因為微軟一直出新的driver來相容新的SQL Server,
導致要一直更新JDBC,對穩定性及安全性來說,實在是有點風險阿。

static final long serialVersionUID用途

private static final long serialVersionUID = 1L 此變量有什麼用途?

一般在什麼情況下加入這樣的變量?它的值有什麼要求?
你可以這樣理解:
serialVersionUID用來表明類的不同版本間的兼容性。如果你修改了此類,要修改此值。否則以前用老版本的類序列化的類恢復時會出錯。為了在反序列化時,確保類版本的兼容性,最好在每個要序列化的類中加入private static final long serialVersionUID這個屬性,具體數值自己定義。
在警告上點左鍵就可以自動添加。當然也可以去掉警告。設置:Window-->Preferences-->Java,將serializable class without serialVersionUID的設置由warning改為Ignore。然後Eclipse會重新編譯程序,那些警告信息也就消失了。

serialVersionUID用來作為Java對象序列化中的版本標示之用;
如果一個序列化類沒有聲明這樣一個static final的產量,JVM會根據各種參數為這個類計算一個;
對於同樣一個類,不同版本的JDK可能會得出不同的serivalVersionUID;


The serializable class XXX does not declare a static final serialVersionUID field of type long
serialVersionUID作用:
序列化時為了保持版本的兼容性,即在版本升級時反序列化仍保持對象的唯一性。

你可以隨便寫一個,在Eclipse中它替你生成一個,有兩種生成方式:
一個是默認的1L,比如:private static final long serialVersionUID = 1L;
一個是根據類名、接口名、成員方法及屬性等來生成一個64位的哈希字段,比如:private static final long serialVersionUID = -8940196742313994740L;之類的。

當你一個類實現了Serializable接口,如果沒有定義serialVersionUID,Eclipse會提供這個提示功能告訴你去定義之。
在Eclipse中點擊類中warning的圖標一下,Eclipse就會自動給定兩種生成的方式,如上面所述。如果不想定義它,在Eclipse的設置中也可以把它關掉的,設置如下:
Window ==> Preferences ==> Java ==> Compiler ==> Error/Warnings ==> Potential programming problems
將Serializable class without serialVersionUID的warning改成ignore即可。

如果你沒有考慮到兼容性問題時,就把它關掉,不過有這個功能是好的,只要任何類別實現了Serializable這個接口的話,如果沒有加入serialVersionUID,Eclipse都會給你warning提示,這個serialVersionUID為了讓該類別Serializable向後兼容。

如果你的類Serialized存到硬盤上面後,可是後來你卻更改了類別的field(增加或減少或改名),當你Deserialize時,就會出現Exception的,這樣就會造 ​​成不兼容性的問題。

但當serialVersionUID相同時,它就會將不一樣的field以type的預設值Deserialize,這個可以避開不兼容性的問題。

最後,不考慮兼容性的問題,我把這個warning改成ignore了。

SQL中的GETDATE() 轉換函式與產生結果

--Sql Server 中一个非常强大的日期格式化函数
Select CONVERT(varchar(100), GETDATE(), 0): 05 16 2006 10:57AM
Select CONVERT(varchar(100), GETDATE(), 1): 05/16/06
Select CONVERT(varchar(100), GETDATE(), 2): 06.05.16
Select CONVERT(varchar(100), GETDATE(), 3): 16/05/06
Select CONVERT(varchar(100), GETDATE(), 4): 16.05.06
Select CONVERT(varchar(100), GETDATE(), 5): 16-05-06
Select CONVERT(varchar(100), GETDATE(), 6): 16 05 06
Select CONVERT(varchar(100), GETDATE(), 7): 05 16, 06
Select CONVERT(varchar(100), GETDATE(), 8): 10:57:46
Select CONVERT(varchar(100), GETDATE(), 9): 05 16 2006 10:57:46:827AM
Select CONVERT(varchar(100), GETDATE(), 10): 05-16-06
Select CONVERT(varchar(100), GETDATE(), 11): 06/05/16
Select CONVERT(varchar(100), GETDATE(), 12): 060516
Select CONVERT(varchar(100), GETDATE(), 13): 16 05 2006 10:57:46:937
Select CONVERT(varchar(100), GETDATE(), 14): 10:57:46:967
Select CONVERT(varchar(100), GETDATE(), 20): 2006-05-16 10:57:47
Select CONVERT(varchar(100), GETDATE(), 21): 2006-05-16 10:57:47.157
Select CONVERT(varchar(100), GETDATE(), 22): 05/16/06 10:57:47 AM
Select CONVERT(varchar(100), GETDATE(), 23): 2006-05-16
Select CONVERT(varchar(100), GETDATE(), 24): 10:57:47
Select CONVERT(varchar(100), GETDATE(), 25): 2006-05-16 10:57:47.250
Select CONVERT(varchar(100), GETDATE(), 100): 05 16 2006 10:57AM
Select CONVERT(varchar(100), GETDATE(), 101): 05/16/2006
Select CONVERT(varchar(100), GETDATE(), 102): 2006.05.16
Select CONVERT(varchar(100), GETDATE(), 103): 16/05/2006
Select CONVERT(varchar(100), GETDATE(), 104): 16.05.2006
Select CONVERT(varchar(100), GETDATE(), 105): 16-05-2006
Select CONVERT(varchar(100), GETDATE(), 106): 16 05 2006
Select CONVERT(varchar(100), GETDATE(), 107): 05 16, 2006
Select CONVERT(varchar(100), GETDATE(), 108): 10:57:49
Select CONVERT(varchar(100), GETDATE(), 109): 05 16 2006 10:57:49:437AM
Select CONVERT(varchar(100), GETDATE(), 110): 05-16-2006
Select CONVERT(varchar(100), GETDATE(), 111): 2006/05/16
Select CONVERT(varchar(100), GETDATE(), 112): 20060516
Select CONVERT(varchar(100), GETDATE(), 113): 16 05 2006 10:57:49:513
Select CONVERT(varchar(100), GETDATE(), 114): 10:57:49:547
Select CONVERT(varchar(100), GETDATE(), 120): 2006-05-16 10:57:49
Select CONVERT(varchar(100), GETDATE(), 121): 2006-05-16 10:57:49.700
Select CONVERT(varchar(100), GETDATE(), 126): 2006-05-16T10:57:49.827
Select CONVERT(varchar(100), GETDATE(), 130): 18 ???? ?????? 1427 10:57:49:907AM
Select CONVERT(varchar(100), GETDATE(), 131): 18/04/1427 10:57:49:920AM


--常用:
Select CONVERT(varchar(100), GETDATE(), 8): 10:57:46
Select CONVERT(varchar(100), GETDATE(), 24): 10:57:47
Select CONVERT(varchar(100), GETDATE(), 108): 10:57:49
Select CONVERT(varchar(100), GETDATE(), 12): 060516
Select CONVERT(varchar(100), GETDATE(), 23): 2006-05-16

2011年8月12日 星期五

重新命名資料庫名稱

要重命名資料庫中是非常普遍的使用
SQL Server 2000的用戶:
     EXEC sp_renameDB 'oldDB' , 'newDB'
SQL Server 2005支持向後兼容, 使用ALTER DATABASE修改名稱代替
  ALTER DATABASE MODIFY NAME


通常會出現錯誤:資料庫無法獨占鎖定來進行這個動作。


通用方法:
1. 卸載資料庫
2. 附載資料庫,這時候可以改資料庫名子!
3. 把之前的使用者的對應附加上去(可能會有孤兒問題)

2011年8月9日 星期二

SQL Server Studio Manager 抓取錯誤訊息

直接利用 PRINT使用下列函式,即可印出錯誤訊息。

USE AdventureWorks2008R2;
GO
-- Verify that the stored procedure does not already exist.
IF OBJECT_ID ( 'usp_GetErrorInfo', 'P' ) IS NOT NULL 
    DROP PROCEDURE usp_GetErrorInfo;
GO

-- Create procedure to retrieve error information.
CREATE PROCEDURE usp_GetErrorInfo
AS
SELECT
     ERROR_NUMBER() AS ErrorNumber
    ,ERROR_SEVERITY() AS ErrorSeverity
    ,ERROR_STATE() AS ErrorState
    ,ERROR_PROCEDURE() AS ErrorProcedure
    ,ERROR_LINE() AS ErrorLine
    ,ERROR_MESSAGE() AS ErrorMessage;
GO

BEGIN TRY
    -- Generate divide-by-zero error.
    SELECT 1/0;
END TRY
BEGIN CATCH
    -- Execute error retrieval routine.
    EXECUTE usp_GetErrorInfo;
END CATCH;

2011年8月8日 星期一

解決 MS-SQL Server 附加資料庫導致孤兒問題

附加資料庫後,資料庫的登入名稱變成空白,且無法使用新建的相同名稱指定登入。

可使用下面指令來指定登入的使用者。

USE database1
exec sp_change_users_login 'update_one','OneUser','LoginOneUser'