Hibernate分页的设计实现
使用Hibernate,在进行查询分页的操作上,是具有非常大的灵活性,Hibernate会首先尝试用特定数据库的分页sql,如果没用,再尝试Scrollable,如果不行,最后采用rset.next()移动的办法。
Hibernate 可以实现分页查询,例如:
从第2万条开始取出100条记录
Query q = session.createQuery("from Cat as c");
q.setFirstResult(20000);
q.setMaxResults(100);
List l = q.list();
那么Hibernate底层如何实现分页的呢?实际上Hibernate的查询定义在net.sf.hibernate.loader.Loader这个类里面,仔细阅读该类代码,就可以把问题彻底搞清楚。
Hibernate2.0.3的Loader源代码第480行以下:
if (useLimit) sql = dialect.getLimitString(sql);
PreparedStatement st = session.getBatcher().prepareQueryStatement(sql, scrollable);
如果相应的数据库定义了限定查询记录的sql语句,那么直接使用特定数据库的sql语句。
然后来看net.sf.hibernate.dialect.MySQLDialect:
public boolean supportsLimit() {
return true;
}
public String getLimitString(String sql) {
StringBuffer pagingSelect = new StringBuffer(100);
pagingSelect.append(sql);
pagingSelect.append(" limit ?, ?");
return pagingSelect.toString();
}
这是MySQL的专用分页语句,再来看net.sf.hibernate.dialect.Oracle9Dialect:
public boolean supportsLimit() {
return true;
}
public String getLimitString(String sql) {
StringBuffer pagingSelect = new StringBuffer(100);
pagingSelect.append("select * from ( select row_.*, rownum rownum_ from ( ");
pagingSelect.append(sql);
pagingSelect.append(" ) row_ where rownum <= ?) where rownum_ > ?");
return pagingSelect.toString();
}
Oracle采用嵌套3层的查询语句结合rownum来实现分页,这在Oracle上是最快的方式,如果只是一层或者两层的查询语句的rownum不能支持order by。
除此之外,Interbase,PostgreSQL,HSQL也支持分页的sql语句,在相应的Dialect里面,大家自行参考。
如果数据库不支持分页的SQL语句,那么根据在配置文件里面
#hibernate.jdbc.use_scrollable_resultset true
默认是true,如果你不指定为false,那么Hibernate会使用JDBC2.0的scrollable result来实现分页,看Loader第430行以下:
if ( session.getFactory().useScrollableResultSets() ) {
// we can go straight to the first required row
rs.absolute(firstRow);
}
else {
// we need to step through the rows one row at a time (slow)
for ( int m=0; m<firstRow; m++ ) rs.next();
}
如果支持scrollable result,使用ResultSet的absolute方法直接移到查询起点,如果不支持的话,使用循环语句,rs.next一点点的移过去。
可见使用Hibernate,在进行查询分页的操作上,是具有非常大的灵活性,Hibernate会首先尝试用特定数据库的分页sql,如果没用,再尝试Scrollable,如果不行,最后采用rset.next()移动的办法。
在查询分页代码中使用Hibernate的一大好处是,既兼顾了查询分页的性能,同时又保证了代码在不同的数据库之间的可移植性。
jsp分页显示
<%@ page contentType="text/html;charset=gb2312" %>
<%@ page language="java" import="java.sql.*" %>
<script language="javascript">
function newwin(url) {
var
newwin=window.open(url,"newwin","toolbar=no,location=no,directories=no,status=no,
menubar=no,scrollbars=yes,resizable=yes,width=600,height=450");
newwin.focus();
return false;
}
</script>
<script LANGUAGE="javascript">
function submit10()
{
self.location.replace("fenye1.jsp")
}
</script>
<%//变量声明
java.sql.Connection sqlCon; //数据库连接对象
java.sql.Statement sqlStmt; //SQL语句对象
java.sql.ResultSet sqlRst; //结果集对象
java.lang.String strCon; //数据库连接字符串
java.lang.String strSQL; //SQL语句
int intPageSize; //一页显示的记录数
int intRowCount; //记录总数
int intPageCount; //总页数
int intPage; //待显示页码
java.lang.String strPage;
int i;
//设置一页显示的记录数
intPageSize = 4;
//取得待显示页码
strPage = request.getParameter("page");
if(strPage==null){//表明在QueryString中没有page这一个参数,此时显示第一页数据
intPage = 1;
}
else{//将字符串转换成整型
intPage = java.lang.Integer.parseInt(strPage);
if(intPage<1) intPage = 1;
}
//装载JDBC驱动程序
Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
//设置数据库连接字符串
strCon = "jdbc:odbc:heyang";
//连接数据库
sqlCon = java.sql.DriverManager.getConnection(strCon,"sa","");
//创建一个可以滚动的只读的SQL语句对象
sqlStmt =
sqlCon.createStatement(java.sql.ResultSet.TYPE_SCROLL_INSENSITIVE,java.sql.Result
Set.CONCUR_READ_ONLY);//准备SQL语句
strSQL = "select user_id,user_name from userinfo order by user_id desc";
//执行SQL语句并获取结果集
sqlRst = sqlStmt.executeQuery(strSQL);
//获取记录总数
sqlRst.last();//??光标在最后一行
intRowCount = sqlRst.getRow();//获得当前行号
//记算总页数
intPageCount = (intRowCount+intPageSize-1) / intPageSize;
//调整待显示的页码
if(intPage>intPageCount) intPage = intPageCount;
%>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
<title>会员管理</title>
</head>
<body>
<form method="POST" action="fenye1.jsp">
第<%=intPage%>页 共<%=intPageCount%>页
<%if(intPage<intPageCount){%><a
href="fenye1.jsp?page=<%=intPage+1%>">下一页
</a><%}%> <%if(intPage>1){%><a href="fenye1.jsp?page=<%=intPage-1%>">
上一页</a><%}%>
转到第:<input type="text" name="page" size="8"> 页
<span><input class=buttonface type=´submit´ value=´GO´ name=´cndok´></span>
</form>
<table border="1" cellspacing="0" cellpadding="0">
<tr>
<th>ID</th>
<th>用户名</th>
<th width=´8%´>删除</th>
</tr>
<%
if(intPageCount>0){
//将记录指针定位到待显示页的第一条记录上
sqlRst.absolute((intPage-1) * intPageSize + 1);
//显示数据
i = 0;
String user_id,user_name;
while(i<intPageSize && !sqlRst.isAfterLast()){
user_id=sqlRst.getString(1);
user_name=sqlRst.getString(2);
%>
<tr>
<td><%=user_id%></td>
<td><%=user_name%></td>
<td width=´8%´ align=´center´><a href="delete.jsp?user_id=<%=user_id%>"
onClick="return newwin(this.href);">删除</a></td>
</tr>
<%
sqlRst.next();
i++;
}
}
%>
</table>
</body>
</html>
<%
//关闭结果集
sqlRst.close();
//关闭SQL语句对象
sqlStmt.close();
//关闭数据库
sqlCon.close();
%
全方位清理浮动
清除浮动一个凡是做页面的人都会遇到的一个东西,但是是否大家都能够清楚的知道,全方位的了解呢?于是一闲下来了马上写了这样的一篇文章,不能讲面面俱到,然而基本能将我所知道的倾囊相授了。
我们粗略的一起来看看清除浮动的办法一共有多少个(IE里面用zoom:1就不写了,下一个专题再写)。对应的DEMO
- 采用伪类:after进行后续空制的高度位零的伪类层清除
- 采用CSS overflow:auto的方式撑高
- 采用CSS overflow:hidden的方式产生怪异适应
- 采用display:table将对象变成table形式
- 采用div标签,以及css的clear属性
- 采用br标签,以及css的clear属性
- 采用br标签,以及其自身HTML的clear属性
粗略的看,他们都能将问题解决;然而他们另外一方面又有着各自的利弊。(一一对应)
- 优点结构语义化完全正确,不会产生其余的怪异问题。
缺点复用方式不当容易造成代码量急剧增大。
建议最外层轻浮动时使用,或清晰模块化复用方式的人使用。 - 优点结构语义化完全正确,代码量极少。
缺点多个嵌套后,点击最外层的轻浮动框会遭成最外层至最内层内容全选(FF);或者在mouseover造成宽度改变时会出现最外层模块有滚动条(IE)。
建议内个模块使用,请勿嵌套。 - 优点结构语义化完全正确,代码量极少。
缺点内容增多时候极易不会自动换行而内容被隐藏掉。
建议宽度固定时使用,请勿嵌套。 - 优点结构语义化完全正确,代码量极少。
缺点盒模型属性已经改变,可想而知奇异事件自然多得你数都数不到。
建议如果你不想改Bug改死你的话,最好不要使用;不过可以作为alpha版本当中临时性的忽悠下测试。 - 优点代码量极少,复用性极高。
缺点完全不能完美的适应语义化,不利于改版以及需求变更。
建议初学者使用,可以让你快速的解决浮动问题。 - 优点语义化程度比第5种情况要更优;代码量极少,复用性极高。
缺点语义化依旧不完美,不利于改版以及需求变更。
建议初学者使用,可以让你快速的解决浮动问题。 - 优点语义化程度比第5、6种情况要更优;代码量最少,复用性极高。
缺点语义化依旧不完美,不利于改版以及需求变更。
建议引导初学者思维升级时使用,让其明白与其用classname来控制一种表现,倒不如回归到WEB1.0的时代的网页直接用html属性来控制表现,毕竟后者的代码量更少。
最后,列举完毕。然而我想有必要和大家道歉,关于之前转载鬼的那篇文章;非常后悔的是当初改了鬼的标题将“最简单”改成了“最优”,以致于后面误导了很多的同学。所以重新写了一篇给大家分享。
div+css 布局最精简代码建议
如何使网站速度快,需要精简代码,那么如何精简代码呢?div+CSS 布局最精简代码建议,使用div+css布局做到最精简的代码,以达升网站速度的目的。
1、css样式尽量合并成一个外部文件,采用link方式导入到网页中来,可以减少不少内嵌在网页中的css代码。
2、多用全局样式,比如网页中只有一个h1标签,那么直接在css文件中定义h1的样式,如h1{......},而不要给h1标签加class或者id来定义样式,这样一来就可以省略class=""或id="",整个网页精简下来就可以简洁不少代码。
3、多采用父级继承样式控制,在div中尽量使用不同标签来控制网页表现形式,比如一个div中需要有3个不同颜色的文字,这样做同样可以减少不少的class和id。
<div>
第一种文字
<span>第二种文字</span>
<font>第三种文字</font>
</div>
css样式可以这样写:
div { color: #000}
div span { color: #f00}
div font { color: #0f0}
C#解析HTML
用System.Net.WebClient下载Web Page存到本地文件或者String中,用正则表达式来分析。这个方法可以用在Web Crawler等需要分析很多Web Page的应用中。
估计这也是大家最直接,最容易想到的一个方法。
所有的href都抽取出来:
using System;
using System.Net;
using System.Text;
using System.Text.RegularExpressions;
namespace HttpGet
{
class Class1
{
[STAThread]
static void Main(string[] args)
{
System.Net.WebClient client = new WebClient();
byte[] page = client.DownloadData("http://www.google.com");
string content = System.Text.Encoding.UTF8.GetString(page);
string regex = "href=["¹](http://|./|/)?w+(.w+)*(/w+(.w+)?)*(/|?w*=w*(&w*=w*)*)?["¹]";
Regex re = new Regex(regex);
MatchCollection matches = re.Matches(content);
System.Collections.IEnumerator enu = matches.GetEnumerator();
while (enu.MoveNext() && enu.Current != null)
{
Match match = (Match)(enu.Current);
Console.Write(match.Value + " ");
}
}
}
}
个人认为这是.net平台下解析html不错的解决方案,基本上能够满足我们对html的解析工作。
自己做了个实例:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using Winista.Text.HtmlParser;
using Winista.Text.HtmlParser.Lex;
using Winista.Text.HtmlParser.Util;
using Winista.Text.HtmlParser.Tags;
using Winista.Text.HtmlParser.Filters;
namespace HTMLParser
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
AddUrl();
}
private void btnParser_Click(object sender, EventArgs e)
{
#region 获得网页的html
try
{
txtHtmlWhole.Text = "";
string url = CBUrl.SelectedItem.ToString().Trim();
System.Net.WebClient aWebClient = new System.Net.WebClient();
aWebClient.Encoding = System.Text.Encoding.Default;
string html = aWebClient.DownloadString(url);
txtHtmlWhole.Text = html;
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
#endregion
#region 分析网页html节点
Lexer lexer = new Lexer(this.txtHtmlWhole.Text);
Parser parser = new Parser(lexer);
NodeList htmlNodes = parser.Parse(null);
this.treeView1.Nodes.Clear();
this.treeView1.Nodes.Add("root");
TreeNode treeRoot = this.treeView1.Nodes[0];
for (int i = 0; i < htmlNodes.Count; i++)
{
this.RecursionHtmlNode(treeRoot, htmlNodes[i], false);
}
#endregion
}
private void RecursionHtmlNode(TreeNode treeNode, INode htmlNode, bool siblingRequired)
{
if (htmlNode == null || treeNode == null) return;
TreeNode current = treeNode;
TreeNode content ;
//current node
if (htmlNode is ITag)
{
ITag tag = (htmlNode as ITag);
if (!tag.IsEndTag())
{
string nodeString = tag.TagName;
if (tag.Attributes != null && tag.Attributes.Count > 0)
{
if (tag.Attributes["ID"] != null)
{
nodeString = nodeString + " { id="" + tag.Attributes["ID"].ToString() + "" }";
}
if (tag.Attributes["HREF"] != null)
{
nodeString = nodeString + " { href="" + tag.Attributes["HREF"].ToString() + "" }";
}
}
current = new TreeNode(nodeString);
treeNode.Nodes.Add(current);
}
}
//获取节点间的内容
if (htmlNode.Children != null && htmlNode.Children.Count > 0)
{
this.RecursionHtmlNode(current, htmlNode.FirstChild, true);
content = new TreeNode(htmlNode.FirstChild.GetText());
treeNode.Nodes.Add(content);
}
//the sibling nodes
if (siblingRequired)
{
INode sibling = htmlNode.NextSibling;
while (sibling != null)
{
this.RecursionHtmlNode(treeNode, sibling, false);
sibling = sibling.NextSibling;
}
}
}
private void AddUrl()
{
CBUrl.Items.Add("http://www.hao123.com");
CBUrl.Items.Add("http://www.sina.com");
CBUrl.Items.Add("http://www.heuet.edu.cn");
}
}
}
网络蜘蛛核心源码
using System;
using System.Collections.Generic;
// using System.Linq;
using System.Text;
using System.IO;
using System.IO.Compression;
using System.Xml;
using System.Web;
using System.Collections;
using System.Runtime.InteropServices;
using System.Net;
using System.Net.Security;
using System.Security.Authentication;
using System.Security.Cryptography.X509Certificates;
namespace Common
{
/// <summary>
/// 准备POST
/// </summary>
/// <param name="httpRequest"></param>
public delegate void OnGetPostReady(HttpWebRequest httpRequest);
/// <summary>
/// 准备取回应
/// </summary>
/// <param name="httpRequest"></param>
public delegate void OnGetResponseReady(HttpWebRequest httpRequest);
public class HttpWebHelper
{
protected HttpWebRequest httpRequest;
protected HttpWebResponse httpResponse;
protected CookieContainer cookieContainer;
protected CredentialCache credentialCache;
protected bool certificatedMode = false;
protected string certFilepath = string.Empty;
public OnGetPostReady OnGetPostReadyHandler = null;
public OnGetPostReady OnGetResponseReadyHandler = null;
protected readonly int DEFAULT_BUFFER_SIZE = 4096;
public WebProxy webProxySrv = null;
private static readonly int MyConnectionLimit = 300;
public bool CheckGotoRecv
{
get;
set;
}
public bool DoBetIsGotoRecv
{
get;
set;
}
public bool LastAccessError
{
private set;
get;
}
/// <summary>
/// 当前自动转向后的url
/// </summary>
public string CurrentUrl
{
private set;
get;
}
public string CurrentLocation
{
private set;
get;
}
public string CurSetCookie
{
set;
get;
}
public string CurSetCookie2
{
set;
get;
}
/// <summary>
/// 默认构造器
/// </summary>
public HttpWebHelper()
{
this.cookieContainer = new CookieContainer();
ServicePointManager.DefaultConnectionLimit = MyConnectionLimit;
ServicePointManager.Expect100Continue = false;
ServicePointManager.MaxServicePointIdleTime = 10000;
}
/// <summary>
/// 代理參數構造器
/// </summary>
/// <param name="wp"></param>
public HttpWebHelper(WebProxy wp) : this()
{
this.webProxySrv = wp;
}
/// <summary>
/// 需要基本认证的构造器
/// </summary>
/// <param name="cred"></param>
public HttpWebHelper(bool cred)
: this()
{
this.certificatedMode = cred;
}
public HttpWebHelper(bool cred, WebProxy wp)
: this()
{
this.certificatedMode = cred;
this.webProxySrv = wp;
}
/// <summary>
/// 基本认证和证书,refer页面
/// </summary>
/// <param name="cred"></param>
/// <param name="certFilepath"></param>
public HttpWebHelper(bool cred, string certFilepath)
: this(cred)
{
this.certFilepath = certFilepath;
}
public HttpWebHelper(bool cred, WebProxy wp, string certFilepath)
: this(cred, wp)
{
this.certFilepath = certFilepath;
}
/// <summary>
/// 提供批量用户名和密码的构造器
/// </summary>
/// <param name="uri"></param>
/// <param name="method"></param>
/// <param name="username"></param>
/// <param name="password"></param>
public HttpWebHelper(string uri, string method, string username, string password)
: this(true)
{
this.credentialCache = new CredentialCache();
this.credentialCache.Add(new Uri(uri), method, new NetworkCredential(username, password));
}
/// <summary>
/// 安全询问回调函数,直接同意
/// </summary>
/// <param name="sender"></param>
/// <param name="certificate"></param>
/// <param name="chain"></param>
/// <param name="errors"></param>
/// <returns></returns>
public bool CheckValidationResult(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors errors)
{
return true;
}
private void SetHttpRequestOptions_Accept(string url, string method, CookieCollection cc, string referUrl, bool nocache, DecompressionMethods dm, string httpAccept)
{
this.SetHttpRequestOptions(url, method, cc, referUrl, nocache, dm);
this.httpRequest.Accept = httpAccept;
}
/// <summary>
/// 设置HttpWebRequest对象
/// </summary>
/// <param name="url"></param>
/// <param name="method"></param>
/// <param name="cc"></param>
/// <param name="referUrl"></param>
/// <param name="nocache"></param>
/// <param name="dm"></param>
private void SetHttpRequestOptions(string url, string method, CookieCollection cc, string referUrl, bool nocache, DecompressionMethods dm)
{
httpRequest = (HttpWebRequest)HttpWebRequest.Create(url);
httpRequest.UnsafeAuthenticatedConnectionSharing = true;
httpRequest.ServicePoint.ConnectionLimit = MyConnectionLimit;
if (null != this.webProxySrv) httpRequest.Proxy = this.webProxySrv;
if (this.certificatedMode && url.ToLower().Substring(0, 5).Equals("https"))
{
ServicePointManager.ServerCertificateValidationCallback = new System.Net.Security.RemoteCertificateValidationCallback(CheckValidationResult);
if (null == this.credentialCache)
httpRequest.UseDefaultCredentials = true;
else
httpRequest.Credentials = this.credentialCache;
if (!string.IsNullOrEmpty(this.certFilepath))
httpRequest.ClientCertificates.Add(X509Certificate.CreateFromCertFile(this.certFilepath));
}
httpRequest.CookieContainer = this.cookieContainer;
if (!string.IsNullOrEmpty(referUrl)) httpRequest.Referer = referUrl;
httpRequest.AutomaticDecompression = dm;
httpRequest.ServicePoint.Expect100Continue = false;
httpRequest.ServicePoint.UseNagleAlgorithm = false;
httpRequest.ContentType = "application/x-www-form-urlencoded";
// httpRequest.Accept = "image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/x-shockwave-flash, */*";
// httpRequest.AllowWriteStreamBuffering = true; 默认值就是true
// httpRequest.AllowAutoRedirect = true; 默认值就是true
httpRequest.Method = method;
httpRequest.Timeout = ApplicationConfig.HTTP_REQUEST_TIMEOUT;
// 讀寫超時
//httpRequest.ReadWriteTimeout = ApplicationConfig.HTTP_REQUEST_TIMEOUT;
// httpRequest.MaximumAutomaticRedirections = 50; 默认值就是50
httpRequest.UserAgent = "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.2; .NET CLR 1.1.4322; .NET CLR 2.0.50727)";
httpRequest.Headers.Add("Accept-Language", "zh-cn");
httpRequest.Headers.Add("UA-CPU", "x86");
//httpRequest.Headers.Add("Accept-Encoding", "gzip, deflate");
if (nocache)
{
httpRequest.Headers.Add("Cache-Control", "no-cache");
//httpRequest.Headers.Add("Pragma", "no-cache");
}
if (null != cc) httpRequest.CookieContainer.Add(cc);
// 回调发起请求前事件
if(null != this.OnGetPostReadyHandler)
{
try
{
this.OnGetPostReadyHandler(this.httpRequest);
//BaseDebug.DebugPrint("KeepAlive = " + this.httpRequest.KeepAlive.ToString());
}
catch (System.Exception ex)
{
this.LastAccessError = true;
BaseDebug.DebugPrint(ex.ToString());
}
}
}
private void SetHttpRequestOptions(string url, string method, CookieCollection cc, string referUrl, string httpAccept)
{
this.SetHttpRequestOptions_Accept(url, method, cc, referUrl, false, DecompressionMethods.GZip | DecompressionMethods.Deflate, httpAccept);
}
/// <summary>
/// 重新设置某些成员
/// </summary>
private void ManualResetMember()
{
this.cookieContainer = httpRequest.CookieContainer;
this.CurrentUrl = httpRequest.Address.OriginalString;
this.CurrentLocation = httpResponse.Headers["Location"];
}
public MemoryStream GetMemoryStream(string url, string method, CookieCollection cc, string referUrl, string httpAccept)
{
MemoryStream ms = new MemoryStream();
try
{
this.SetHttpRequestOptions(url, method, cc, referUrl, "*/*");
this.httpRequest.Accept = httpAccept;
this.httpResponse = (HttpWebResponse)httpRequest.GetResponse();
// 是否收到响应
if (!this.httpRequest.HaveResponse)
{
this.httpResponse.Close();
this.httpRequest.Abort();
return ms;
}
this.ManualResetMember();
if (null != this.OnGetResponseReadyHandler)
{
try
{
this.OnGetResponseReadyHandler(this.httpRequest);
}
catch (System.Exception ex)
{
this.LastAccessError = true;
BaseDebug.DebugPrint(ex.ToString());
}
}
this.DoBetIsGotoRecv = true;
Stream sm = httpResponse.GetResponseStream();
if (null != sm && sm.CanRead)
{
//int readBytes = 0;
//byte[] buffer = new byte[DEFAULT_BUFFER_SIZE];
//while ((readBytes = sm.Read(buffer, 0, buffer.Length)) != 0)
//{
// ms.Write(buffer, 0, readBytes);
//}
BinaryReader br = new BinaryReader(sm);
byte[] bytes = br.ReadBytes(DEFAULT_BUFFER_SIZE);
while (null != bytes && bytes.Length != 0)
{
ms.Write(bytes, 0, bytes.Length);
bytes = br.ReadBytes(DEFAULT_BUFFER_SIZE);
}
br.Close();
}
if (httpResponse.Headers["Set-Cookie"] != null)
this.CurSetCookie = httpResponse.Headers["Set-Cookie"].ToString();
httpResponse.Close();
if (null != sm) sm.Close();
// 非常重要,回到开头
ms.Seek(0, SeekOrigin.Begin);
}
catch (System.Exception ex)
{
this.LastAccessError = true;
BaseDebug.DebugPrint("異常網址:" + url);
BaseDebug.DebugPrint(ex.ToString());
if (null != httpRequest) httpRequest.Abort();
}
return ms;
}
public MemoryStream SimpleGetMemoryStream(string url, string method)
{
return this.GetMemoryStream(url, method, null, null, "text/html");
}
public MemoryStream SimpleGetMemoryStream(string url, string method, string httpAccept)
{
return this.GetMemoryStream(url, method, null, null, httpAccept);
}
/// <summary>
/// 仅仅发送请求,返回所有的输出文本
/// </summary>
/// <param name="url"></param>
/// <param name="method"></param>
/// <param name="coding"></param>
/// <param name="cc"></param>
/// <param name="referUrl"></param>
/// <returns></returns>
public string SimpleDoPostWrapper(string url, string method, Encoding coding, CookieCollection cc, string referUrl)
{
string str = string.Empty;
StreamReader sr = null;
MemoryStream sm = null;
if (null == coding)
{
sm = this.GetMemoryStream(url, method, cc, referUrl, "text/html");
sr = new StreamReader(sm);
}
else
{
sm = this.GetMemoryStream(url, method, cc, referUrl, "text/html");
sr = new StreamReader(sm, coding);
}
str = sr.ReadToEnd();
sr.Close();
sm.Close();
return str;
}
public string SimpleDoPostWrapper(string url, string method)
{
return this.SimpleDoPostWrapper(url, method, null, null, null);
}
public string SimpleDoPostWrapper(string url, string method, CookieCollection cc)
{
return this.SimpleDoPostWrapper(url, method, null, cc, null);
}
public string SimpleDoPostWrapper(string url, string method, string referUrl)
{
return this.SimpleDoPostWrapper(url, method, null, null, referUrl);
}
/// <summary>
/// 上送数据,返回输出流
/// </summary>
/// <param name="url"></param>
/// <param name="data"></param>
/// <param name="method"></param>
/// <param name="coding"></param>
/// <param name="cc"></param>
/// <param name="referUrl"></param>
/// <returns></returns>
public MemoryStream GetMemoryStream(string url, string data, string method, Encoding coding, CookieCollection cc, string referUrl)
{
MemoryStream ms = new MemoryStream();
try
{
this.SetHttpRequestOptions(url, method, cc, referUrl, "text/html");
byte[] bytesData = coding.GetBytes(data);
Stream requestStream = httpRequest.GetRequestStream();
requestStream.Write(bytesData, 0, bytesData.Length);
requestStream.Flush();
requestStream.Close();
this.httpResponse = (HttpWebResponse)httpRequest.GetResponse();
// 是否收到响应
if (!this.httpRequest.HaveResponse)
{
this.httpResponse.Close();
this.httpRequest.Abort();
return ms;
}
this.ManualResetMember();
if (null != this.OnGetResponseReadyHandler)
{
try
{
this.OnGetResponseReadyHandler(this.httpRequest);
}
catch (System.Exception ex)
{
this.LastAccessError = true;
BaseDebug.DebugPrint(ex.ToString());
}
}
this.DoBetIsGotoRecv = true;
Stream sm = httpResponse.GetResponseStream();
if (null != sm && sm.CanRead)
{
//int readBytes = 0;
//byte[] buffer = new byte[DEFAULT_BUFFER_SIZE];
//while ((readBytes = sm.Read(buffer, 0, buffer.Length)) != 0)
//{
// ms.Write(buffer, 0, readBytes);
//}
BinaryReader br = new BinaryReader(sm);
byte[] bytes = br.ReadBytes(DEFAULT_BUFFER_SIZE);
while (null != bytes && bytes.Length != 0)
{
ms.Write(bytes, 0, bytes.Length);
bytes = br.ReadBytes(DEFAULT_BUFFER_SIZE);
}
br.Close();
}
if (httpResponse.Headers["Set-Cookie"] != null)
this.CurSetCookie = httpResponse.Headers["Set-Cookie"].ToString();
httpResponse.Close();
if (null != sm) sm.Close();
// 非常重要,回到开头
ms.Seek(0, SeekOrigin.Begin);
}
catch (System.Exception ex)
{
this.LastAccessError = true;
BaseDebug.DebugPrint("異常網址:" + url);
BaseDebug.DebugPrint(ex.ToString());
if (null != httpRequest) httpRequest.Abort();
}
return ms;
}
public MemoryStream SimpleGetMemoryStream(string url, string data, string method, Encoding coding)
{
return this.GetMemoryStream(url, data, method, coding, null, null);
}
public MemoryStream SimpleGetMemoryStream(string url, string data, string method, Encoding coding, string referUrl)
{
return this.GetMemoryStream(url, data, method, coding, null, referUrl);
}
/// <summary>
/// 上送,返回所有的输出文本
/// </summary>
/// <param name="url"></param>
/// <param name="data"></param>
/// <param name="method"></param>
/// <param name="coding"></param>
/// <param name="referUrl"></param>
/// <returns></returns>
public string DoPostWrapper(string url, string data, string method, Encoding coding, CookieCollection cc, string referUrl)
{
string str = string.Empty;
MemoryStream sm = this.GetMemoryStream(url, data, method, coding, cc, referUrl);
StreamReader sr = new StreamReader(sm);
str = sr.ReadToEnd();
sr.Close();
sm.Close();
return str;
}
public string DoPostWrapper(string url, string data, string method, Encoding coding)
{
return this.DoPostWrapper(url, data, method, coding, null, null);
}
public string DoPostWrapper(string url, string data, string method, Encoding coding, CookieCollection cc)
{
return this.DoPostWrapper(url, data, method, coding, cc, null);
}
public string DoPostWrapper(string url, string data, string method, Encoding coding, string referUrl)
{
return this.DoPostWrapper(url, data, method, coding, null, referUrl);
}
/// <summary>
/// 上送,返回所有的输出文本,参数是字典
/// </summary>
/// <param name="url"></param>
/// <param name="dicArguments"></param>
/// <param name="method"></param>
/// <param name="coding"></param>
/// <param name="referUrl"></param>
/// <returns></returns>
public string DoPostWrapper(string url, Dictionary<string, string> dicArguments, string method, Encoding coding, CookieCollection cc, string referUrl)
{
string data = this.BuildRequestArguments(dicArguments);
return this.DoPostWrapper(url, data, method, coding, cc, referUrl);
}
public string DoPostWrapper(string url, Dictionary<string, string> dicArguments, string method, Encoding coding)
{
return this.DoPostWrapper(url, dicArguments, method, coding, null, null);
}
public string DoPostWrapper(string url, Dictionary<string, string> dicArguments, string method, Encoding coding, CookieCollection cc)
{
return this.DoPostWrapper(url, dicArguments, method, coding, cc, null);
}
public string DoPostWrapper(string url, Dictionary<string, string> dicArguments, string method, Encoding coding, string referUrl)
{
return this.DoPostWrapper(url, dicArguments, method, coding, null, referUrl);
}
/// <summary>
/// 下载验证码,只返回内存流,调用函数要负责关闭该Stream
/// </summary>
/// <param name="url"></param>
/// <param name="method"></param>
/// <returns></returns>
public MemoryStream DownloadStream(string url, string method)
{
return this.SimpleGetMemoryStream(url, method, "*/*");
}
/// <summary>
/// 从字典中生成上传参数.提供编码定制支持
/// </summary>
/// <param name="dicArguments"></param>
/// <param name="coding"></param>
/// <returns></returns>
public string BuildRequestArguments(Dictionary<string, string> dicArguments, Encoding coding)
{
StringBuilder sb = new StringBuilder();
string str = string.Empty;
if (0 == dicArguments.Count) return str;
foreach (KeyValuePair<string, string> kvp in dicArguments)
{
if(null != coding)
sb.Append(HttpUtility.UrlEncode(kvp.Key, coding) + "=" + HttpUtility.UrlEncode(kvp.Value, coding));
else
sb.Append(HttpUtility.UrlEncode(kvp.Key) + "=" + HttpUtility.UrlEncode(kvp.Value));
// a&b
sb.Append("&");
}
str = sb.ToString();
return str.Substring(0, str.Length - 1);
}
/// <summary>
/// 从字典中生成上传的默认参数,不提供编码定制支持
/// </summary>
/// <param name="dicArguments"></param>
/// <returns></returns>
public string BuildRequestArguments(Dictionary<string, string> dicArguments)
{
return this.BuildRequestArguments(dicArguments, null);
}
/// <summary>
/// 查询cookie中的某个项的值
/// </summary>
/// <param name="key"></param>
/// <param name="domain"></param>
/// <returns></returns>
public string GetCookieValue(string key, string domain)
{
if (0 == this.cookieContainer.Count)
{
return string.Empty;
}
CookieCollection cc = this.cookieContainer.GetCookies(new Uri(domain));
return cc[key].Value;
}
/// <summary>
/// 设置cookies容器
/// </summary>
/// <param name="cc"></param>
public void SetCookieContainer(CookieContainer cc)
{
this.cookieContainer = cc;
}
/// <summary>
/// 放棄請求
/// </summary>
public bool AbortHttpRequest()
{
if(null != this.httpRequest)
{
this.httpRequest.Abort();
}
return this.CheckGotoRecv && this.DoBetIsGotoRecv;
}
}
}
Oracle 游标
create or replace
PROCEDURE proceudre_name AS
BEGIN
DECLARE
sPara VARCHAR(50);
sPara2 VARCHAR(50);
CURSOR c_cursor IS SELECT ID,Name FROM Temp_table;
BEGIN
OPEN c_cursor;
LOOP
FETCH c_cursor INTO sPara, sPara2;
EXIT WHEN c_cursor%NOTFOUND;
BEGIN
--just do what you want.
END;
END LOOP;
CLOSE c_cursor;
END;
END;
MyEclipse6.0连接SQL2000和2005
步骤:
1. 下载Microsoft SQL Server 2000 Driver for JDBC这个,并在MyEclipse 6.0中添加了引用
2. 加环境变量
CLASSPATH值%JAVA_HOME%in;
JAVA_HOME值C:Program FilesJavajdk1.6.0_02
修改增加path值%JAVA_HOME%in;
3. 安装SQL 2000的SP3补丁
4. 在命令下测试telnet localhost 1433正常
代码如:
import java.sql.*;
public class HelloWorld {
private static String driverName = "com.microsoft.jdbc.sqlserver.SQLServerDriver";
private static String dbURL = "jdbc:microsoft:sqlserver://localhost:1433;DatabaseName=pubs";
private static Connection dbConn = null;
public static void main(String [] args)
{
try
{
Class.forName(driverName);
dbConn = DriverManager.getConnection(dbURL,"sa","");
Statement sql = dbConn.createStatement();
ResultSet set = sql.executeQuery("select * from jobs");
while(set.next())
{
System.out.println(set.getString("job_id")+" "+
set.getString("job_desc"));
}
System.out.println("连接成功!");
dbConn.close();
} catch (ClassNotFoundException e)
{
e.printStackTrace();
} catch (SQLException e)
{
e.printStackTrace();
}
}
}
测试成功!
连2005
1. 下载sqljdbc_1.1.1501.101_chs.exe并引入
2. 更改端口为5125(用360查出的)
import java.sql.*;
public class DbConnect {
private static String driverName = "com.microsoft.sqlserver.jdbc.SQLServerDriver";
private static String dbURL = "jdbc:sqlserver://localhost:5125; DatabaseName=master";
private static Connection dbConn = null;
public static void main(String[] args) {
try
{
Class.forName(driverName);
dbConn = DriverManager.getConnection(dbURL,"sa","000000");
Statement sql = dbConn.createStatement();
ResultSet set = sql.executeQuery("SELECT * FROM spt_values");
while(set.next())
{
//System.out.println(set.getString("name")+" "+
//set.getString("number"));
System.out.println(set.getString(1));
}
System.out.println("连接成功!");
dbConn.close();
} catch (ClassNotFoundException e)
{
e.printStackTrace();
} catch (SQLException e)
{
e.printStackTrace();
}
}
}
Java加密技术
除了DES,我们还知道有DESede(TripleDES,就是3DES)、AES、Blowfish、RC2、RC4(ARCFOUR)等多种对称加密方式,其实现方式大同小异,这里介绍对称加密的另一个算法——PBE
PBE
PBE——Password-based encryption(基于密码加密)。其特点在于口令由用户自己掌管,不借助任何物理媒体;采用随机数(这里我们叫做盐)杂凑多重加密等方法保证数据的安全性。是一种简便的加密方式。
通过java代码实现如下:
import java.security.Key;
import java.util.Random;
import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.PBEKeySpec;
import javax.crypto.spec.PBEParameterSpec;
/** *//**
* PBE安全编码组件
*
*/
public abstract class PBECoder extends Coder {
/** *//**
* 支持以下任意一种算法
*
* <pre>
* PBEWithMD5AndDES
* PBEWithMD5AndTripleDES
* PBEWithSHA1AndDESede
* PBEWithSHA1AndRC2_40
* </pre>
*/
public static final String ALGORITHM = "PBEWITHMD5andDES";
/** *//**
* 盐初始化
*
* @return
* @throws Exception
*/
public static byte[] initSalt() throws Exception {
byte[] salt = new byte[8];
Random random = new Random();
random.nextBytes(salt);
return salt;
}
/** *//**
* 转换密钥<br>
*
* @param password
* @return
* @throws Exception
*/
private static Key toKey(String password) throws Exception {
PBEKeySpec keySpec = new PBEKeySpec(password.toCharArray());
SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(ALGORITHM);
SecretKey secretKey = keyFactory.generateSecret(keySpec);
return secretKey;
}
/** *//**
* 加密
*
* @param data
* 数据
* @param password
* 密码
* @param salt
* 盐
* @return
* @throws Exception
*/
public static byte[] encrypt(byte[] data, String password, byte[] salt)
throws Exception {
Key key = toKey(password);
PBEParameterSpec paramSpec = new PBEParameterSpec(salt, 100);
Cipher cipher = Cipher.getInstance(ALGORITHM);
cipher.init(Cipher.ENCRYPT_MODE, key, paramSpec);
return cipher.doFinal(data);
}
/** *//**
* 解密
*
* @param data
* 数据
* @param password
* 密码
* @param salt
* 盐
* @return
* @throws Exception
*/
public static byte[] decrypt(byte[] data, String password, byte[] salt)
throws Exception {
Key key = toKey(password);
PBEParameterSpec paramSpec = new PBEParameterSpec(salt, 100);
Cipher cipher = Cipher.getInstance(ALGORITHM);
cipher.init(Cipher.DECRYPT_MODE, key, paramSpec);
return cipher.doFinal(data);
}
}
再给出一个测试类:
import static org.junit.Assert.*;
import org.junit.Test;
/** *//**
*
* @version 1.0
* @since 1.0
*/
public class PBECoderTest {
@Test
public void test() throws Exception {
String inputStr = "abc";
System.err.println("原文: " + inputStr);
byte[] input = inputStr.getBytes();
String pwd = "efg";
System.err.println("密码: " + pwd);
byte[] salt = PBECoder.initSalt();
byte[] data = PBECoder.encrypt(input, pwd, salt);
System.err.println("加密后: " + PBECoder.encryptBASE64(data));
byte[] output = PBECoder.decrypt(data, pwd, salt);
String outputStr = new String(output);
System.err.println("解密后: " + outputStr);
assertEquals(inputStr, outputStr);
}
}
控制台输出:
原文: abc
密码: efg
加密后: iCZ0uRtaAhE=
解密后: abc
RSA
这种算法1978年就出现了,它是第一个既能用于数据加密也能用于数字签名的算法。它易于理解和操作,也很流行。算法的名字以发明者的名字命名:Ron Rivest, AdiShamir 和Leonard Adleman.这种加密算法的特点主要是密钥的变化,上文我们看到DES只有一个密钥。相当于只有一把钥匙,如果这把钥匙丢了,数据也就不安全了。RSA同时有两把钥匙,公钥与私钥。同时支持数字签名。数字签名的意义在于,对传输过来的数据进行校验。确保数据在传输工程中不被修改。
流程分析:
1、甲方构建密钥对儿,将公钥公布给乙方,将私钥保留。
2、甲方使用私钥加密数据,然后用私钥对加密后的数据签名,发送给乙方签名以及加密后的数据;乙方使用公钥、签名来验证待解密数据是否有效,如果有效使用公钥对数据解密。
3、乙方使用公钥加密数据,向甲方发送经过加密后的数据;甲方获得加密数据,通过私钥解密。
通过java代码实现如下:
import java.security.Key;
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.Signature;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.HashMap;
import java.util.Map;
import javax.crypto.Cipher;
/** *//**
* RSA安全编码组件
*
* @version 1.0
* @since 1.0
*/
public abstract class RSACoder extends Coder {
public static final String KEY_ALGORITHM = "RSA";
public static final String SIGNATURE_ALGORITHM = "MD5withRSA";
private static final String PUBLIC_KEY = "RSAPublicKey";
private static final String PRIVATE_KEY = "RSAPrivateKey";
/** *//**
* 用私钥对信息生成数字签名
*
* @param data
* 加密数据
* @param privateKey
* 私钥
*
* @return
* @throws Exception
*/
public static String sign(byte[] data, String privateKey) throws Exception {
// 解密由base64编码的私钥
byte[] keyBytes = decryptBASE64(privateKey);
// 构造PKCS8EncodedKeySpec对象
PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
// KEY_ALGORITHM 指定的加密算法
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
// 取私钥匙对象
PrivateKey priKey = keyFactory.generatePrivate(pkcs8KeySpec);
// 用私钥对信息生成数字签名
Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);
signature.initSign(priKey);
signature.update(data);
return encryptBASE64(signature.sign());
}
/** *//**
* 校验数字签名
*
* @param data
* 加密数据
* @param publicKey
* 公钥
* @param sign
* 数字签名
*
* @return 校验成功返回true 失败返回false
* @throws Exception
*
*/
public static boolean verify(byte[] data, String publicKey, String sign)
throws Exception {
// 解密由base64编码的公钥
byte[] keyBytes = decryptBASE64(publicKey);
// 构造X509EncodedKeySpec对象
X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes);
// KEY_ALGORITHM 指定的加密算法
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
// 取公钥匙对象
PublicKey pubKey = keyFactory.generatePublic(keySpec);
Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);
signature.initVerify(pubKey);
signature.update(data);
// 验证签名是否正常
return signature.verify(decryptBASE64(sign));
}
/** *//**
* 解密<br>
* 用私钥解密
*
* @param data
* @param key
* @return
* @throws Exception
*/
public static byte[] decryptByPrivateKey(byte[] data, String key)
throws Exception {
// 对密钥解密
byte[] keyBytes = decryptBASE64(key);
// 取得私钥
PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
Key privateKey = keyFactory.generatePrivate(pkcs8KeySpec);
// 对数据解密
Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
cipher.init(Cipher.DECRYPT_MODE, privateKey);
return cipher.doFinal(data);
}
/** *//**
* 解密<br>
* 用私钥解密
*
* @param data
* @param key
* @return
* @throws Exception
*/
public static byte[] decryptByPublicKey(byte[] data, String key)
throws Exception {
// 对密钥解密
byte[] keyBytes = decryptBASE64(key);
// 取得公钥
X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes);
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
Key publicKey = keyFactory.generatePublic(x509KeySpec);
// 对数据解密
Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
cipher.init(Cipher.DECRYPT_MODE, publicKey);
return cipher.doFinal(data);
}
/** *//**
* 加密<br>
* 用公钥加密
*
* @param data
* @param key
* @return
* @throws Exception
*/
public static byte[] encryptByPublicKey(byte[] data, String key)
throws Exception {
// 对公钥解密
byte[] keyBytes = decryptBASE64(key);
// 取得公钥
X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes);
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
Key publicKey = keyFactory.generatePublic(x509KeySpec);
// 对数据加密
Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
return cipher.doFinal(data);
}
/** *//**
* 加密<br>
* 用私钥加密
*
* @param data
* @param key
* @return
* @throws Exception
*/
public static byte[] encryptByPrivateKey(byte[] data, String key)
throws Exception {
// 对密钥解密
byte[] keyBytes = decryptBASE64(key);
// 取得私钥
PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
Key privateKey = keyFactory.generatePrivate(pkcs8KeySpec);
// 对数据加密
Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
cipher.init(Cipher.ENCRYPT_MODE, privateKey);
return cipher.doFinal(data);
}
/** *//**
* 取得私钥
*
* @param keyMap
* @return
* @throws Exception
*/
public static String getPrivateKey(Map<String, Object> keyMap)
throws Exception {
Key key = (Key) keyMap.get(PRIVATE_KEY);
return encryptBASE64(key.getEncoded());
}
/** *//**
* 取得公钥
*
* @param keyMap
* @return
* @throws Exception
*/
public static String getPublicKey(Map<String, Object> keyMap)
throws Exception {
Key key = (Key) keyMap.get(PUBLIC_KEY);
return encryptBASE64(key.getEncoded());
}
/** *//**
* 初始化密钥
*
* @return
* @throws Exception
*/
public static Map<String, Object> initKey() throws Exception {
KeyPairGenerator keyPairGen = KeyPairGenerator
.getInstance(KEY_ALGORITHM);
keyPairGen.initialize(1024);
KeyPair keyPair = keyPairGen.generateKeyPair();
// 公钥
RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();
// 私钥
RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();
Map<String, Object> keyMap = new HashMap<String, Object>(2);
keyMap.put(PUBLIC_KEY, publicKey);
keyMap.put(PRIVATE_KEY, privateKey);
return keyMap;
}
}
再给出一个测试类:
import static org.junit.Assert.*;
import org.junit.Before;
import org.junit.Test;
import java.util.Map;
/** *//**
*
* @version 1.0
* @since 1.0
*/
public class RSACoderTest {
private String publicKey;
private String privateKey;
@Before
public void setUp() throws Exception {
Map<String, Object> keyMap = RSACoder.initKey();
publicKey = RSACoder.getPublicKey(keyMap);
privateKey = RSACoder.getPrivateKey(keyMap);
System.err.println("公钥: " + publicKey);
System.err.println("私钥: " + privateKey);
}
@Test
public void test() throws Exception {
System.err.println("公钥加密——私钥解密");
String inputStr = "abc";
byte[] data = inputStr.getBytes();
byte[] encodedData = RSACoder.encryptByPublicKey(data, publicKey);
byte[] decodedData = RSACoder.decryptByPrivateKey(encodedData,
privateKey);
String outputStr = new String(decodedData);
System.err.println("加密前: " + inputStr + " " + "解密后: " + outputStr);
assertEquals(inputStr, outputStr);
}
@Test
public void testSign() throws Exception {
System.err.println("私钥加密——公钥解密");
String inputStr = "sign";
byte[] data = inputStr.getBytes();
byte[] encodedData = RSACoder.encryptByPrivateKey(data, privateKey);
byte[] decodedData = RSACoder
.decryptByPublicKey(encodedData, publicKey);
String outputStr = new String(decodedData);
System.err.println("加密前: " + inputStr + " " + "解密后: " + outputStr);
assertEquals(inputStr, outputStr);
System.err.println("私钥签名——公钥验证签名");
// 产生签名
String sign = RSACoder.sign(encodedData, privateKey);
System.err.println("签名: " + sign);
// 验证签名
boolean status = RSACoder.verify(encodedData, publicKey, sign);
System.err.println("状态: " + status);
assertTrue(status);
}
}
Console代码:
公钥:
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCYU/+I0+z1aBl5X6DUUOHQ7FZpmBSDbKTtx89J
EcB64jFCkunELT8qiKly7fzEqD03g8ALlu5XvX+bBqHFy7YPJJP0ekE2X3wjUnh2NxlqpH3/B/xm
1ZdSlCwDIkbijhBVDjA/bu5BObhZqQmDwIxlQInL9oVz+o6FbAZCyHBd7wIDAQAB
私钥:
MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAJhT/4jT7PVoGXlfoNRQ4dDsVmmY
FINspO3Hz0kRwHriMUKS6cQtPyqIqXLt/MSoPTeDwAuW7le9f5sGocXLtg8kk/R6QTZffCNSeHY3
GWqkff8H/GbVl1KULAMiRuKOEFUOMD9u7kE5uFmpCYPAjGVAicv2hXP6joVsBkLIcF3vAgMBAAEC
gYBvZHWoZHmS2EZQqKqeuGr58eobG9hcZzWQoJ4nq/CarBAjw/VovUHE490uK3S9ht4FW7Yzg3LV
/MB06Huifh6qf/X9NQA7SeZRRC8gnCQk6JuDIEVJOud5jU+9tyumJakDKodQ3Jf2zQtNr+5ZdEPl
uwWgv9c4kmpjhAdyMuQmYQJBANn6pcgvyYaia52dnu+yBUsGkaFfwXkzFSExIbi0MXTkhEb/ER/D
rLytukkUu5S5ecz/KBa8U4xIslZDYQbLz5ECQQCy5dutt7RsxN4+dxCWn0/1FrkWl2G329Ucewm3
QU9CKu4D+7Kqdj+Ha3lXP8F0Etaaapi7+EfkRUpukn2ItZV/AkEAlk+I0iphxT1rCB0Q5CjWDY5S
Df2B5JmdEG5Y2o0nLXwG2w44OLct/k2uD4cEcuITY5Dvi/4BftMCZwm/dnhEgQJACIktJSnJwxLV
o9dchENPtlsCM9C/Sd2EWpqISSUlmfugZbJBwR5pQ5XeMUqKeXZYpP+HEBj1nS+tMH9u2/IGEwJA
fL8mZiZXan/oBKrblAbplNcKWGRVD/3y65042PAEeghahlJMiYquV5DzZajuuT0wbJ5xQuZB01+X
nfpFpBJ2dw==
公钥加密——私钥解密
加密前: abc
解密后: abc
公钥:
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDdOj40yEB48XqWxmPILmJAc7UecIN7F32etSHF
9rwbuEh3+iTPOGSxhoSQpOED0vOb0ZIMkBXZSgsxLaBSin2RZ09YKWRjtpCA0kDkiD11gj4tzTiM
l9qq1kwSK7ZkGAgodEn3yIILVmQDuEImHOXFtulvJ71ka07u3LuwUNdB/wIDAQAB
私钥:
MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBAN06PjTIQHjxepbGY8guYkBztR5w
g3sXfZ61IcX2vBu4SHf6JM84ZLGGhJCk4QPS85vRkgyQFdlKCzEtoFKKfZFnT1gpZGO2kIDSQOSI
PXWCPi3NOIyX2qrWTBIrtmQYCCh0SffIggtWZAO4QiYc5cW26W8nvWRrTu7cu7BQ10H/AgMBAAEC
gYEAz2JWBizjI31bqhP4XiP9PuY5F3vqBW4T+L9cFbQiyumKJc58yzTWUAUGKIIn3enXLG7dNqGr
mbJro4JeFIJ3CiVDpXR9+FluIgI4SXm7ioGKF2NOMA9LR5Fu82W+pLfpTN2y2SaLYWEDZyp53BxY
j9gUxaxi1MQs+C1ZgDF2xmECQQDy70bQntbRfysP+ppCtd56YRnES1Tyekw0wryS2tr+ivQJl7JF
gp5rPAOXpgrq36xHDwUspQ0sJ0vj0O7ywxr1AkEA6SAaLhrJJrYucC0jxwAhUYyaPN+aOsWymaRh
9jA/Wc0wp29SbGTh5CcMuGpXm1g0M+FKW3dGiHgS3rVUKim4owJAbnxgapUzAgiiHxxMeDaavnHW
9C2GrtjsO7qtZOTgYI/1uT8itvZW8lJTF+9OW8/qXE76fXl7ai9dFnl5kzMk2QJBALfHz/vCsArt
mkRiwY6zApE4Z6tPl1V33ymSVovvUzHnOdD1SKQdD5t+UV/crb3QVi8ED0t2B0u0ZSPfDT/D7kMC
QDpwdj9k2F5aokLHBHUNJPFDAp7a5QMaT64gv/d48ITJ68Co+v5WzLMpzJBYXK6PAtqIhxbuPEc2
I2k1Afmrwyw=
私钥加密——公钥解密
加密前: sign
解密后: sign
私钥签名——公钥验证签名
签名:
ud1RsIwmSC1pN22I4IXteg1VD2FbiehKUfNxgVSHzvQNIK+d20FCkHCqh9djP3h94iWnIUY0ifU+
mbJkhAl/i5krExOE0hknOnPMcEP+lZV1RbJI2zG2YooSp2XDleqrQk5e/QF2Mx0Zxt8Xsg7ucVpn
i3wwbYWs9wSzIf0UjlM=
状态:
true
简要总结一下,使用公钥加密、私钥解密,完成了乙方到甲方的一次数据传递,通过私钥加密、公钥解密,同时通过私钥签 名、公钥验证签名,完成了一次甲方到乙方的数据传递与验证,两次数据传递完成一整套的数据交互!
类似数字签名,数字信封是这样描述的:
数字信封
数字信封用加密技术来保证只有特定的收信人才能阅读信的内容。
流程:
信息发送方采用对称密钥来加密信息,然后再用接收方的公钥来加密此对称密钥(这部分称为数字信封),再将它和信息一起发送给接收方;接收方先用相应的私钥打开数字信封,得到对称密钥,然后使用对称密钥再解开信息。
js实现html表格增减
<script>
function addRow(){
// 插入一行
myNewRow = document.all.myTable.insertRow();
var lenRow = document.all.myTable.rows.length; // 计算总行数
if(lenRow > 1){
var point = myNewRow.rowIndex; // 计算当前行位置
var lenCol = document.all.myTable.rows(0).cells.length; // 计算每行有几列
// 插入lenCol个td
for (i=0; i < lenCol; i++) {
document.all.myTable.rows(point).insertCell();
document.all.myTable.rows(point).cells(i).innerHTML = parseFloat(document.all.myTable.rows(point-1).cells(i).innerHTML) + lenCol;
}
}else if(lenRow == 1){
// 原来table是0行,初始化一行
for(i = 0; i < 10; i++){
document.all.myTable.rows(0).insertCell();
document.all.myTable.rows(0).cells(i).innerHTML = i;
}
}
}
function delRow(){
document.all.myTable.deleteRow();
}
</script>
<a href="javascript: addRow()">增加一行</a>
<a href="javascript: delRow()">减去一行</a>
<table name=myTable border=1 id=myTable>
</table>
- 默认分类(20)
- J2EE(25)
- Java(56)
- PHP(55)
- SEO(10)
- 网页设计(20)
- 网站建设(37)
- 数据库(7)
- JavaScript(17)
- JQuery(6)
- MySQL(20)
- SQL Server(6)
- Access(1)
- Oracle(6)
- office(6)
- Dreamweaver(4)
- Photoshop(12)
- Flash(9)
- Fireworks(13)
- CSS(14)
- HTML(4)
- .NET(7)
- ASP(2)
- DB2(1)
- Ajax(2)
- Linux(12)
- Struts(7)
- Hibernate(8)
- Spring(2)
- Jsp(22)
- Asp(8)
- C#(3)
- C++(1)
- 网络安全(5)
- 软件工程(7)
- XML(1)
- English(2)
- 计算机等级考试(2)
- 计算机病毒(4)
- 个人日志(76)
- 互联网(15)
- ActionScript(10)
- Android(3)
- 数据结构与算法(1)
- 游戏策略(3)
- 美文翻译(2)
- 编程开发(19)
- 计算机应用(4)
- 计算机(10)
- Unity3d(6)
- 其他(1)
- egret(1)