在项目中可能有时候上传的文件比较大。如果用http方式来进行文件上传的话,问题比较多。 所用可以采用ftp的方式,但是一般都是做的web项目,要在浏览器中嵌入,因为对于java的话,有applet的方式,当然applet用户需要安装JRE。一般的JRE大概在 10M多点。applet是在一个“沙箱”里运行,不能对用户的文件进行读取,如果要读取本地的文件,就需要对其进行授权。需要用到java_home/bin目录下的一些工具。 下面的网上找的一些关于文件上传的代码和操作方式,稍微修改了一下。

一、下面是applet的代码,其他需要用到commons-net-3.0-src包,可以到apache的官网网站上下载。

之所以用src的包是因为需要把applet的代码和commons-net的代码都打成一个jar包。所以把commons-net-3.0-src下的源码和applet的代码放到同一个目录下,

然后打成jar包。

package com.test.ftp;


import java.applet.Applet;
import java.io.File;
import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.filechooser.FileFilter; 

 /**
  * 说明:本APPLET只是测试大文件FTP上传可行性

  * 至于其他功能比如FTP下载、删除、FTP服务器文件列表可调用ContinueFTP相应功能。
  */

public class FileFtpApplet extends Applet  {

 /**
  * Constructor of the applet.
  *
  * @exception HeadlessException if GraphicsEnvironment.isHeadless()
  * returns true.
  */
/* public FileFtpApplet() throws HeadlessException {
  super();
 }*/

 /**
  * Called by the browser or applet viewer to inform
  * this applet that it is being reclaimed and that it should destroy
  * any resources that it has allocated. The <code>stop</code> method
  * will always be called before <code>destroy</code>. <p>
  *
  * A subclass of <code>Applet</code> should override this method if
  * it has any operation that it wants to perform before it is
  * destroyed. For example, an applet with threads would use the
  * <code>init</code> method to create the threads and the
  * <code>destroy</code> method to kill them. <p>
  */
 public void destroy() {
  // Put your code here
 }

 /**
  * Returns information about this applet. An applet should override
  * this method to return a <code>String</code> containing information
  * about the author, version, and copyright of the applet. <p>
  *
  * @return  a string containing information about the author, version, and
  * copyright of the applet.
  */
 public String getAppletInfo() {
  return "This is my default applet created by Eclipse";
 }

 /**
  * Called by the browser or applet viewer to inform
  * this applet that it has been loaded into the system. It is always
  * called before the first time that the <code>start</code> method is
  * called. <p>
  *
  * A subclass of <code>Applet</code> should override this method if
  * it has initialization to perform. For example, an applet with
  * threads would use the <code>init</code> method to create the
  * threads and the <code>destroy</code> method to kill them. <p>
  */
 public void init() {
  // Put your code here
 }

 /**
  * Called by the browser or applet viewer to inform
  * this applet that it should start its execution. It is called after
  * the <code>init</code> method and each time the applet is revisited
  * in a Web page. <p>
  *
  * A subclass of <code>Applet</code> should override this method if
  * it has any operation that it wants to perform each time the Web
  * page containing it is visited. For example, an applet with
  * animation might want to use the <code>start</code> method to
  * resume animation, and the <code>stop</code> method to suspend the
  * animation. <p>
  */
 public void start() {
  // Put your code here
 }

 /**
  * Called by the browser or applet viewer to inform
  * this applet that it should stop its execution. It is called when
  * the Web page that contains this applet has been replaced by
  * another page, and also just before the applet is to be destroyed. <p>
  *
  * A subclass of <code>Applet</code> should override this method if
  * it has any operation that it wants to perform each time the Web
  * page containing it is no longer visible. For example, an applet
  * with animation might want to use the <code>start</code> method to
  * resume animation, and the <code>stop</code> method to suspend the
  * animation. <p>
  */
 public void stop() {
  // Put your code here
 }
    private static final long serialVersionUID = 1L;

    private FileFtpApplet jFrame = null;

    private JButton jFileButton = null;

    public FileFtpApplet() {
   // TODO Auto-generated constructor stub
   jFrame = this;
   this.setSize(496, 260);
   jFileButton = new JButton("打开文件");
   jFrame.add(jFileButton);
   jFileButton.addMouseListener(new java.awt.event.MouseAdapter() {
       public void mouseClicked(java.awt.event.MouseEvent e) {
     // System.out.println("mouseClicked()"); // TODO
     // Auto-generated Event stub mouseClicked()
     JFileChooser jfChooser = new JFileChooser("D:\\..\\..");
     jfChooser.setDialogTitle("打开并上传文件");
     jfChooser.setFileFilter(new FileFilter() {
         @Override
         public boolean accept(File f) {
       if (f.getName().endsWith("dat") || f.isDirectory())
           return true;
       return false;
         }
         @Override
         public String getDescription() {
       // TODO Auto-generated method stub
       return "数据文件(*.dat)";
         }
     });
     int result = jfChooser.showOpenDialog(jFrame);
     if (result == JFileChooser.APPROVE_OPTION) { // 确认打开
 
         File fileIn = jfChooser.getSelectedFile();
 
         if (fileIn.exists()) {
           //JOptionPane.showMessageDialog(jFrame, "OPEN"); // 提示框
         ContinueFTP myFtp = new ContinueFTP();  
         try {  
             long l1 = System.currentTimeMillis();
             System.out.println("begin:"+ l1);
                if (myFtp.connect("10.68.7.182", 21, "a", "a")) {
                    String  remotePath = "/";
           String remoteFile = myFtp.getRemoteFileName(fileIn.getName());
           if (remotePath == null || remotePath.trim().equals(""))
            remotePath = "/";
           //文件扩展名
           String kzNm = "";
           if (remoteFile.indexOf(".")>=0)
            kzNm = remoteFile.substring(remoteFile.indexOf("."));
           String cellCode = "yp";
           boolean isSaveFileName  = false;
           //若不保留原文件,则重新组装远程文件名
           if (!isSaveFileName)
           remoteFile= cellCode+"_"+System.currentTimeMillis()+kzNm;
           //获得远程路径最后一位
           String lastStr = remotePath.substring(remotePath.length()-1);
           if (lastStr.trim().equals("/"))
            remoteFile = remotePath + cellCode + "/" + remoteFile;
           else 
            remoteFile = remotePath + "/" +cellCode + "/" + remoteFile;
                 
                 myFtp.upload(fileIn, remoteFile);
                 myFtp.disconnect(); 
              long l2 = System.currentTimeMillis();
              System.out.println("end:"+ l2);
                 System.out.println("remaining:"+(l2-l1));
                } 
            } catch (Exception e1) {  
                System.out.println("连接FTP出错:"+e1.getMessage());  
            }
       } else {
         }
     } else if (result == JFileChooser.CANCEL_OPTION) {
         System.out.println("Cancel button is pushed.");
     } else if (result == JFileChooser.ERROR_OPTION) {
         System.err.println("Error when select file.");
     }

      }
   }
  );
  } 
}

package com.test.ftp;


import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.io.RandomAccessFile;
import java.util.ArrayList;
import java.util.List;

import org.apache.commons.net.PrintCommandListener;
import org.apache.commons.net.ftp.FTP;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPFile;
import org.apache.commons.net.ftp.FTPReply;

/**
 * FTP上传下载文件
 * 支持断点续传
 * @version: 2009-10-23 下午04:28:48
 */
public class ContinueFTP{    
   private File file=null;
   //是否完整保留原文件名
   private boolean isSaveFileName = true;
   //枚举上传状态 
   public enum UploadStatus {  
         Create_Directory_Fail,      //远程服务器相应目录创建失败  
         Create_Directory_Success,   //远程服务器创建目录成功  
         Upload_New_File_Success,    //上传新文件成功  
         Upload_New_File_Failed,     //上传新文件失败  
         File_Exits,                 //文件已经存在  
         Remote_Bigger_Local,        //远程文件大于本地文件  
         Upload_From_Break_Success,  //断点续传成功  
         Upload_From_Break_Failed,   //断点续传失败  
         Delete_Remote_Faild;        //删除远程文件失败  
    } 
    
    //枚举下载状态
    public enum DownloadStatus {  
          Remote_File_Noexist,    //远程文件不存在  
          Local_Bigger_Remote,    //本地文件大于远程文件  
          Download_From_Break_Success,    //断点下载文件成功  
          Download_From_Break_Failed,     //断点下载文件失败  
          Download_New_Success,           //全新下载文件成功  
          Download_New_Failed;            //全新下载文件失败  
    } 
    
    public void init(){
     
    }
    
    public FTPClient ftpClient = new FTPClient();  
         
     public ContinueFTP(){  
           //设置将过程中使用到的命令输出到控制台  
           this.ftpClient.addProtocolCommandListener(new PrintCommandListener(new PrintWriter(System.out)));  
     }  
       
    /**
     * 功能:通过本地文件名指定远程文件名 
     * @param localFileName
     * @return
     * String
     * 范例:
     */
    public String getRemoteFileName(String localFileName){
     String fileName ="";
     //分隔符
     String sepaRator="\\";
        if (localFileName.indexOf(sepaRator)<0)
         sepaRator="/";
        //最后分隔符位置
        int idx = localFileName.lastIndexOf(sepaRator)+1;
        fileName = localFileName.substring(idx);
        return fileName;
    }     
      
       /**
        * 功能:检查远程是否存在文件  
        * @param remoteFileName 远程文件名
        * @return
        * @throws IOException
        * boolean
        * 范例:
        */
       public boolean isFileExist(String remoteFileName) throws IOException{
        boolean isFileExist = false;           
           //检查远程是否存在文件  
           FTPFile[] files = ftpClient.listFiles(new String(remoteFileName.getBytes("GBK"),"iso-8859-1"));  
           if(files!=null && files.length >= 1){  
              isFileExist = true;
        }
        return isFileExist;
       }
       
       
       /** 
        * 连接到FTP服务器 
        
        * @param hostname 主机名 
        * @param port 端口 
        * @param username 用户名 
        * @param password 密码 
        * @return 是否连接成功 
        * @throws IOException 
        */  
       public boolean connect(String hostname,int port,String username,String password) throws Exception{  
        boolean bl = false;
        try{
         ftpClient.connect(hostname, port);  
        }catch(Exception e){
          //可具体报错到主机和端口号
            e.printStackTrace();
    //  throw new BaseException("FTPConnError01",new String[]{"connect",e.getMessage()});
        }
        try{
         //ftpClient.setControlEncoding("GBK"); 
            if(FTPReply.isPositiveCompletion(ftpClient.getReplyCode())){  
                if(ftpClient.login(username, password)){  
                 bl = true;  
                }  
            }
        }catch(Exception e){
          //可具体报错到用户和密码
     // throw new BaseException("FTPConnError02",new String[]{"connect",e.getMessage()});
            e.printStackTrace();
        }
           return bl;  
       }  
         
       /** 
        * 从FTP服务器上下载文件,支持断点续传,上传百分比汇报 
        * @param remote 远程文件路径 
        * @param local 本地文件路径 
        * @return 上传的状态 
        * @throws IOException 
        */  
       public DownloadStatus download(String remote,String local) throws Exception{  
           //设置被动模式  
           ftpClient.enterLocalPassiveMode();  
           //设置以二进制方式传输  
           ftpClient.setFileType(FTP.BINARY_FILE_TYPE);  
           DownloadStatus result;  
             
           //检查远程文件是否存在  
           FTPFile[] files = ftpClient.listFiles(new String(remote.getBytes("GBK"),"iso-8859-1"));  
           if(files.length != 1){  
           // throw new BaseException("CellDataInputService",new String[]{"download","远程文件"+remote+"不存在"});
            System.out.println("远程文件"+remote+"不存在");
           }  
             
           long lRemoteSize = files[0].getSize();  
           File f = new File(local);  
           //本地存在文件,进行断点下载  
           if(f.exists()){  
               long localSize = f.length();  
               //判断本地文件大小是否大于远程文件大小  
               if(localSize >= lRemoteSize){  
                   System.out.println("本地文件大于远程文件,下载中止");  
                   return DownloadStatus.Local_Bigger_Remote;  
               }  
                 
               //进行断点续传,并记录状态  
               FileOutputStream out = new FileOutputStream(f,true);  
               ftpClient.setRestartOffset(localSize);  
               InputStream in = ftpClient.retrieveFileStream(new String(remote.getBytes("GBK"),"iso-8859-1"));  
               byte[] bytes = new byte[1024];  
               long step = lRemoteSize /100;  
               long process=localSize /step;  
               int c;  
               while((c = in.read(bytes))!= -1){  
                   out.write(bytes,0,c);  
                   localSize+=c;  
                   long nowProcess = localSize /step;  
                   if(nowProcess > process){  
                       process = nowProcess;  
                       if(process % 10 == 0)  
                           System.out.println("下载进度:"+process);  
                       //TODO 更新文件下载进度,值存放在process变量中  
                   }  
               }  
               in.close();  
               out.close();  
               boolean isDo = ftpClient.completePendingCommand();  
               if(isDo){  
                   result = DownloadStatus.Download_From_Break_Success;  
               }else {  
                   result = DownloadStatus.Download_From_Break_Failed;  
               }  
           }else {  
               OutputStream out = new FileOutputStream(f);  
               InputStream in= ftpClient.retrieveFileStream(new String(remote.getBytes("GBK"),"iso-8859-1"));  
               byte[] bytes = new byte[1024];  
               long step = lRemoteSize /100;  
               long process=0;  
               long localSize = 0L;  
               int c;  
               while((c = in.read(bytes))!= -1){  
                   out.write(bytes, 0, c);  
                   localSize+=c;  
                   long nowProcess = localSize /step;  
                   if(nowProcess > process){  
                       process = nowProcess;  
                       if(process % 10 == 0)  
                           System.out.println("下载进度:"+process);  
                       //TODO 更新文件下载进度,值存放在process变量中  
                   }  
               }  
               in.close();  
               out.close();  
               boolean upNewStatus = ftpClient.completePendingCommand();  
               if(upNewStatus){  
                   result = DownloadStatus.Download_New_Success;  
               }else {  
                   result = DownloadStatus.Download_New_Failed;  
               }  
           }  
           return result;  
       }  

       /** 
        * 上传文件到FTP服务器,支持断点续传 
        * @param local 本地文件名称,绝对路径 
        * @param remote 远程文件路径,使用/home/directory1/subdirectory/file.ext 按照Linux上的路径指定方式,支持多级目录嵌套,支持递归创建不存在的目录结构 
        * @return 上传结果 
        * @throws IOException 
        */  
       public UploadStatus upload(File localFile,String remote) throws IOException{  
           //设置PassiveMode传输  
           ftpClient.enterLocalPassiveMode();  
           //设置以二进制流的方式传输  
           ftpClient.setFileType(FTP.BINARY_FILE_TYPE);  
           //ftpClient.setControlEncoding("GBK");  
           UploadStatus result;  
           //对远程目录的处理  
           String remoteFileName = remote;  
           if(remote.contains("/")){  
               remoteFileName = remote.substring(remote.lastIndexOf("/")+1);  
               //创建服务器远程目录结构,创建失败直接返回  
               if(CreateDirecroty(remote, ftpClient)==UploadStatus.Create_Directory_Fail){  
                   return UploadStatus.Create_Directory_Fail;  
               }  
           }  
             
           //检查远程是否存在文件  
           FTPFile[] files = ftpClient.listFiles(new String(remoteFileName.getBytes("GBK"),"iso-8859-1"));  
           if(files!=null && files.length == 1){  
               long remoteSize = files[0].getSize();  
               //File f = new File(local);  
               long localSize = localFile.length();  
               if(remoteSize==localSize){  
                   return UploadStatus.File_Exits;  
               }else if(remoteSize > localSize){  
                   return UploadStatus.Remote_Bigger_Local;  
               }  
                 
               //尝试移动文件内读取指针,实现断点续传  
               result = uploadFile(remoteFileName, localFile, ftpClient, remoteSize);  
                 
               //如果断点续传没有成功,则删除服务器上文件,重新上传  
               if(result == UploadStatus.Upload_From_Break_Failed){  
                   if(!ftpClient.deleteFile(remoteFileName)){  
                       return UploadStatus.Delete_Remote_Faild;  
                   }  
                   result = uploadFile(remoteFileName, localFile, ftpClient, 0);  
               }  
           }else {  
               result = uploadFile(remoteFileName, localFile, ftpClient, 0);  
           }  
           return result;  
       }  
       /** 
        * 断开与远程服务器的连接 
        
        * @throws IOException 
        */  
       public void disconnect() throws IOException{  
           if(this.ftpClient.isConnected()){  
            this.ftpClient.disconnect();  
           }  
       }  
         
       /**
        * 功能:创建目录
        *      若传入路径已经存在,则返回该路径,否则创建 
        *      目前暂不支持中文列名
        * @param remoteDir
        * @return
        * @throws IOException
        * String
        * 范例:
        */
       public String CreateDirecroty(String remoteDir)throws IOException{ 
        String fillDir = "";
              UploadStatus st = CreateDirecroty(remoteDir,this.ftpClient);
              if (st == UploadStatus.Create_Directory_Success)
          fillDir = remoteDir;
        else
        fillDir = "";
              
        return fillDir;
       }
       
       /** 
        * 递归创建远程服务器目录 
        * @param remote 远程服务器文件绝对路径 
        * @param ftpClient FTPClient对象 
        * @return 目录创建是否成功 
        * @throws IOException 
        */  
       public UploadStatus CreateDirecroty(String remote,FTPClient ftpClient) throws IOException{  
           UploadStatus status = UploadStatus.Create_Directory_Success;  
           String directory = remote.substring(0,remote.lastIndexOf("/")+1);  
           if(!directory.equalsIgnoreCase("/")&&!ftpClient.changeWorkingDirectory(new String(directory.getBytes("GBK"),"iso-8859-1"))){  
               //如果远程目录不存在,则递归创建远程服务器目录  
               int start=0;  
               int end = 0;  
               if(directory.startsWith("/")){  
                   start = 1;  
               }else{  
                   start = 0;  
               }  
               end = directory.indexOf("/",start);  
               while(true){  
                   String subDirectory = new String(remote.substring(start,end).getBytes("GBK"),"iso-8859-1");  
                   if(!ftpClient.changeWorkingDirectory(subDirectory)){  
                       if(ftpClient.makeDirectory(subDirectory)){  
                           ftpClient.changeWorkingDirectory(subDirectory);  
                       }else {  
                           System.out.println("创建目录失败");  
                           return UploadStatus.Create_Directory_Fail;  
                       }  
                   }  
                     
                   start = end + 1;  
                   end = directory.indexOf("/",start);  
                     
                   //检查所有目录是否创建完毕  
                   if(end <= start){  
                       break;  
                   }  
               }  
           }  
           return status;  
       }  
         
       /** 
        * 上传文件到服务器,新上传和断点续传 
        * @param remoteFile 远程文件名,在上传之前已经将服务器工作目录做了改变 
        * @param localFile 本地文件File句柄,绝对路径 
        * @param processStep 需要显示的处理进度步进值 
        * @param ftpClient FTPClient引用 
        * @return 
        * @throws IOException 
        */  
       public UploadStatus uploadFile(String remoteFile,File localFile,FTPClient ftpClient,long remoteSize) throws IOException{  
           UploadStatus status;  
           //显示进度的上传  
           long step = localFile.length() / 100;  
           long process = 0;  
           long localreadbytes = 0L;  
           RandomAccessFile raf = new RandomAccessFile(localFile,"r");  
           OutputStream out = ftpClient.appendFileStream(new String(remoteFile.getBytes("GBK"),"iso-8859-1"));  
           //断点续传  
           if(remoteSize>0){  
               ftpClient.setRestartOffset(remoteSize);  
               process = remoteSize /step;  
               raf.seek(remoteSize);  
               localreadbytes = remoteSize;  
           }  
           byte[] bytes = new byte[1024];  
           int c;  
           while((c = raf.read(bytes))!= -1){  
               out.write(bytes,0,c);  
               localreadbytes+=c;  
                  //TODO 汇报上传状态  
               if(localreadbytes / step != process){  
                   process = localreadbytes / step;  
                   System.out.println("上传进度:" + process);  
               }  
           }  
           out.flush();  
           raf.close();  
           out.close();  
           boolean result =ftpClient.completePendingCommand();  
           if(remoteSize > 0){  
               status = result?UploadStatus.Upload_From_Break_Success:UploadStatus.Upload_From_Break_Failed;  
           }else {  
               status = result?UploadStatus.Upload_New_File_Success:UploadStatus.Upload_New_File_Failed;  
           }  
           return status;  
       }  
       /**
        * 功能:获得远程文件列表 
        * @param remoteDir 远程路径
        * @return
        * List<String>
        * 范例:
        */
       public List<String> getRemoteFileList(String remoteDir){
         List<String> list = new ArrayList<String>();
              FTPFile[] files;
     try {
      files = ftpClient.listFiles(remoteDir);
               for (int i = 0; i < files.length; i++) {
                list.add(files[i].getName());
               }
     } catch (IOException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
     }
              return list;
        }
       
       /**
        * 功能:删除指定远程文件 
        * @param fillFileName 包括路径的完整文件名
        * @return
        * @throws Exception
        * boolean
        * 范例:
        */
       public boolean deleteFile(String fillFileName) throws Exception {
        boolean bl = false;
        this.ftpClient.deleteFile(fillFileName);
           int status = this.ftpClient.getReplyCode();
           if(status == 250){
            bl = true;
            System.out.println("成功删除FTP服务器中文件:" + fillFileName);            
           } 
           return bl;
       }

/**
        * 功能:删除指定远程路径         
        * @param remoteDir
        * @return
        * @throws Exception
        * boolean
        * 范例:
        */
       public boolean deleteDir(String remoteDir)throws Exception {
        boolean isDel = false;
        this.ftpClient.removeDirectory(remoteDir);
           int status = this.ftpClient.getReplyCode();
           if(status == 250){
            isDel = true;
            System.out.println("成功删除FTP服务器中目录:" + remoteDir);            
           } 
        return isDel;
       }
         
       public static void main(String[] args) throws Exception {
        ContinueFTP myFtp = new ContinueFTP();  
        try {  
            long l1 = System.currentTimeMillis();
            System.out.println("begin:"+ l1);
               if (myFtp.connect("192.168.1.101", 21, "cfd", "123456")) {
                String mkDir = myFtp.CreateDirecroty("TTT/ccc/");
                if (mkDir != null && !mkDir.trim().equals(""))
                 System.out.println("mkDir success:"+mkDir);
                //myFtp.download( "/XA01B03H05/5.mp3",file,"0");
                //myFtp.upload("/XA01B03H05/5.mp3", "/云台山.mpg");
                //myFtp.delete_file("/tmp.txt");
                //String str = new String("电视剧"); 
                //myFtp.ftpClient.removeDirectory("/kkk/jk/");
                //myFtp.ftpClient.makeDirectory(new String(str.getBytes("GBK"),"iso-8859-1")); 
                myFtp.disconnect(); 
             long l2 = System.currentTimeMillis();
             System.out.println("end:"+ l2);
                System.out.println("remaining:"+(l2-l1));
               } 
           } catch (IOException e) {  
               System.out.println("连接FTP出错:"+e.getMessage());  
           }
          
       }

   public File getFile() {
    return file;
   }

   public void setFile(File file) {
    this.file = file;
   }

   public boolean isSaveFileName() {
    return isSaveFileName;
   }

   public void setSaveFileName(boolean isSaveFileName) {
    this.isSaveFileName = isSaveFileName;
   }
   
}

二、下面是数字签名的方法和html内容

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <title>My applet 'FileFtpApplet' starting page</title>   
    <meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
    <meta http-equiv="description" content="this is my page">
    <meta http-equiv="content-type" content="text/html; charset=UTF-8">      
  </head> 
  <body>   
    <applet codebase="." 
            code="com.test.ftp.FileFtpApplet.class" 
            name="FileFtpApplet"
            width="320"
            archive="FileFtpApplet.jar"
            height="240">
    </applet>
    <!-- archive:存放applet的jar包的名称 code:要运行的applet的名称(包括包名) -->
  </body>
</html>

签名方法:

<1>、生成密匙证书(key certificate),该证书将存储在你的.keystore文件中。Validity指的是密匙的有效期,默认是180,但是这里我们需要一年的时间,所以我们设置为365
keytool -genkey -alias FileFtpApplet -validity 365 -keystore FileFtpApplet.keystore
<2>、用我们的密匙来设计我们的APPLET
jarsigner -keystore FileFtpApplet.keystore FileFtpApplet.jar FileFtpApplet
<3>、导出证书
keytool -export -keystore FileFtpApplet.keystore -alias FileFtpApplet -file FileFtpApplet.cer

签名的时候把上面applet打成的jar包放到cmd当前的目录下。