2006年02月07日

11.2 JSP语法概要表 JSP元素 语法 说明 备注
  JSP表达式 <%= expression %> 计算表达式并输出结果。 等价的XML表达是:
  <jsp:expression>
  expression
  </jsp:expression>
  
  可以使用的预定义变量包括:request,response,out,session,application,config,pageContext。这些预定义变量也可以在JSP Scriptlet中使用。
  
  JSP Scriptlet <% code %> 插入到service方法的代码。 等价的XML表达是:
  <jsp:scriptlet>
  code
  </jsp:scriptlet>
  
  JSP声明 <%! code %> 代码被插入到Servlet类(在service方法之外)。 等价的XML表达是:
  <jsp:declaration>
  code
  </jsp:declaration>
  
  page指令 <%@ page att="val" %> 作用于Servlet引擎的全局性指令。 等价的XML表达是
  <jsp:directive.page att="val"\>。
  
  合法的属性如下表,其中粗体表示默认值:
  
  import="package.class"
  contentType="MIME-Type"
  isThreadSafe="true|false"
  session="true|false"
  buffer="size kb|none"
  autoflush="true|false"
  extends="package.class"
  info="message"
  errorPage="url"
  isErrorPage="true|false"
  language="java"
  
  include指令 <%@ include file="url" %> 当JSP转换成Servlet时,应当包含本地系统上的指定文件。 等价的XML表达是:
  
  <jsp:directive.include
  file="url"\>.
  
  其中URL必须是相对URL。
  
  利用jsp:include动作可以在请求的时候(而不是JSP转换成Servlet时)引入文件。
  
  JSP注释 <%– comment –%> 注释;JSP转换成Servlet时被忽略。 如果要把注释嵌入结果HTML文档,使用普通的HTML注释标记<– comment –>。
  jsp:include动作 <jsp:include
  page="relative URL"
  flush="true"/> 当Servlet被请求时,引入指定的文件。 如果你希望在页面转换的时候包含某个文件,使用JSP include指令。
  注意:在某些服务器上,被包含文件必须是HTML文件或JSP文件,具体由服务器决定(通常根据文件扩展名判断)。
  
  jsp:useBean动作 <jsp:useBean att=val*/> 或者
  <jsp:useBean att=val*>
  …
  </jsp:useBean> 寻找或实例化一个Java Bean。 可能的属性包括:
  id="name"
  scope="page|request
  |session|application"
  class="package.class"
  type="package.class"
  beanName="package.class"
  
  jsp:setProperty动作 <jsp:setProperty att=val*/> 设置Bean的属性。既可以设置一个确定的值,也可以指定属性值来自请求参数。 合法的属性包括:
  name="beanName"
  property="propertyName|*"
  param="parameterName"
  value="val"
  
  jsp:getProperty动作 <jsp:getProperty
  name="propertyName"
  value="val"/> 提取并输出Bean的属性。  
  jsp:forward动作 <jsp:forward
  page="relative URL"/> 把请求转到另外一个页面。  
  jsp:plugin动作 <jsp:plugin
  attribute="value"*>
  …
  </jsp:plugin> 根据浏览器类型生成OBJECT或者EMBED标记,以便通过Java Plugin运行Java Applet。   
  

2006年02月06日
/*
  *游戏的主画布类
  */
import javax.swing.*;
import java.awt.*;

public class GameCanvas extends JPanel
{
 private int rows = 30, cols = 30;
 private int boxWidth, boxHeight;
 private Color bgColor = Color.darkGray,
               snakeColor = Color.GREEN;
 private boolean [][]colorFlags;
 private static GameCanvas instance = null;
/*
 *构造函数私有,使用单例模式,其他类共享一个实例
 */
 private GameCanvas()
 {
  colorFlags = new boolean[rows][cols];
   for(int i = 0; i < colorFlags.length; i++)
     for(int j = 0; j<colorFlags[i].length; j++)
            colorFlags[i][j] = false;
 }
/*
 *获得GameCanvas的实例
 */
 public static GameCanvas getCanvasInstance()
 {
   if(instance == null)
      instance = new GameCanvas();
   return instance;
 }
 /*
  *设置面板画布的行数
  */
 public void setRows(int rows)
 {
  this.rows = rows;
 }
 /*
  *得到画布方格的行数
  */
 public int getRows()
 {
  return rows;
 }
 /*
  *设置画布方格的列数
  */
 public void setCols(int cols)
 {
  this.cols = cols;
 }
  /*
   * 得到面板方格的列数
   */
 public int getCols()
 {
  return cols;
 }
 /*
 *绘图类,在画布上绘图
 */
  public void paintComponent(Graphics g)
  {
   super.paintComponent(g);
   
   fanning();
   for(int i = 0; i < colorFlags.length; i++)
     for(int j = 0; j < colorFlags[i].length; j++)
      {
        Color color = colorFlags[i][j] ? snakeColor : bgColor;
        g.setColor(color);
        g.fill3DRect(j * boxWidth, i * boxHeight, boxWidth, boxHeight,true);
      }
  } 
/*
*画布重置,恢复画布的原始状态
*/
  public void reset()
  {
   for(int i = 0; i < colorFlags.length; i++)
     for(int j = 0; j<colorFlags[i].length; j++)
            colorFlags[i][j] = false;
        repaint();
  }
/*
*根据窗口大小调整方格的大小
*/
  public void fanning()
  {
   boxWidth = getSize().width / cols;
   boxHeight = getSize().height / rows;
  }
  /*
   * 获取画布(row,col)位置颜色的值
   */
  public boolean getColorFlag(int row, int col)
  {
   return colorFlags[row][col];
  }
  /*
   * 设置画布(row,col)位置颜色的值
   */
  public void setColorFlag(int row, int col, boolean colorFlag)
  {
   colorFlags[row][col] =  colorFlag;
  }
}
/*
 *蛇的节点类,保存当前节点所在的(row,col)坐标值
 *(同时也被用作食物类,因为食物所要保存的信息和此相同,没有再设)
 */
public class SnakeNode
{
  private int row,col;

 /*
  *构造函数
  */
   public SnakeNode(int row,int col)
   {
 this.row = row;
 this.col = col;
   }

/*
* 设置该节点所在的行
*/
  public void setRow(int row)
  {
   this.row = row;
  }

/*
 * 获得该节点所在的行
 */
  public int getRow()
  {
   return row;
  }

  /*
   * 设置该节点所在的列
   */
  public void setCol(int col)
  {
   this.col = col;
  }

/*
 * 返回该节点所在的列
 */
  public int getCol()
  {
   return col;
  }
}
 /*
  *游戏的主画布类
  */
import javax.swing.*;
import java.awt.*;

public class GameCanvas extends JPanel
{
 private int rows = 30, cols = 30;
 private int boxWidth, boxHeight;
 private Color bgColor = Color.darkGray,
               snakeColor = Color.GREEN;
 private boolean [][]colorFlags;
 private static GameCanvas instance = null;
/*
 *构造函数私有,使用单例模式,其他类共享一个实例
 */
 private GameCanvas()
 {
  colorFlags = new boolean[rows][cols];
   for(int i = 0; i < colorFlags.length; i++)
     for(int j = 0; j<colorFlags[i].length; j++)
            colorFlags[i][j] = false;
 }
 /*
  *获得GameCanvas的实例
  */
 public static GameCanvas getCanvasInstance()
 {
   if(instance == null)
      instance = new GameCanvas();
   return instance;
 }
 /*
  *设置面板画布的行数
  */
 public void setRows(int rows)
 {
  this.rows = rows;
 }
 /*
  *得到画布方格的行数
  */
 public int getRows()
 {
  return rows;
 }
 /*
  *设置画布方格的列数
  */
 public void setCols(int cols)
 {
  this.cols = cols;
 }
  /*
   * 得到面板方格的列数
   */
 public int getCols()
 {
  return cols;
 }
 /*
  *绘图类,在画布上绘图
  */
  public void paintComponent(Graphics g)
  {
   super.paintComponent(g);
   
   fanning();
   for(int i = 0; i < colorFlags.length; i++)
     for(int j = 0; j < colorFlags[i].length; j++)
      {
        Color color = colorFlags[i][j] ? snakeColor : bgColor;
        g.setColor(color);
        g.fill3DRect(j * boxWidth, i * boxHeight, boxWidth, boxHeight,true);
      }
  } 
  /*
   *画布重置,恢复画布的原始状态
   */
  public void reset()
  {
   for(int i = 0; i < colorFlags.length; i++)
     for(int j = 0; j<colorFlags[i].length; j++)
            colorFlags[i][j] = false;
        repaint();
  }
  /*
  *根据窗口大小调整方格的大小
  */
  public void fanning()
  {
   boxWidth = getSize().width / cols;
   boxHeight = getSize().height / rows;
  }
  /*
   * 获取画布(row,col)位置颜色的值
   */
  public boolean getColorFlag(int row, int col)
  {
   return colorFlags[row][col];
  }
  /*
   * 设置画布(row,col)位置颜色的值
   */
  public void setColorFlag(int row, int col, boolean colorFlag)
  {
   colorFlags[row][col] =  colorFlag;
  }
}
/*
 *蛇身线程类,控制蛇的移动及其方向
 */
import javax.swing.*;
import java.util.*;

class SnakeBody extends Thread
{
 private LinkedList snakeList;
 private int iniSnakeBodyLength;
 private GreedSnakeGame game;
 private GameCanvas canvas;
 public  final static int DOWN = -1;
 public final static int  LEFT = -2;
 public final static int UP = 1;
 public final static int RIGHT = 2;
 private final static int PER_LEVEL_SPEED_UP = 10;
 private final static int PER_FOOD_SCORE = 10;
 private final static int PER_LEVEL_SCORE = 20 *PER_FOOD_SCORE;
 private int direction = LEFT;
 private boolean running = true,pause = false;
 private int timeInterval = 200,curLevelScore;
 private ArrayList food;
 /*
 *构造函数
 */
 public SnakeBody(final GreedSnakeGame game,int iniSnakeBodyLength)
 {
  this.game = game;
  this.iniSnakeBodyLength = iniSnakeBodyLength;
  curLevelScore = 0;
  food = new ArrayList(5);
  canvas = GameCanvas.getCanvasInstance();
  /*
  * 初始化蛇身
  */
  snakeList = new LinkedList();
  int rows = canvas.getRows();
  int cols = canvas.getCols();
  for(int i = 0; i < iniSnakeBodyLength; i++)
  {
   snakeList.add(new SnakeNode(rows / 2, cols / 2 + i));
   canvas.setColorFlag(rows / 2, cols / 2 + i, true);
  }
  createFood();
  canvas.repaint();
 }
 /*
  *暂停移动
  */
 public void pauseMove()
 {
  pause = true;
 }
 /*
  *恢复移动
  */
 public void resumeMove()
 {
  pause = false;
 }
 /*
 *停止移动
 */
 public void stopMove()
 {
  running = false;
 }
 /*
  *每次创建食物
  */
 public void createFood()
 {
  for(int i = 0;i < 5;i++)
  {
   int x = (int)(Math.random() * canvas.getCols());
   int y = (int)(Math.random() * canvas.getRows());
   if(canvas.getColorFlag(x,y))
    i–;
   else
    food.add(new SnakeNode(x,y));
    canvas.setColorFlag(x,y,true);
   }
   canvas.repaint();
 }
 /*
  * 改变蛇的移动方向
  */
 public void changeDirection(int direction)
 {
  this.direction = direction;
 }
 /*
  *在没有改变方向时,控制蛇的移动,以及吃食物
  */
 private boolean moveOn()
 {
  SnakeNode snakeHead  = (SnakeNode)snakeList.getFirst();
  int x = snakeHead.getRow();
  int y = snakeHead.getCol();
  boolean isFood = false,isBody = false;
  switch(direction)
  {
   case LEFT: y–; break;
   case RIGHT: y++; break;
   case DOWN:  x++; break;
   case UP:   x–; break;
   default:  break;
  }
  if((x >= 0 && x < canvas.getCols()) &&( y >=0 && y < canvas.getRows()))
  {
    int i = 0;
    for(;i < food.size();i++)
     if(x == ((SnakeNode)food.get(i)).getRow() && y == ((SnakeNode)food.get(i)).getCol())
     {
      isFood = true;
        break;
     }
    for(int j=0;j < snakeList.size()-1 ;j++)
      if(x == ((SnakeNode)snakeList.get(j)).getRow() && y == ((SnakeNode)snakeList.get(j)).getCol())
      {
       isBody = true;
         break;
      }
    if(isFood)
    {
     int score = game.getScore();
     score += PER_FOOD_SCORE;
     game.setScore(score);
     curLevelScore += PER_FOOD_SCORE;
     snakeList.addFirst(new SnakeNode(x,y));
     food.remove(i);
     
      if(food.size() == 0)
               { 
             if(curLevelScore >= PER_LEVEL_SCORE)
             { 
            int level = game.getLevel();
              level++;
              game.setLevel(level);
              curLevelScore -=PER_LEVEL_SCORE; 
              }     
        createFood();
       }
    }
    else if(isBody)
    {
     JOptionPane.showMessageDialog(null,"You Failed","Game Over",
                         JOptionPane.INFORMATION_MESSAGE);
                 running = false;     
    }
    else
    {
     snakeHead = new SnakeNode(x,y);
     snakeList.addFirst(snakeHead);
     canvas.setColorFlag(x,y,true);
     SnakeNode snakeTail = (SnakeNode)snakeList.getLast();
     snakeList.removeLast();
     canvas.setColorFlag(snakeTail.getRow(),snakeTail.getCol(),false);
     canvas.repaint();
    }
    return true;
  }
    return false;  
 }
 /*
  *run方法,控制线程运行要处理的事务
  */
 public void run()
 {
  while(running)
  {
   try
   {
    sleep(timeInterval-game.getLevel() * PER_LEVEL_SPEED_UP);
    
   }catch(InterruptedException e)
   {
    e.printStackTrace();
   }
   if(!pause)
   {
    if(!moveOn())
    {
      JOptionPane.showMessageDialog(null,"You Failed","Game Over",
                                         JOptionPane.INFORMATION_MESSAGE);
                  running = false;                              
     }
   }
  }
 }
}
/*
 *控制面板类
 */
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.border.*;

class ControlPanel extends JPanel
{
 private JPanel infoPanel,buttonPanel;
 private SnakePanel snakePanel;
 private JTextField levelField;
 private JTextField scoreField;
 private JButton playButton, pauseButton, stopButton,
                 turnEasilyButton, turnHarderButton;
 private Timer timer;
 private GreedSnakeGame game;
 private EtchedBorder border = new EtchedBorder(EtchedBorder.RAISED,Color.white,Color.lightGray);
/*
 *构造函数
 */
 public ControlPanel(final GreedSnakeGame game)
 {
   this.game = game;
   setLayout(new GridLayout(3,1,0,4));
  
   snakePanel = new SnakePanel();
   snakePanel.setBorder(border);
   levelField = new JTextField("0");
   scoreField = new JTextField("0");
   infoPanel = new JPanel(new GridLayout(4,1,0,0));
   infoPanel.add(new JLabel("Level:"));
   infoPanel.add(levelField);
   infoPanel.add(new JLabel("Score:"));
   infoPanel.add(scoreField);
   infoPanel.setBorder(border);
  
   playButton = new JButton("Play");
   pauseButton = new JButton("Pause");
   stopButton = new JButton("Stop");
   turnEasilyButton = new JButton("Turn Easily");
   turnHarderButton = new JButton("Turn Harder");
   buttonPanel = new JPanel(new GridLayout(5,1,0,1));
   buttonPanel.add(playButton);
   buttonPanel.add(pauseButton);
   buttonPanel.add(stopButton);
   buttonPanel.add(turnEasilyButton);
   buttonPanel.add(turnHarderButton);
   buttonPanel.setBorder(border);
  
   add(snakePanel);
   add(infoPanel);
   add(buttonPanel);
   playButton.addActionListener(
   new ActionListener()
   {
    public void actionPerformed(ActionEvent event)
    {
     game.playGame();
     requestFocus();
    }
   }
   );
   pauseButton.addActionListener(
   new ActionListener()
   {
    public void actionPerformed(ActionEvent event)
    {
     if(pauseButton.getText().equals("Pause"))
        game.pauseGame();
     else
       game.resumeGame();
       requestFocus();
    }
   }
   );
   stopButton.addActionListener(
   new ActionListener()
   {
    public void actionPerformed(ActionEvent event)
    {
     game.stopGame();
     requestFocus();
    }
   }
   );
   turnHarderButton.addActionListener(
   new ActionListener()
   {
    public void actionPerformed(ActionEvent event)
    {
     int level = game.getLevel();
     game.setLevel((level + 1)%9);
     requestFocus();
    }
   });
   turnEasilyButton.addActionListener(
   new ActionListener()
   {
    public void actionPerformed(ActionEvent event)
    {
     int level = game.getLevel();
     if(level > 0)
     {
      game.setLevel(level – 1);
     }
     requestFocus();
    }
   });
   timer =  new Timer(500,
  new ActionListener()
  {
   public void actionPerformed(ActionEvent event)
   {
      levelField.setText(""+game.getLevel());
     scoreField.setText(""+game.getScore());
   }
  }
  );
  timer.start();
  addKeyListener(new ControlKeyListener());
 }
 /*
  *设置play按钮的可用性
  */
 public void setPlayButtonEnabled(boolean enable)
 {
  playButton.setEnabled(enable);
 }
  /*
   *设置按钮时Pause还是Resume
   */
 public void setPauseButtonLabel(boolean pause)
 {
  pauseButton.setText(pause ? "Pause" : "Resume");
 }
  /*
  *重置游戏
  */
 public void reset()
 {
  scoreField.setText("0");
  levelField.setText("0");
  game.setLevel(0);
  game.setScore(0);
 }
  /*
  *绘制贪吃蛇图片的面板
  */
 private class SnakePanel extends JPanel
 {
  private ImageIcon snake = new ImageIcon("GeedSnake.jpe");
 
  public void paintComponent(Graphics g)
  {
   super.paintComponent(g);
   snake.paintIcon(this,g,0,0);
  }
 }
  /*
  *键盘控制类,控制蛇头的移动方向
  */
 private class ControlKeyListener extends KeyAdapter {
  
   private int direction = -2;
     public void keyPressed(KeyEvent ke)
  {
   if (!game.isPlaying()) return;
     
   switch (ke.getKeyCode()) {
    case KeyEvent.VK_DOWN:
     if(direction/SnakeBody.DOWN!=-1)
     {
      game.changeDirection(SnakeBody.DOWN);
      direction = -1;
     }
     break;
    case KeyEvent.VK_LEFT:
     if(direction/SnakeBody.LEFT!=-1)
     {
      game.changeDirection(SnakeBody.LEFT);
      direction = -2;
     }
     break;
    case KeyEvent.VK_RIGHT:
     if(direction/SnakeBody.RIGHT!=-1)
     {
      game.changeDirection(SnakeBody.RIGHT);
      direction = 2;
      break;
     }
    case KeyEvent.VK_UP:
     if(direction/SnakeBody.UP!=-1)
     {
      game.changeDirection(SnakeBody.UP);
      direction = 1;
      break;
     }
    default:
     break;
   }
  }
 }                 
}

电子邮件(E-mail)是Internet上使用最广泛的服务之一,传统的Email应用模式基于C/S结构,即用户使用客户端的邮件收发工具(如Outlook、Foxmail等)与提供邮件服务的服务器(如163.net、263.net、371.net)通信,在使用客户端邮件工具之前,用户要进行一些必要的设置,如指定邮件服务器的主机地址和通信端口等,这些工作对刚开始上网的用户会有一定的困难,如果把E-mail和Web结合在一起,即通过Web编程和适当的系统设置,使用户仅仅以访问Web的方式就可以得到和使用完整的邮件服务,这样将极大地方便上网用户,这种系统称为WebMail。WebMail是目前Internet上最受欢迎的服务之一,也是很多网站必备功能之一。另外WebMail同样也适用于企业或校园网的应用。 
  通常在后台服务器的搭建和设置完成后实现WebMail系统,而前台的开发工作主要是开发工具与后台数据库和邮件服务器的交互问题。在Linux平台上运行的各种服务器软件稳定性和可靠性一直很好,而且选择跨平台的Java开发工具使系统更稳定,具有更高的伸缩性。 
JSP性能
  尽管JSP提供强大的功能是建立在Servlet之上,但JSP的性能和Servlet相差无几。JSP首先要编译成Servlet,这只会增加少量的代码,仅需编译一次且可以预编译,这就消除了运行时花费不必要的负担。JSP与Servlet性能上的差异仅仅表现在返回的数据是二进制的。这是因为JSP返回时用的是PrintWriter,而Servlet可以应用于速度更快的OutputStream。 
  JSP自定义的标签库可以封装大量的、复杂的Java操作在一个Form里面,这些预先定义好的标签可以很容易的被那些没有Java知识的人调用。因此,JSP自定义的标签库可以有效地实现Java程序员和Web设计人员工作的划分。然而,在页面上应用的每一个标签,Web容器都必须创建一个新的标签句柄对象或从标签缓冲中提取它。因此,过多的应用自定义的标签将会带来不必要的资源浪费。 
  BodyTags是一种特殊的定制标签,可以提取在它之间封装的内容或者替换那些内容。BodyTags之间的内容一般会备份在内存中。由于BodyTags之间能够嵌套和重复,因此,在程序中应用了多级的BodyTags会占用大量宝贵的内存和系统资源。 

实现WebMail的主要功能
  该系统提供了获取、阅读、书写、转发、回复、打印、删除及用户管理的功能。考虑到系统的跨平台性,采用Java及相关技术产品为开发工具,特别是采用JSP作为服务程序,这样对客户端也没有其它要求,同时系统的性能在高负荷下得到进一步提高。整个WebMail系统全部采用纯Java代码,服务器端每响应一个服务请求启动一个线程,而不像CGI那样启动一个进程。这样能够节省系统资源,提高系统性能。 


实现主要代码:


获取用户输入的信息 
  对于用户输入内容获取功能是通过getParameter方法来实现的,对于输入的文本内容,通过如下代码就能在服务器端获取,程序代码如下: 
String username=request.getParameter("login");
String password=request.getParameter("password");
Session session2=Session.getInstance(System.getProperties() ,null);
Store store=session2.getStore("pop3");
 根据用户输入的信息来连接服务器,程序代码如下:
try{
 store.connect(host,username+"%nyist.net", password);
}
catch(javax.mail.AuthenticationFailedException e)
{content="用户名与密码不匹配";}


接收邮件代码段 
根据获取用户输入的信息来连接服务器,代码为:
store.connect("nyist.net",-1,request.getParameter("username")+"%nyist.net",request
.getParameter("password"));
获取服务器端的信息,代码如下: 
Folder folder = store.getFolder("INBOX");
Folder.open (Folder.READ_WRITE);
Message message[]=folder.getMessages();
FetchProfile fp=new FetchProfile();
fp.add(FetchProfile.Item.ENVELOPE);
fp.add(FetchProfile.Item.FLAGS);
fp.add("X-Mailer");
folder.fetch(message,fp);
根据服务器上信息的不同格式,使用不同的方式来读取: 
String contentbody="";
Object o=message[j].getContent();
若其Type为tex/plain就可直接读出,代码如下: 
if (message[j].isMimeType("text/plain")) 
{
 contentbody=(String)+"</td>";
 StringBuffer  buf=new  StringBuffer(contentbody.length()+6);
 char  ch=" ";
 for(int  p=0;p<contentbody.length();p++)//若遇到换行就转为<br>
 {ch=contentbody.charAt(p);
  if(ch=="\n")buf.append("<br>");
  else  buf.append(ch);
 }
 contentbody=buf.toString();

如果信息类型为text/html,不同的信息类型处理的方式稍有不同(如下段代码),由于篇幅有限不再一一说明。 
else if (message[j].isMimeType("text/html")) 
 contentbody=(String)o+"</td>";

发送邮件代码段 

根据用户输入的内容,获取邮件头信息代码如下: 
String host = "nyist.net";
String from = request.getParameter("from");
String to = request.getParameter("to");
String subject = request.getParameter("subject");
String content = request.getParameter("content");
Properties props = System.getProperties();
//设置邮件服务
props.put("mail.smtp.host", host);
Session session2 =Session.getInstance(props, null);
设置邮件头信息代码如下: 
MimeMessage message =new MimeMessage(session2);
message.setFrom(new InternetAddress(from));
message.addRecipient(Message.RecipientType.TO,new InternetAddress(to));
message.setSubject(subject);
message.setSentDate(new Date());
// create the message part
MimeBodyPart messageBodyPart =new MimeBodyPart();
设置邮件内容,构建程序段如下: 
messageBodyPart.setText(content);
Multipart multipart = new MimeMultipart();
multipart.addBodyPart(messageBodyPart);
用户在发送邮件时常常带有附件,就是将浏览器客户端用户本地的文件传送到POP客户端,实现代码如下: 
for (int i=0;i<mySmartUpload.getFiles().getCount();i++)
{
 com.jspsmart.upload.File myFile = mySmartUpload.getFiles().getFile(i);
 if (!myFile.isMissing()) {
 myFile.saveAs("/upload/" + myFile.getFileName()); 
 count ++;
}
在上传附件的同时,对上传文件的数量进行统计,并通过out.println("上传了"+count + "个文件")将其在屏幕上显示出来。 
在发送的信件中如果有附件,使用如下代码进行发送: 
for(int i=0;request.getParameter("file"+i)!=null;i++)
{
 messageBodyPart = new MimeBodyPart();
 File file=new File("/home/mengyu/ROOT/upload/",request.getParameter("file"+i));
 DataSource source =new FileDataSource(file);
 messageBodyPart.setDataHandler(new DataHandler(source));
 messageBodyPart.setFileName(request.getParameter("file"+i));
 multipart.addBodyPart(messageBodyPart);
}
// Put parts in message
message.setContent(multipart);
调用Transport的send方法,将构造好MIME Message对象发送出去,代码如下: 
Transport.send(message);


删除电子邮件代码段 
在通过Web界面使用电子邮件过程中,经常要对接收到垃圾邮件或已查看过的邮件进行删除,这也是电子邮件中必不可少的一个功能,所以我们设计了Web界面中删除电子邮件的相应功能,主要程序代码段如下: 
Folder folder=store.getFolder("INBOX");
folder.open(Folder.READ_WRITE);
Message message[]=folder.getMessages();
String msg[]=request.getParameterValues("msg");
for(int i=0,n=msg.length;i<n;i++)
 message[Double.valueOf(msg[i]).intValue()].setFlag(Flags.Flag.DELETED,true);
folder.close(true);
 
用户管理 
在使用系统运行的过程中,通过管理界面添加用户,删除不必要的用户,修改用户的密码,这是程序运行过程中必要的模块,代码如下: 
//添加用户
Runtime.getRuntime().exec("/home/vpopmail/bin/vadduser"+request.getParameter("username")+"@nyist.net "+request.getParameter("passwd"));
//删除用户
Runtime.getRuntime().exec("/home/vpopmail/bin/vdeluser"+request.getParameter("username")+"@nyist.net");
//修改用户密码
Runtime.getRuntime().exec("/home/vpopmail/bin/vpasswd"+request.getParameter("username")+"@nyist.net "+request.getParameter("passwd")); 


总结
Java简化了企业解决方案的开发、部署和管理等相关的复杂问题,它是面向对象的编程语言,同时也是具有平台独立性、高性能的服务器端编程语言。它提供的标准系统框架和服务适合团体开发,可控制性好,与其它资源的集成性好。采用Java为编程工具开发高性能、高可用性的WebMail服务器具有非常重要的意义。

import java.awt.*;

import java.awt.event.*;

import javax.swing.*;

public class Calculator extends JFrame


{


 private Container container;


 private GridBagLayout layout;


 private GridBagConstraints constraints;


 private JTextField displayField;//计算结果显示区


 private String lastCommand;//保存+,-,*,/,=命令


 private double result;//保存计算结果


 private boolean start;//判断是否为数字的开始


 
  public Calculator()


  {


  super("Calculator");


  container=getContentPane();


  layout=new GridBagLayout();


  container.setLayout(layout);


  constraints=new GridBagConstraints();
  
  start=true;


  result=0;


    lastCommand = "=";
  
  displayField=new JTextField(20);


  displayField.setHorizontalAlignment(JTextField.RIGHT);


  constraints.gridx=0;


  constraints.gridy=0;


  constraints.gridwidth=4;


  constraints.gridheight=1;


  constraints.fill=GridBagConstraints.BOTH;


  constraints.weightx=100;


  constraints.weighty=100;


  layout.setConstraints(displayField,constraints);


  container.add(displayField);
  
  ActionListener insert = new InsertAction();


    ActionListener command = new CommandAction();


    
  addButton("Backspace",0,1,2,1,insert);


  addButton("CE",2,1,1,1,insert);


  addButton("C",3,1,1,1,insert);
  
  addButton("7",0,2,1,1,insert);


  addButton("8",1,2,1,1,insert);


  addButton("9",2,2,1,1,insert);


  addButton("/",3,2,1,1,command);
  


  addButton("4",0,3,1,1,insert);


  addButton("5",1,3,1,1,insert);


  addButton("6",2,3,1,1,insert);


  addButton("*",3,3,1,1,command);
  


  addButton("1",0,4,1,1,insert);


  addButton("2",1,4,1,1,insert);


  addButton("3",2,4,1,1,insert);


  addButton("-",3,4,1,1,command);
  


  addButton("0",0,5,1,1,insert);


  addButton("+/-",1,5,1,1,insert);//只显示"-"号,"+"没有实用价值


  addButton(".",2,5,1,1,insert);


  addButton("+",3,5,1,1,command);
  


  addButton("=",0,6,4,1,command);
  


  setSize(300,300);


  setVisible(true);


  }


  private void addButton(String label,int row,int column,int with,int height,ActionListener listener)


  {


   JButton button=new JButton(label);


 
   constraints.gridx=row;


   constraints.gridy=column;
   


   constraints.gridwidth=with;


   constraints.gridheight=height;


   
    constraints.fill=GridBagConstraints.BOTH;


   
   button.addActionListener(listener);


   layout.setConstraints(button,constraints);


   container.add(button);


  }


  private class InsertAction implements ActionListener


    {


       public void actionPerformed(ActionEvent event)


       {


          String input=event.getActionCommand();


          if (start)


          {


             displayField.setText("");


             start=false;


             
             if(input.equals("+/-"))


             displayField.setText(displayField.getText()+"-");


          }


          if(!input.equals("+/-"))


          {


           if(input.equals("Backspace"))


           {


            String str=displayField.getText();


            if(str.length()>0)


              displayField.setText(str.substring(0,str.length()-1));


            }


           else if(input.equals("CE")||input.equals("C"))


           {


            displayField.setText("0");


            start=true;


           } 


           else


             displayField.setText(displayField.getText()+input);


         }


       }


    }


    private class CommandAction implements ActionListener


    {


       public void actionPerformed(ActionEvent evt)


       {


          String command=evt.getActionCommand();


          if(start)


          {


           lastCommand=command;


          }


          else


          {


          calculate(Double.parseDouble(displayField.getText()));


          lastCommand=command;


          start=true;


          }


         }


      }


   public void calculate(double x)


   {


      if (lastCommand.equals("+")) result+= x;    

  
      else if (lastCommand.equals("-")) result-=x;


      else if (lastCommand.equals("*")) result*=x;   

    
      else if (lastCommand.equals("/")) result/=x;


      else if (lastCommand.equals("=")) result=x;


       displayField.setText(""+ result);


    }


   public static void  main(String []args)


   {


     Calculator calculator=new Calculator();


     calculator.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);


   }


}

/*
  *游戏的主画布类
  */
import javax.swing.*;
import java.awt.*;

public class GameCanvas extends JPanel
{
 private int rows = 30, cols = 30;
 private int boxWidth, boxHeight;
 private Color bgColor = Color.darkGray,
               snakeColor = Color.GREEN;
 private boolean [][]colorFlags;
 private static GameCanvas instance = null;
/*
 *构造函数私有,使用单例模式,其他类共享一个实例
 */
 private GameCanvas()
 {
  colorFlags = new boolean[rows][cols];
   for(int i = 0; i < colorFlags.length; i++)
     for(int j = 0; j<colorFlags[i].length; j++)
            colorFlags[i][j] = false;
 }
/*
 *获得GameCanvas的实例
 */
 public static GameCanvas getCanvasInstance()
 {
   if(instance == null)
      instance = new GameCanvas();
   return instance;
 }
 /*
  *设置面板画布的行数
  */
 public void setRows(int rows)
 {
  this.rows = rows;
 }
 /*
  *得到画布方格的行数
  */
 public int getRows()
 {
  return rows;
 }
 /*
  *设置画布方格的列数
  */
 public void setCols(int cols)
 {
  this.cols = cols;
 }
  /*
   * 得到面板方格的列数
   */
 public int getCols()
 {
  return cols;
 }
 /*
 *绘图类,在画布上绘图
 */
  public void paintComponent(Graphics g)
  {
   super.paintComponent(g);
   
   fanning();
   for(int i = 0; i < colorFlags.length; i++)
     for(int j = 0; j < colorFlags[i].length; j++)
      {
        Color color = colorFlags[i][j] ? snakeColor : bgColor;
        g.setColor(color);
        g.fill3DRect(j * boxWidth, i * boxHeight, boxWidth, boxHeight,true);
      }
  } 
/*
*画布重置,恢复画布的原始状态
*/
  public void reset()
  {
   for(int i = 0; i < colorFlags.length; i++)
     for(int j = 0; j<colorFlags[i].length; j++)
            colorFlags[i][j] = false;
        repaint();
  }
/*
*根据窗口大小调整方格的大小
*/
  public void fanning()
  {
   boxWidth = getSize().width / cols;
   boxHeight = getSize().height / rows;
  }
  /*
   * 获取画布(row,col)位置颜色的值
   */
  public boolean getColorFlag(int row, int col)
  {
   return colorFlags[row][col];
  }
  /*
   * 设置画布(row,col)位置颜色的值
   */
  public void setColorFlag(int row, int col, boolean colorFlag)
  {
   colorFlags[row][col] =  colorFlag;
  }
}
/*
 *蛇的节点类,保存当前节点所在的(row,col)坐标值
 *(同时也被用作食物类,因为食物所要保存的信息和此相同,没有再设)
 */
public class SnakeNode
{
  private int row,col;

 /*
  *构造函数
  */
   public SnakeNode(int row,int col)
   {
 this.row = row;
 this.col = col;
   }

/*
* 设置该节点所在的行
*/
  public void setRow(int row)
  {
   this.row = row;
  }

/*
 * 获得该节点所在的行
 */
  public int getRow()
  {
   return row;
  }

  /*
   * 设置该节点所在的列
   */
  public void setCol(int col)
  {
   this.col = col;
  }

/*
 * 返回该节点所在的列
 */
  public int getCol()
  {
   return col;
  }
}
 /*
  *游戏的主画布类
  */
import javax.swing.*;
import java.awt.*;

public class GameCanvas extends JPanel
{
 private int rows = 30, cols = 30;
 private int boxWidth, boxHeight;
 private Color bgColor = Color.darkGray,
               snakeColor = Color.GREEN;
 private boolean [][]colorFlags;
 private static GameCanvas instance = null;
/*
 *构造函数私有,使用单例模式,其他类共享一个实例
 */
 private GameCanvas()
 {
  colorFlags = new boolean[rows][cols];
   for(int i = 0; i < colorFlags.length; i++)
     for(int j = 0; j<colorFlags[i].length; j++)
            colorFlags[i][j] = false;
 }
 /*
  *获得GameCanvas的实例
  */
 public static GameCanvas getCanvasInstance()
 {
   if(instance == null)
      instance = new GameCanvas();
   return instance;
 }
 /*
  *设置面板画布的行数
  */
 public void setRows(int rows)
 {
  this.rows = rows;
 }
 /*
  *得到画布方格的行数
  */
 public int getRows()
 {
  return rows;
 }
 /*
  *设置画布方格的列数
  */
 public void setCols(int cols)
 {
  this.cols = cols;
 }
  /*
   * 得到面板方格的列数
   */
 public int getCols()
 {
  return cols;
 }
 /*
  *绘图类,在画布上绘图
  */
  public void paintComponent(Graphics g)
  {
   super.paintComponent(g);
   
   fanning();
   for(int i = 0; i < colorFlags.length; i++)
     for(int j = 0; j < colorFlags[i].length; j++)
      {
        Color color = colorFlags[i][j] ? snakeColor : bgColor;
        g.setColor(color);
        g.fill3DRect(j * boxWidth, i * boxHeight, boxWidth, boxHeight,true);
      }
  } 
  /*
   *画布重置,恢复画布的原始状态
   */
  public void reset()
  {
   for(int i = 0; i < colorFlags.length; i++)
     for(int j = 0; j<colorFlags[i].length; j++)
            colorFlags[i][j] = false;
        repaint();
  }
  /*
  *根据窗口大小调整方格的大小
  */
  public void fanning()
  {
   boxWidth = getSize().width / cols;
   boxHeight = getSize().height / rows;
  }
  /*
   * 获取画布(row,col)位置颜色的值
   */
  public boolean getColorFlag(int row, int col)
  {
   return colorFlags[row][col];
  }
  /*
   * 设置画布(row,col)位置颜色的值
   */
  public void setColorFlag(int row, int col, boolean colorFlag)
  {
   colorFlags[row][col] =  colorFlag;
  }
}
/*
 *蛇身线程类,控制蛇的移动及其方向
 */
import javax.swing.*;
import java.util.*;

class SnakeBody extends Thread
{
 private LinkedList snakeList;
 private int iniSnakeBodyLength;
 private GreedSnakeGame game;
 private GameCanvas canvas;
 public  final static int DOWN = -1;
 public final static int  LEFT = -2;
 public final static int UP = 1;
 public final static int RIGHT = 2;
 private final static int PER_LEVEL_SPEED_UP = 10;
 private final static int PER_FOOD_SCORE = 10;
 private final static int PER_LEVEL_SCORE = 20 *PER_FOOD_SCORE;
 private int direction = LEFT;
 private boolean running = true,pause = false;
 private int timeInterval = 200,curLevelScore;
 private ArrayList food;
 /*
 *构造函数
 */
 public SnakeBody(final GreedSnakeGame game,int iniSnakeBodyLength)
 {
  this.game = game;
  this.iniSnakeBodyLength = iniSnakeBodyLength;
  curLevelScore = 0;
  food = new ArrayList(5);
  canvas = GameCanvas.getCanvasInstance();
  /*
  * 初始化蛇身
  */
  snakeList = new LinkedList();
  int rows = canvas.getRows();
  int cols = canvas.getCols();
  for(int i = 0; i < iniSnakeBodyLength; i++)
  {
   snakeList.add(new SnakeNode(rows / 2, cols / 2 + i));
   canvas.setColorFlag(rows / 2, cols / 2 + i, true);
  }
  createFood();
  canvas.repaint();
 }
 /*
  *暂停移动
  */
 public void pauseMove()
 {
  pause = true;
 }
 /*
  *恢复移动
  */
 public void resumeMove()
 {
  pause = false;
 }
 /*
 *停止移动
 */
 public void stopMove()
 {
  running = false;
 }
 /*
  *每次创建食物
  */
 public void createFood()
 {
  for(int i = 0;i < 5;i++)
  {
   int x = (int)(Math.random() * canvas.getCols());
   int y = (int)(Math.random() * canvas.getRows());
   if(canvas.getColorFlag(x,y))
    i–;
   else
    food.add(new SnakeNode(x,y));
    canvas.setColorFlag(x,y,true);
   }
   canvas.repaint();
 }
 /*
  * 改变蛇的移动方向
  */
 public void changeDirection(int direction)
 {
  this.direction = direction;
 }
 /*
  *在没有改变方向时,控制蛇的移动,以及吃食物
  */
 private boolean moveOn()
 {
  SnakeNode snakeHead  = (SnakeNode)snakeList.getFirst();
  int x = snakeHead.getRow();
  int y = snakeHead.getCol();
  boolean isFood = false,isBody = false;
  switch(direction)
  {
   case LEFT: y–; break;
   case RIGHT: y++; break;
   case DOWN:  x++; break;
   case UP:   x–; break;
   default:  break;
  }
  if((x >= 0 && x < canvas.getCols()) &&( y >=0 && y < canvas.getRows()))
  {
    int i = 0;
    for(;i < food.size();i++)
     if(x == ((SnakeNode)food.get(i)).getRow() && y == ((SnakeNode)food.get(i)).getCol())
     {
      isFood = true;
        break;
     }
    for(int j=0;j < snakeList.size()-1 ;j++)
      if(x == ((SnakeNode)snakeList.get(j)).getRow() && y == ((SnakeNode)snakeList.get(j)).getCol())
      {
       isBody = true;
         break;
      }
    if(isFood)
    {
     int score = game.getScore();
     score += PER_FOOD_SCORE;
     game.setScore(score);
     curLevelScore += PER_FOOD_SCORE;
     snakeList.addFirst(new SnakeNode(x,y));
     food.remove(i);
     
      if(food.size() == 0)
               { 
             if(curLevelScore >= PER_LEVEL_SCORE)
             { 
            int level = game.getLevel();
              level++;
              game.setLevel(level);
              curLevelScore -=PER_LEVEL_SCORE; 
              }     
        createFood();
       }
    }
    else if(isBody)
    {
     JOptionPane.showMessageDialog(null,"You Failed","Game Over",
                         JOptionPane.INFORMATION_MESSAGE);
                 running = false;     
    }
    else
    {
     snakeHead = new SnakeNode(x,y);
     snakeList.addFirst(snakeHead);
     canvas.setColorFlag(x,y,true);
     SnakeNode snakeTail = (SnakeNode)snakeList.getLast();
     snakeList.removeLast();
     canvas.setColorFlag(snakeTail.getRow(),snakeTail.getCol(),false);
     canvas.repaint();
    }
    return true;
  }
    return false;  
 }
 /*
  *run方法,控制线程运行要处理的事务
  */
 public void run()
 {
  while(running)
  {
   try
   {
    sleep(timeInterval-game.getLevel() * PER_LEVEL_SPEED_UP);
    
   }catch(InterruptedException e)
   {
    e.printStackTrace();
   }
   if(!pause)
   {
    if(!moveOn())
    {
      JOptionPane.showMessageDialog(null,"You Failed","Game Over",
                                         JOptionPane.INFORMATION_MESSAGE);
                  running = false;                              
     }
   }
  }
 }
}
/*
 *控制面板类
 */
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.border.*;

class ControlPanel extends JPanel
{
 private JPanel infoPanel,buttonPanel;
 private SnakePanel snakePanel;
 private JTextField levelField;
 private JTextField scoreField;
 private JButton playButton, pauseButton, stopButton,
                 turnEasilyButton, turnHarderButton;
 private Timer timer;
 private GreedSnakeGame game;
 private EtchedBorder border = new EtchedBorder(EtchedBorder.RAISED,Color.white,Color.lightGray);
/*
 *构造函数
 */
 public ControlPanel(final GreedSnakeGame game)
 {
   this.game = game;
   setLayout(new GridLayout(3,1,0,4));
  
   snakePanel = new SnakePanel();
   snakePanel.setBorder(border);
   levelField = new JTextField("0");
   scoreField = new JTextField("0");
   infoPanel = new JPanel(new GridLayout(4,1,0,0));
   infoPanel.add(new JLabel("Level:"));
   infoPanel.add(levelField);
   infoPanel.add(new JLabel("Score:"));
   infoPanel.add(scoreField);
   infoPanel.setBorder(border);
  
   playButton = new JButton("Play");
   pauseButton = new JButton("Pause");
   stopButton = new JButton("Stop");
   turnEasilyButton = new JButton("Turn Easily");
   turnHarderButton = new JButton("Turn Harder");
   buttonPanel = new JPanel(new GridLayout(5,1,0,1));
   buttonPanel.add(playButton);
   buttonPanel.add(pauseButton);
   buttonPanel.add(stopButton);
   buttonPanel.add(turnEasilyButton);
   buttonPanel.add(turnHarderButton);
   buttonPanel.setBorder(border);
  
   add(snakePanel);
   add(infoPanel);
   add(buttonPanel);
   playButton.addActionListener(
   new ActionListener()
   {
    public void actionPerformed(ActionEvent event)
    {
     game.playGame();
     requestFocus();
    }
   }
   );
   pauseButton.addActionListener(
   new ActionListener()
   {
    public void actionPerformed(ActionEvent event)
    {
     if(pauseButton.getText().equals("Pause"))
        game.pauseGame();
     else
       game.resumeGame();
       requestFocus();
    }
   }
   );
   stopButton.addActionListener(
   new ActionListener()
   {
    public void actionPerformed(ActionEvent event)
    {
     game.stopGame();
     requestFocus();
    }
   }
   );
   turnHarderButton.addActionListener(
   new ActionListener()
   {
    public void actionPerformed(ActionEvent event)
    {
     int level = game.getLevel();
     game.setLevel((level + 1)%9);
     requestFocus();
    }
   });
   turnEasilyButton.addActionListener(
   new ActionListener()
   {
    public void actionPerformed(ActionEvent event)
    {
     int level = game.getLevel();
     if(level > 0)
     {
      game.setLevel(level – 1);
     }
     requestFocus();
    }
   });
   timer =  new Timer(500,
  new ActionListener()
  {
   public void actionPerformed(ActionEvent event)
   {
      levelField.setText(""+game.getLevel());
     scoreField.setText(""+game.getScore());
   }
  }
  );
  timer.start();
  addKeyListener(new ControlKeyListener());
 }
 /*
  *设置play按钮的可用性
  */
 public void setPlayButtonEnabled(boolean enable)
 {
  playButton.setEnabled(enable);
 }
  /*
   *设置按钮时Pause还是Resume
   */
 public void setPauseButtonLabel(boolean pause)
 {
  pauseButton.setText(pause ? "Pause" : "Resume");
 }
  /*
  *重置游戏
  */
 public void reset()
 {
  scoreField.setText("0");
  levelField.setText("0");
  game.setLevel(0);
  game.setScore(0);
 }
  /*
  *绘制贪吃蛇图片的面板
  */
 private class SnakePanel extends JPanel
 {
  private ImageIcon snake = new ImageIcon("GeedSnake.jpe");
 
  public void paintComponent(Graphics g)
  {
   super.paintComponent(g);
   snake.paintIcon(this,g,0,0);
  }
 }
  /*
  *键盘控制类,控制蛇头的移动方向
  */
 private class ControlKeyListener extends KeyAdapter {
  
   private int direction = -2;
     public void keyPressed(KeyEvent ke)
  {
   if (!game.isPlaying()) return;
     
   switch (ke.getKeyCode()) {
    case KeyEvent.VK_DOWN:
     if(direction/SnakeBody.DOWN!=-1)
     {
      game.changeDirection(SnakeBody.DOWN);
      direction = -1;
     }
     break;
    case KeyEvent.VK_LEFT:
     if(direction/SnakeBody.LEFT!=-1)
     {
      game.changeDirection(SnakeBody.LEFT);
      direction = -2;
     }
     break;
    case KeyEvent.VK_RIGHT:
     if(direction/SnakeBody.RIGHT!=-1)
     {
      game.changeDirection(SnakeBody.RIGHT);
      direction = 2;
      break;
     }
    case KeyEvent.VK_UP:
     if(direction/SnakeBody.UP!=-1)
     {
      game.changeDirection(SnakeBody.UP);
      direction = 1;
      break;
     }
    default:
     break;
   }
  }
 }                 
}

每个项目都有一些全局,常用的信息,而这些信息如果在每次使用时都载入,那必将耗费很大的资源,特别是对访问压力大的系统。因此,这个情况中,把这些全局信息放到缓存中是很必要的,放在缓存中可以使得数据能够很快的被读取,节省了很多宝贵的CPU和IO。

项目中通常是用application 和cache来实现缓存的功能。他们的用法分别为:

1)application:
application["test"] = "this is a application message!";

2)cache

 Cache.Add("Key1", "Value");

两种用法都很相似,都是采用名/值对的方式来保存数据,而在读取数据时也只要用 键 就可以获取缓存的值。

而2种相比,到底哪种更有优势呢? 答案是CACHE在使用上更具有灵活性。特点如下:

1。自有的按时更新缓存的机制

有的项目需要定时获取最新数据的需求,如天气预报,可能间隔10分钟 就要读取一次需求,那这可以利用CACHE本身的方法来实现。


//监视某个时间
public void CreateDependency(Object sender, EventArgs e) {
    // Create a DateTime object.
    DateTime dt = DateTime.Now.AddSeconds(10);

    // Create a cache entry.
    Cache["key1"] = "Value 1";
    CacheDependency dependency = new CacheDependency(null,  dt);

    Cache.Insert("key2", "Value 2", dependency);

    DisplayValues();
}




2.当缓存的源修改时,可以重新更新缓存。这个缓存源可以是变量,也可以是文件,或者目录。

//监视某个变量
public void CreateDependency(Object sender, EventArgs e) {
    // Create a DateTime object.
    //DateTime dt = DateTime.Now.AddSeconds(10);

    // Create a cache entry.
    Cache["key1"] = "Value 1";

    // Make key2 dependent on key1.
    String[] dependencyKey = new String[1];
    dependencyKey[0] = "key1";
    CacheDependency dependency = new CacheDependency(null, dependencyKey, null);

    Cache.Insert("key2", "Value 2", dependency);

    DisplayValues();
}



3.同时以多种搭配来自动更新缓存,如同时监视某个文件,并且在指定间隔的时间内自动更新。

//监视某个时间和变量
public void CreateDependency(Object sender, EventArgs e) {
    // Create a DateTime object.
    DateTime dt = DateTime.Now.AddSeconds(10);

    // Create a cache entry.
    Cache["key1"] = "Value 1";

    // Make key2 dependent on key1.
    String[] dependencyKey = new String[1];
    dependencyKey[0] = "key1";
    CacheDependency dependency = new CacheDependency(null, dependencyKey, dt);

    Cache.Insert("key2", "Value 2", dependency);

    DisplayValues();
}

一、什么是SQL注入式攻击?

  所谓SQL注入式攻击,就是攻击者把SQL命令插入到Web表单的输入域或页面请求的查询字符串,欺骗服务器执行恶意的SQL命令。在某些表单中,用户输入的内容直接用来构造(或者影响)动态SQL命令,或作为存储过程的输入参数,这类表单特别容易受到SQL注入式攻击。常见的SQL注入式攻击过程类如:

  ⑴ 某个ASP.NET Web应用有一个登录页面,这个登录页面控制着用户是否有权访问应用,它要求用户输入一个名称和密码。

  ⑵ 登录页面中输入的内容将直接用来构造动态的SQL命令,或者直接用作存储过程的参数。下面是ASP.NET应用构造查询的一个例子:

  System.Text.StringBuilder query = new System.Text.StringBuilder(
  SELECT * from Users WHERE login = )
  .Append(txtLogin.Text).Append( AND password=)
  .Append(txtPassword.Text).Append();

  ⑶ 攻击者在用户名字和密码输入框中输入或1=1之类的内容。

  ⑷ 用户输入的内容提交给服务器之后,服务器运行上面的ASP.NET代码构造出查询用户的SQL命令,但由于攻击者输入的内容非常特殊,所以最后得到的SQL命令变成:SELECT * from Users WHERE login = or 1=1 AND password = or 1=1。

  ⑸ 服务器执行查询或存储过程,将用户输入的身份信息和服务器中保存的身份信息进行对比。

  ⑹ 由于SQL命令实际上已被注入式攻击修改,已经不能真正验证用户身份,所以系统会错误地授权给攻击者。

  如果攻击者知道应用会将表单中输入的内容直接用于验证身份的查询,他就会尝试输入某些特殊的SQL字符串篡改查询改变其原来的功能,欺骗系统授予访问权限。

  系统环境不同,攻击者可能造成的损害也不同,这主要由应用访问数据库的安全权限决定。如果用户的帐户具有管理员或其他比较高级的权限,攻击者就可能对数据库的表执行各种他想要做的操作,包括添加、删除或更新数据,甚至可能直接删除表。

    二、如何防范?

  好在要防止ASP.NET应用被SQL注入式攻击闯入并不是一件特别困难的事情,只要在利用表单输入的内容构造SQL命令之前,把所有输入内容过滤一番就可以了。过滤输入内容可以按多种方式进行。

  ⑴ 对于动态构造SQL查询的场合,可以使用下面的技术:

  第一:替换单引号,即把所有单独出现的单引号改成两个单引号,防止攻击者修改SQL命令的含义。再来看前面的例子,“SELECT * from Users WHERE login = or 1=1 AND password = or 1=1”显然会得到与“SELECT * from Users WHERE login = or 1=1 AND password = or 1=1”不同的结果。

  第二:删除用户输入内容中的所有连字符,防止攻击者构造出类如“SELECT * from Users WHERE login = mas — AND password =”之类的查询,因为这类查询的后半部分已经被注释掉,不再有效,攻击者只要知道一个合法的用户登录名称,根本不需要知道用户的密码就可以顺利获得访问权限。

  第三:对于用来执行查询的数据库帐户,限制其权限。用不同的用户帐户执行查询、插入、更新、删除操作。由于隔离了不同帐户可执行的操作,因而也就防止了原本用于执行SELECT命令的地方却被用于执行INSERT、UPDATE或DELETE命令。

  ⑵ 用存储过程来执行所有的查询。SQL参数的传递方式将防止攻击者利用单引号和连字符实施攻击。此外,它还使得数据库权限可以限制到只允许特定的存储过程执行,所有的用户输入必须遵从被调用的存储过程的安全上下文,这样就很难再发生注入式攻击了。

  ⑶ 限制表单或查询字符串输入的长度。如果用户的登录名字最多只有10个字符,那么不要认可表单中输入的10个以上的字符,这将大大增加攻击者在SQL命令中插入有害代码的难度。

  ⑷ 检查用户输入的合法性,确信输入的内容只包含合法的数据。数据检查应当在客户端和服务器端都执行——之所以要执行服务器端验证,是为了弥补客户端验证机制脆弱的安全性。

  在客户端,攻击者完全有可能获得网页的源代码,修改验证合法性的脚本(或者直接删除脚本),然后将非法内容通过修改后的表单提交给服务器。因此,要保证验证操作确实已经执行,唯一的办法就是在服务器端也执行验证。你可以使用许多内建的验证对象,例如RegularExpressionValidator,它们能够自动生成验证用的客户端脚本,当然你也可以插入服务器端的方法调用。如果找不到现成的验证对象,你可以通过CustomValidator自己创建一个。

  ⑸ 将用户登录名称、密码等数据加密保存。加密用户输入的数据,然后再将它与数据库中保存的数据比较,这相当于对用户输入的数据进行了“消毒”处理,用户输入的数据不再对数据库有任何特殊的意义,从而也就防止了攻击者注入SQL命令。System.Web.Security.FormsAuthentication类有一个HashPasswordForStoringInConfigFile,非常适合于对输入数据进行消毒处理。

  ⑹ 检查提取数据的查询所返回的记录数量。如果程序只要求返回一个记录,但实际返回的记录却超过一行,那就当作出错处理。

2006年01月27日

using System; 

namespace ShellSorter

{

public class ShellSorter

{

public void Sort(int [] list)

{

int inc;

for(inc=1;inc<=list.Length/9;inc=3*inc+1);

for(;inc>0;inc/=3)

{

for(int i=inc+1;i<=list.Length;i+=inc)

{

int t=list[i-1];

int j=i;

while((j>inc)&&(list[j-inc-1]>t))

{

list[j-1]=list[j-inc-1];

j-=inc;

}

list[j-1]=t;

}   }

}   }

public class MainClass

{   public static void Main()

{

int[] iArrary=new int[]{1,5,13,6,10,55,99,2,87,12,34,75,33,47};

ShellSorter sh=new ShellSorter();

sh.Sort(iArrary);

for(int m=0;m<iArrary.Length;m++)

Console.Write("{0} ",iArrary[m]);

Console.WriteLine();

}   }

}

using System;

namespace InsertionSorter

{ public class InsertionSorter

{ public void Sort(int [] list)

{ for(int i=1;i<list.Length;i++)

{  int t=list[i];

int j=i;

while((j>0)&&(list[j-1]>t))

{  list[j]=list[j-1];

–j;

}

list[j]=t; } 

}

}

public class MainClass

{  public static void Main()

{

int[] iArrary=new int[]{1,13,3,6,10,55,98,2,87,12,34,75,33,47};

InsertionSorter ii=new InsertionSorter();

ii.Sort(iArrary);

for(int m=0;m<iArrary.Length;m++)

Console.Write("{0}",iArrary[m]);

Console.WriteLine();

}  }

}

using System;  

namespace SelectionSorter

{  public class SelectionSorter

{   private int min;

public void Sort(int [] list)

{  for(int i=0;i<list.Length-1;i++)

{  min=i;

for(int j=i+1;j<list.Length;j++)

{   if(list[j]<list[min]) 

min=j;

}

int t=list[min];

list[min]=list[i];

list[i]=t;

}   }

}

public class MainClass

{  public static void Main()

{

int[] iArrary=new int[]{1,5,3,6,10,55,9,2,87,12,34,75,33,47};

SelectionSorter ss=new SelectionSorter();

ss.Sort(iArrary);

for(int m=0;m<iArrary.Length;m++)

Console.Write("{0} ",iArrary[m]);

Console.WriteLine(); 

}  }

}