Posts Tagged ‘方案’

元素水平居中方案全集

星期三, 06月 4th, 2008

先来看我一个简单XHTML/HTML文件相关代码(部分),我de目de是让#container水平居中.


<body>
<div?id=”container”>
<h1>content</h1>
<p>Lorem?ipsum?dolor?sit?amet,?consectetuer?adipiscing?elit.Phasellus?varius?eleifend.</p>
</div>
</body>

使用自适应边界(auto?margin)
水平居中任意元素de首选办法是使用边界(margin)性质(property),并把左右之值设置为auto.但您必须为#container指定一个宽度.

div#container?{
margin-left:?auto;
margin-right:?auto;
width:?168px;
}
这个方案在任何当代浏览器上都有效,即使是IE6,前提是在web标准兼容模式下(compliance?mode).不幸de是,它不会在先前版本deIE/Win中工作.我为此列一个表格:


浏览de自适应边界支持一览表?浏览器?版本?支持?
Internet Explorer 6.0, compliance?mode?是?
Internet Explorer 6.0, quirks?mode?否?
Internet Explorer 5.5 Windows?否?
Internet Explorer 5.0 Windows?否?
Internet Explorer 5.2 Macintosh?是?
Mozilla 所有当前版本?是?
Mozilla Firefox?所有版本?是?
Netscape?4.x?否?
Netscape?6.x ?是?
Opera?6.0,?7.0?Macintosh?and?Windows?是?
Safari?1.2?是?

尽管受到浏览器支持de限制,大部分设计师还是提倡您尽可能这样做.但我依然可以使用CSS应付一切情况.

使用文本排列(text-align)
此方案需要使用到text-align性质,应用给body元素并且赋予centerde值.

body{
text-align:center;
}
它公正地对待各种浏览器,十分彻底,唾手可得.然而,这是赋予文本de性质,它使#container中de文本也居中了.所以,在布局上我还得做一些额外工作:

div#container{
text-align:?left;
}
这样才可以把文本de对齐方式返回默认状状态.

综合边界和文本排列
因为文本排列向后兼容,当代浏览器也支持自适应边界,很多设计师把他们结合起来,实现跨浏览器使用.

body{
text-align:?center;
}
#container?{
margin-left:?auto;
margin-right:?auto;
border:?1px?solid?red;
width:?168px;
text-align:?left
}
唉,依然不完美,因为还是一个黑客技巧?(hack).您不得不为文本排列写下多余de规则.但现在,我可以使用更完美de跨浏览器de方案.

负边界解决方案
此方案得结合使用绝对定位(absolute?positioning?).首先,把#container绝对定位并左偏移 50%,这样,#containerde左边界就是页面分辨率de一半.下一步,把#containerde左边界设置为负值,值大小为#container宽 度(width)de一半.

#container?{
background:?#ffc?url(mid.jpg)?repeat-y?center;
position:?absolute;
left:?50%;
width:?760px;
margin-left:?-380px;
}
看,没有任何黑客技巧(no?hacks)!连Netscape?4.x都支持!

WEB页面多语言支持解决方案

星期二, 06月 3rd, 2008

首先建立语言档,在项目中加入.resx文件
例如:
message.zh-cn.resx ‘简体中文
message.zh-tw.resx ‘繁体中文
message.en ‘英文
…………..
=========================================
然后利用Name –Value 键值对 填入您要在页面上显示de语言
如:
name value
message.zh-cn.resx中:
res_loginbname 登陆名 :
message.zh-tw.resx中:
res_loginbname 登陸名 :
message.zh-cn.resx中:
res_loginbname Login Name :

=========================================
然后在Golbal.asax中加入多语言设定支持相关代码(浏览器需要支持Cookie)

‘=========================================
‘ Application_BeginRequest Event

‘ The Application_BeginRequest method is an ASP.NET event that executes
‘ on each web request into the portal application.

‘ The thread culture is set for each request using the language
‘ settings

‘=========================================
Sub Application_BeginRequest(ByVal sender As Object, ByVal e As EventArgs)
Try
If Not Request.Cookies(”resource”) Is Nothing Or Request.Cookies(”resource”).Value = “” Then
Thread.CurrentThread.CurrentCulture = CultureInfo.CreateSpecificCulture(Request.Cookies(”resource”).Value)
Else
Thread.CurrentThread.CurrentCulture = New CultureInfo(ConfigurationSettings.AppSettings(”DefaultCulture”))
End If
Thread.CurrentThread.CurrentUICulture = Thread.CurrentThread.CurrentCulture
Catch ex As Exception
Thread.CurrentThread.CurrentCulture = New CultureInfo(ConfigurationSettings.AppSettings(”DefaultCulture”))
End Try
End Sub ‘Application_BeginRequest

在Web.Config中加入如下相关代码,用于设定编码和默认语种,在Global.asax中有调用:

=========================================
<globalization requestEncoding=”utf-8″ responseEncoding=”utf-8″ />
<appSettings>
<add key=”DefaultCulture” value=”zh-cn” />
<!– zh-cn:簡體中文 zh-tw:繁體中文 en:英文 –>
</appSettings>

=========================================
页面相关代码中使用多语言支持:

Imports System.Resources

Public Class 类名
Inherits System.Web.UI.Page
Protected LocRM As ResourceManager = New ResourceManager(”项目文件名.message”, GetType(类名).Assembly)

Private Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
lblLogin.Text = LocRM.GetString(”res_login”)
End Sub
End Class


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

到这里多语言支持de工作就作完了,接下来自己去慢慢Key
message.zh-cn.resx ‘简体中文
message.zh-tw.resx ‘繁体中文
message.en ‘英文

这几个语言档吧

ASP.Net防止刷新自动触发事件的解决方案

星期二, 06月 3rd, 2008

  使用asp.net,在刷新页面de时候会自动触发服务器端de事件.举个简单de例子,如:一个注册页面,我填写完注册信息之后,如果按F5刷新之后,会自动触发到Button事件上,这样就造成了又注册了一次de麻烦.

  我先前de解决方案:用关键字查询,如有相同,则提示已有此用户.

  但是这种方案不能在没有表识de情况下使用,他会重新提交.鉴于此,我寻找了一种新de解决方案,很庆幸,在朋友de提点下,迸发了这样de解决方案,肯定有更好de解决方案,不吝赐教.

  解决思路:刷新时,捕捉KeyPress,让他触发其他无用de事件.

  1、捕捉F5事件deJavaScript

window.document.onkeydown = KeyStroke;
function KeyStroke()
{
var key = event.keyCode;
event.srcElement.releaseCapture();
if(key == 116)
{
document.getElementById(”Button1″).click();
event.keyCode=0;
event.returnValue=false;
}
}

  2、aspx页面放置一个Button

<asp:Button id=”Button1″ style=”Z-INDEX: 102; LEFT: 344px; POSITION: absolute; TOP: 408px; WIDTH: 0px;” runat=”server”
Text=”Button”></asp:Button>

  3、Button事件

private void Button1_Click(object sender, System.EventArgs e)
{
Response.Write( “You have pressed the key F5″);
}

  这个“舍车保帅”de方案,能解决刷新自动触发事件de解决方案这个小问题,如果谁有更好de方案,希望告诉我一声,不胜感激!

ASP.NET技巧:access下的分页方案

星期二, 06月 3rd, 2008

具体不多说了,只贴出相关源码~

using System;
using System.Collections.Generic;
using System.Text;
using System.Data;
using System.Data.OleDb;
using System.Web;

/**//// <summary>
/// 名称:access下de分页方案(仿sql存储过程)
/// 作者:cncxz(虫虫)
/// blog:http://cncxz.cnblogs.com
/// </summary>
public class AdoPager
{
protected string m_ConnString;
protected OleDbConnection m_Conn;

public AdoPager()
{
CreateConn(string.Empty);
}
public AdoPager(string dbPath)
{
CreateConn(dbPath);
}

private void CreateConn(string dbPath)
{
if (string.IsNullOrEmpty(dbPath))
{
string str = System.Configuration.ConfigurationManager.AppSettings["dbPath"] as string;
if (string.IsNullOrEmpty(str))
str = “~/App_Data/db.mdb”;
m_ConnString = string.Format(@”Provider=Microsoft.Jet.OLEDB.4.0;Data source={0}”, HttpContext.Current.Server.MapPath(str));
}
else
m_ConnString = string.Format(@”Provider=Microsoft.Jet.OLEDB.4.0;Data source={0}”, dbPath);

m_Conn = new OleDbConnection(m_ConnString);
}
/**//// <summary>
/// 打开连接
/// </summary>
public void ConnOpen()
{
if (m_Conn.State != ConnectionState.Open)
m_Conn.Open();
}
/**//// <summary>
/// 关闭连接
/// </summary>
public void ConnClose()
{
if (m_Conn.State != ConnectionState.Closed)
m_Conn.Close();
}

private string recordID(string query, int passCount)
{
OleDbCommand cmd = new OleDbCommand(query, m_Conn);
string result = string.Empty;
using (IDataReader dr = cmd.ExecuteReader())
{
while (dr.Read())
{
if (passCount < 1)
{
result = “,” dr.GetInt32(0);
}
passCount–;
}
}
return result.Substring(1);
}


/**//// <summary>
/// 获取当前页应该显示de记录,注意:查询中必须包含名为IDde自动编号列,若不符合您de要求,就修改一下源码吧 :)
/// </summary>
/// <param name=”pageIndex”>当前页码</param>
/// <param name=”pageSize”>分页容量</param>
/// <param name=”showString”>显示de字段</param>
/// <param name=”queryString”>查询字符串,支持联合查询</param>
/// <param name=”whereString”>查询条件,若有条件限制则必须以where 开头</param>
/// <param name=”orderString”>排序规则</param>
/// <param name=”pageCount”>传出参数:总页数统计</param>
/// <param name=”recordCount”>传出参数:总记录统计</param>
/// <returns>装载记录deDataTable</returns>
public DataTable ExecutePager(int pageIndex, int pageSize, string showString, string queryString, string whereString, string orderString, out int pageCount, out int recordCount)
{
if (pageIndex < 1) pageIndex = 1;
if (pageSize < 1) pageSize = 10;
if (string.IsNullOrEmpty(showString)) showString = “*”;
if (string.IsNullOrEmpty(orderString)) orderString = “ID desc”;
ConnOpen();
string myVw = string.Format(” ( {0} ) tempVw “, queryString);
OleDbCommand cmdCount = new OleDbCommand(string.Format(” select count(0) as recordCount from {0} {1}”, myVw, whereString), m_Conn);

recordCount = Convert.ToInt32(cmdCount.ExecuteScalar());

if ((recordCount % pageSize) > 0)
pageCount = recordCount / pageSize 1;
else
pageCount = recordCount / pageSize;
OleDbCommand cmdRecord;
if (pageIndex == 1)//第一页
{
cmdRecord = new OleDbCommand(string.Format(”select top {0} {1} from {2} {3} order by {4} “, pageSize, showString, myVw, whereString, orderString), m_Conn);
}
else if (pageIndex > pageCount)//超出总页数
{
cmdRecord = new OleDbCommand(string.Format(”select top {0} {1} from {2} {3} order by {4} “, pageSize, showString, myVw, “where 1=2″, orderString), m_Conn);
}
else
{
int pageLowerBound = pageSize * pageIndex;
int pageUpperBound = pageLowerBound - pageSize;
string recordIDs = recordID(string.Format(”select top {0} {1} from {2} {3} order by {4} “, pageLowerBound, “ID”, myVw, whereString, orderString), pageUpperBound);
cmdRecord = new OleDbCommand(string.Format(”select {0} from {1} where id in ({2}) order by {3} “, showString, myVw, recordIDs, orderString), m_Conn);

}
OleDbDataAdapter dataAdapter = new OleDbDataAdapter(cmdRecord);
DataTable dt=new DataTable();
dataAdapter.Fill(dt);
ConnClose();
return dt;
}
}

还有调用示例:html相关代码

<%@ Page Language=”C#” AutoEventWireup=”true” CodeFile=”Default.aspx.cs” Inherits=”_Default” %>

<!DOCTYPE html PUBLIC “-//W3C//DTD XHTML 1.0 Transitional//EN” “http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd“>

<html xmlns=”http://www.w3.org/1999/xhtml” >
<head runat=”server”>
<title>分页演示</title>
</head>
<body>
<form id=”form1″ runat=”server”>
<div>
<br />
转到第<asp:TextBox ID=”txtPageSize” runat=”server” Width=”29px”>1</asp:TextBox>页<asp:Button ID=”btnJump” runat=”server” Text=”Go” OnClick=”btnJump_Click” /><br />
<asp:GridView ID=”GridView1″ runat=”server” CellPadding=”4″ ForeColor=”#333333″ GridLines=”None” Width=”90%”>
<FooterStyle BackColor=”#507CD1″ Font-Bold=”True” ForeColor=”White” />
<RowStyle BackColor=”#EFF3FB” />
<EditRowStyle BackColor=”#2461BF” />
<SelectedRowStyle BackColor=”#D1DDF1″ Font-Bold=”True” ForeColor=”#333333″ />
<PagerStyle BackColor=”#2461BF” ForeColor=”White” HorizontalAlign=”Center” />
<HeaderStyle BackColor=”#507CD1″ Font-Bold=”True” ForeColor=”White” />
<AlternatingRowStyle BackColor=”White” />
</asp:GridView>
</div>
<asp:Label ID=”Label1″ runat=”server” Text=”Label”></asp:Label>
</form>
</body>
</html>

示例decodebehind相关代码

using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.Collections.Generic;

public partial class _Default : System.Web.UI.Page
{
private AdoPager mm_Pager;
protected AdoPager m_Pager
{
get{
if (mm_Pager == null)
mm_Pager = new AdoPager();
return mm_Pager;
}
}
protected void Page_Load(object sender, EventArgs e)
{
if(!IsPostBack)
LoadData();
}
private int pageIndex = 1;
private int pageSize = 20;
private int pageCount = -1;
private int recordCount = -1;

private void LoadData()
{
string strQuery = “select a.*,b.KindText from tableTest a left join tableKind b on a.KindCode=b.KindCode “;
string strShow = “ID,Subject,KindCode,KindText”;
DataTable dt = m_Pager.ExecutePager(pageIndex, pageSize, strShow, strQuery, “”, “ID desc”, out pageCount, out recordCount);
GridView1.DataSource = dt;
GridView1.DataBind();
Label1.Text = string.Format(”共{0}条记录,每页{1}条,页次{2}/{3}”,recordCount,pageSize,pageIndex,pageCount);
}

protected void btnJump_Click(object sender, EventArgs e)
{
int.TryParse(txtPageSize.Text, out pageIndex);
LoadData();
}
}

ASP.NET 2005 Treeview终极解决方案

星期二, 06月 3rd, 2008

  这几天在写HRMde时候 这问题搞了我两天,开始在使用Google 找了半天都是一堆垃圾,都是使用算法de较多, 后来就去了demsdn.yesky.com 找到点启示. 好了废话多说无用.
  首先表结构如下 表名 Test
按此在新窗口浏览图片
  写个存储过程 GetTreeview
  这个不用我说了吧下面用到
  为了速度缓存DataTable
Public Function GetTreeTable() As DataTable
 Dim dt As New DataTable()
 dt = HttpContext.Current.Cache(”Treeview”)
 If dt Is Nothing Then
  Dim Conn As New SqlConnection
  Dim clsConnDatabase As New ConnectionDatabase
  Conn = clsConnDatabase.ConnDatabase
  Dim Command As New SqlCommand
  Command.Connection = Conn
  Command.CommandText = “GetTreeview”
  Command.CommandType = CommandType.StoredProcedure
  Command.ExecuteNonQuery()
  Dim da As New SqlDataAdapter(Command)
  dt = New DataTable()
  da.Fill(dt)
  HttpContext.Current.Cache.Insert(”Treeview”, dt)
 End If
 Return dt
End Function
  这里是主要阿
Public Sub PopulateNodes(ByVal nodes As TreeNodeCollection, Optional ByVal intParentID As Int32 = 0)
 Dim dt As New DataTable()
 dt = clsWebForms.GetTreeTable()
 Dim strExpression As String
 strExpression = “[parentID] = ” & intParentID
 Dim foundRows() As DataRow
 foundRows = dt.Select(strExpression)
 
 Dim I As Integer
 For I = 0 To foundRows.GetUpperBound(0)
  Dim tn As New TreeNode()
  tn.Text = foundRows(I).Item(“TableName”).ToString()
  tn.Value = foundRows(I).Item(”ID”).ToString()
  Dim dr() As DataRow
  dr = dt.Select(”[parentID] = ” & tn.Value)
  If dr.GetUpperBound(0) > -1 Then
   tn.PopulateOnDemand = True
  End If
  nodes.Add(tn)
 Next
End Sub
  建立WebForm 放入Treeview
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
     
 If Not Page.IsPostBack Then
  PopulateNodes(TreeView1.Nodes, 0)
 End If
End Sub
Protected Sub TreeView1_TreeNodePopulate(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.TreeNodeEventArgs) Handles TreeView1.TreeNodePopulate
 PopulateNodes(e.Node.ChildNodes, e.Node.Value)
End Sub
  至于速度我没测试,如果大家有兴趣帮忙测测.

用Java实现FTP服务器解决方案

星期一, 06月 2nd, 2008

FTP 命令

  FTP de主要操作都是基于各种命令基础之上de.常用de命令有:
  · 设置传输模式,它包括ASCⅡ(文本) 和BINARY 二进制模式;
  · 目录操作,改变或显示远程计算机de当前目录(cd、dir/ls 命令);
  · 连接操作,open命令用于建立同远程计算机de连接;close命令用于关闭连接;
  · 发送操作,put命令用于传送文件到远程计算机;mput 命令用于传送多个文件到远程计算机;
  · 获取操作,get命令用于接收一个文件;mget命令用于接收多个文件.
  编程思路

  根据FTP de工作原理,在主函数中建立一个服务器套接字端口,等待客户端请求,一旦客户端请求被接受,服务器程序就建立一个服务器分线程,处理客户端de命令.如果客户端需要和服务器端进行文件de传输,则建立一个新de套接字连接来完成文件de操作.
  编程技巧说明

  1.主函数设计
  在主函数中,完成服务器端口de侦听和服务线程de创建.我利用一个静态字符串变量initDir 来保存服务器线程运行时所在de工作目录.服务器de初始工作目录是由程序运行时用户输入de,缺省为C盘de根目录.
  具体de相关代码如下:
  public class ftpServer extends Thread{
  private Socket socketClient;
  private int counter;
  private static String initDir;
  public static void main(String[] args){
  if(args.length != 0) {
   initDir = args[0];
  }else{ initDir = “c:”;}
  int i = 1;
  try{
   System.out.println(”ftp server started!”);
   //监听21号端口
   ServerSocket s = new ServerSocket(21);
   for(;;){
    //接受客户端请求
    Socket incoming = s.accept();
    //创建服务线程
    new ftpServer(incoming,i).start();
    i ;
   }
  }catch(Exception e){}
  }
  2. 线程类de设计
  线程类de主要设计都是在run()方法中实现.用run()方法得到客户端de套接字信息,根据套接字得到输入流和输出流,向客户端发送欢迎信息.
  3. FTP 命令de处理
  (1) 访问控制命令
  · user name(user) 和 password (pass) 命令处理相关代码如下:
  if(str.startsWith(”USER”)){
  user = str.substring(4);
  user = user.trim();
  out.println(”331 Password”);
  }
  if(str.startsWith(”PASS”))
  out.println(”230 User ” user ” logged in.”);
  User 命令和 Password 命令分别用来提交客户端用户输入de用户名和口令.
  · CWD (CHANGE WORKING DIRECTORY) 命令处理相关代码如下:
  if(str.startsWith(”CWD”)){
  String str1 = str.substring(3);
  dir = dir “/” str1.trim();
  out.println(”250 CWD command succesful”);
  }
  该命令改变工作目录到用户指定de目录.
  · CDUP (CHANGE TO PARENT DIRECTORY) 命令处理相关代码如下:
  if(str.startsWith(”CDUP”)){
  int n = dir.lastIndexOf(”/”);
  dir = dir.substring(0,n);
  out.println(”250 CWD command succesful”);
  }
  该命令改变当前目录为上一层目录.
  · QUIT命令处理相关代码如下:
  if(str.startsWith(”QUIT”)) {
  out.println(”GOOD BYE”);
  done = true;
  }
  该命令退出及关闭与服务器de连接,输出GOOD BYE.
  (2) 传输参数命令
  · Port命令处理相关代码如下:
  if(str.startsWith(”PORT”)) {
  out.println(”200 PORT command successful”);
  int i = str.length() - 1;
  int j = str.lastIndexOf(”,”);
  int k = str.lastIndexOf(”,”,j-1);
  String str1,str2;
  str1=”";
  str2=”";
  for(int l=k 1;lstr1 = str2 str.charAt(l);
  }
  for(int l=j 1;l<=i;l ){
  str2 = str2 str.charAt(l);
  }
  tempPort = Integer.parseInt(str1) * 16 *16 Integer.parseInt(str2);
  }
  使用该命令时,客户端必须发送客户端用于接收数据de32位IP 地址和16位 deTCP 端口号.这些信息以8位为一组,使用十进制传输,中间用逗号隔开.
  · TYPE命令处理相关代码如下:
  if(str.startsWith(”TYPE”)){
  out.println(”200 type set”);
  }
  TYPE 命令用来完成类型设置.
  (3) FTP 服务命令
  · RETR (RETEIEVE) 和 STORE (STORE)命令处理de相关代码
  if(str.startsWith(”RETR”)){
  out.println(”150 Binary data connection”);
  str = str.substring(4);
  str = str.trim();
  RandomAccessFile outFile = new
  RandomAccessFile(dir “/” str,”r”);
  Socket tempSocket = new Socket(host,tempPort);
  OutputStream outSocket = tempSocket.getOutputStream();
  byte byteBuffer[]= new byte[1024];
  int amount;
  try{
  while((amount = outFile.read(byteBuffer)) != -1){
   outSocket.write(byteBuffer, 0, amount);
  }
  outSocket.close();
  out.println(”226 transfer complete”);
  outFile.close();
  tempSocket.close();
  }
  catch(IOException e){}
  }
  if(str.startsWith(”STOR”)){
  out.println(”150 Binary data connection”);
  str = str.substring(4);
  str = str.trim();
  RandomAccessFile inFile = new
  RandomAccessFile(dir “/” str,”rw”);
  Socket tempSocket = new Socket(host,tempPort);
  InputStream inSocket = tempSocket.getInputStream();
  byte byteBuffer[] = new byte[1024];
  int amount;
  try{
  while((amount =inSocket.read(byteBuffer) )!= -1){
  inFile.write(byteBuffer, 0, amount);
  }
  inSocket.close();
  out.println(”226 transfer complete”);
  inFile.close();
  tempSocket.close();
  }
  catch(IOException e){}
  }
  文件传输命令包括从服务器中获得文件RETR和向服务器中发送文件STOR,这两个命令de处理非常类似.处理RETR命令时,首先得到用户要获得de文件de名称,根据名称创建一个文件输入流,然后和客户端建立临时套接字连接,并得到一个输出流.随后,将文件输入流中de数据读出并借助于套接字输出流发送到客户端,传输完毕以后,关闭流和临时套接字.
  STOR 命令de处理也是同样de过程,只是方向正好相反.
  · DELE (DELETE)命令处理相关代码如下:
  if(str.startsWith(”DELE”)){
  str = str.substring(4);
  str = str.trim();
  File file = new File(dir,str);
  boolean del = file.delete();
  out.println(”250 delete command successful”);
  }
  DELE 命令用于删除服务器上de指定文件.
  · LIST命令处理相关代码如下:
  if(str.startsWith(”LIST”)) {
  try{
  out.println(”150 ASCII data”);
  Socket tempSocket = new Socket(host,tempPort);
  PrintWriter out2= new PrintWriter(tempSocket.getOutputStream(),true);
  File file = new File(dir);
  String[] dirStructure = new String[10];
  dirStructure= file.list();
  String strType=”";
  for(int i=0;iif( dirStructure[i].indexOf(”.”) == -1) { strType = “d “;}
   else
   {strType = “- “;}
   out2.println(strType dirStructure[i]);
  }
  tempSocket.close();
  out.println(”226 transfer complete”);
  }
  catch(IOException e){}
  LIST 命令用于向客户端返回服务器中工作目录下de目录结构,包括文件和目录de列表.处理这个命令时,先创建一个临时de套接字向客户端发送目录信息.这个套接字de目de端口号缺省为1,然后为当前工作目录创建File 对象,利用该对象delist()方法得到一个包含该目录下所有文件和子目录名称de字符串数组,然后根据名称中是否含有文件名中特有de“.”来区别目录和文件.最后,将得到de名称数组通过临时套接字发送到客户端.

JSP避免Form重复提交的三种方案

星期一, 06月 2nd, 2008

  1 javascript ,设置一个变量,只允许提交一次. 

  <script language=”javascript”>

   var checkSubmitFlg = false;

   function checkSubmit() {

   if (checkSubmitFlg == true) {

   return false;

   }

   checkSubmitFlg = true;

   return true;

   }

   document.ondblclick = function docondblclick() {

   window.event.returnValue = false;

   }

   document.onclick = function doconclick() {

   if (checkSubmitFlg) {

   window.event.returnValue = false;

   }

   }

  </script>

  

  <html:form action=”myAction.do” method=”post” onsubmit=”return checkSubmit();”>  

  2 还是javascript,将提交按钮或者image置为disable  

   <html:form action=”myAction.do” method=”post”

   onsubmit=”getElById(’submitInput’).disabled = true; return true;”>   

   <html:image styleId=”submitInput” src=”images/ok_b.gif” border=”0″ /> 

   </html:form>  

  3 利用strutsde同步令牌机制  

  利用同步令牌(Token)机制来解决Web应用中重复提交de问题,Struts也给出了一个参考实现.

  基本原理: 

  服务器端在处理到达de请求之前,会将请求中包含de令牌值与保存在当前用户会话中de令牌值进行比较,看是否匹配.在处理完该请求后,且在答复发送给客户端之前,将会产生一个新de令牌,该令牌除传给客户端以外,也会将用户会话中保存de旧de令牌进行替换.这样如果用户回退到刚才de提交页面并再次提交de话,客户端传过来de令牌就和服务器端de令牌不一致,从而有效地防止了重复提交de发生. 

  if (isTokenValid(request, true)) {

   // your code here

   return mapping.findForward(”success”);

  } else {

   saveToken(request);

   return mapping.findForward(”submitagain”);

  } 

  Struts根据用户会话ID和当前系统时间来生成一个唯一(对于每个会话)令牌de,具体实现可以参考TokenProcessor类中degenerateToken()方法.  

  1. //验证事务控制令牌,<html:form >会自动根据session中标识生成一个隐含input代表令牌,防止两次提交

  2. 在action中:  

   //<input type=”hidden” name=”org.apache.struts.taglib.html.TOKEN”

   // value=”6aa35341f25184fd996c4c918255c3ae”>

   if (!isTokenValid(request))

   errors.add(ActionErrors.GLOBAL_ERROR,

   new ActionError(”error.transaction.token”));

   resetToken(request); //删除session中de令牌  

  3. action有这样de一个方法生成令牌  

   protected String generateToken(HttpServletRequest request) {  

   HttpSession session = request.getSession();

   try {

   byte id[] = session.getId().getBytes();

   byte now[] =

   new Long(System.currentTimeMillis()).toString().getBytes();

   MessageDigest md = MessageDigest.getInstance(”MD5″);

   md.update(id);

   md.update(now);

   return (toHex(md.digest()));

   } catch (IllegalStateException e) {

   return (null);

   } catch (NoSuchAlgorithmException e) {

   return (null);

   }

   }   

JSP显示中文问题的解决方案

星期一, 06月 2nd, 2008

这两天在win98下装apache1.3.9加jserv和gnujsp1.0,jdk1.2.2,jsdk2.0
发现中文无法正常显示.要么乱码,要么出错.
经网友提醒,总结了以下几条方法.
1:修改区域设置:在控制面版中选择区域设置,设为英语(美国)?nbsp;
然后重起.一切就都正常.
2:在jsp页中加入一条语句:
<%@ page contentType="text/html;charset=gb2312" %> ?
琷sp显示就正常了.
3:在编译servlet和jsp时加入相关代码选项.编译servlet使用
javac -encoding iso8859_1 myservlet.java
在jspdezone配置文件中.修改编译参数为:
compiler=builtin-javac -encoding ISO8859_1
使用这种方法后,不需要作其他de改动就可以正常显示中文了.
4:最土de办法,在servlet源程序中加入相关代码变换语句.如
try{
out.println(new ( (new String("我爱死您了")).getBytes("GBK"),"ISO8859_1"))
}
catch( UnsupportedEncodingException e)
{
…….
}
使用这种方法一定要注意捕获UnsupportedEncodingException

php 之 没有mysql支持时的替代方案

星期一, 06月 2nd, 2008

一般个人免费主页空间都不会提供mysql支持,就是提供也很苛刻,所以寻找也个良好de替代方案很重要哦!
PHPde文件处理功能很强大,所以可以用文件de存取来代替来!
(要知道没有数据库de时候,什么都是用文件组织de哦!呵呵!),其中个数据项用特殊符号分割,我采用de是“||”,方便通过explode()函数读取单个记录!
其实这里数据库de思想还是可以用到de!象数据库de索引!
所以必须先做个索引文件!(这样说也并不正确)
就以留言本来说吧:
主要文件是:
index.database
其结构如下:
留言人姓名||留言人性别||留言时间||留言内容存放位置||feiyn(这项是方便读取时de被‘n’干恼de!
每条存储一行可以方便de通过PHPdefgets()函数读取,或者file()函数读取每行到数组
为了防止多人同是对数据de写入冲突,故还需要加锁(也用文件实现)
以下是写入相关代码
<?php
//必须传入以下参量:
//留言人姓名 $name
//留言人性别 $sex
//留言时间 $time
//留言内容存放位置 $savePosite
$indexFile="index.database";
$indexFileLock=$indexFile."Lock";
$message=$name."||".$sex."||".$time."||".$savePosite."||feiy||";//这就是要写入de记录
while(file_exists($indexFileLock)) $temp ; //检测是否已加锁
fclose(fopen($indexFileLock,"w")); //如没有则进入并加锁避免同是访问冲突
$fp=fopen($indexFile,"a");
fputs($message,strlen($message));
fclose($fp);
unlink($indexFileLock);//解锁
?>
读取相关代码
<?php
$indexFile="index.database";
$indexFileLock=$indexFile."Lock";
while(file_exists($indexFileLock)) $temp ; //检测是否已加锁
fclose(fopen($indexFileLock,"w")); //如没有则进入并加锁避免同是访问冲突
$ary=file($indexFile);
unlink($indexfileLock);//解锁
for($i=0;$i<sizeof($ary);$i ){
$tempAry=explode("||",$ary[$i]);
echo("name:".$tempAry[0]);
echo("sex:".$tempAry[1]);
echo("sex:".$tempAry[2]);
echo("savePosite:",$tempAry[3]);//可以从该地址读取留言内容
}
?>
通过以上可以方便de解决常用de网页运用,比如聊天室,BBS论坛,书签之类
如果那位大虾有更好de解决方法,请赐教!谢谢!
我de主页:feiyschool.51.net
QQ:23072155
email:feiyhy@sina.com
【本文版权归作者feiy与奥索网共同拥有,如需转载,请注明作者及出处】

PHP下MAIL的另一解决方案

星期一, 06月 2nd, 2008

前一段时间我接触到DEC Tru64 Unix 我在上面装了PHP APACHE,可以用提供demail函数始终不能正常发信,于是自编了一个函数,它利用UNIX下de管道和PHPdeSOCK函数进行发信,经过实验非常驻成功,下面是此函数原相关代码.
function mymail($mto,$mcc,$msubject,$mbody)
{
$from="webmaster@backhome.com.cn";
$sign = "\n";//随您便写些什么
$sendmailpath="/usr/lib/sendmail";//Semdmail路径
$bound = "========_".uniqid("BCFMail")."==_";//分界符
$headers = "MIME-Version: 1.0\n".
"Content-Type: multipart/mixed; boundary=\"$bound\"\n".
"Date: ".date("D, d M H:i:s Y ")."\n".
"From: $from\n".
"To: $mto\n".
"Cc: $mcc\n".
"Subject: $msubject\n".
"Status: \n".
"X-Status:\n".
"X-Mailer: MY Email Interface\n".
"X-Keywords:\n\n";
$content="–".$bound."\n"."Content-Type:text/plain;charset=\"GB2312\"\n\n".$mbody.$sign."\n";
$end = "\n"."–".$bound."–\n";
$sock = popen("$sendmailpath -t -f ‘webmaster@backhome.com.cn’",’w');
fputs($sock, $headers);
fputs($sock, $content);
fputs($sock, $end);
fputs($sock, ".\n");
fputs($sock, "QUIT\n");
pclose($sock);
}