tbwshc

#

xml解析方式

xml解析方式
dom:(document objectb model),文档对象模型,是w3c组织推荐的解析的xml的一种方式
sax:(simple api for xml),不是官方标准,但是xml社区事实上的标准,几乎所有的xml解析器都支持它

xml解析开发包
Jaxp(sun公司),dom4j,Jdom

dom和sax解析的原理
      在dom中,解析文档的结构类似为一棵树,文档、文档中的根、元素、元素内容、属性、属性值等都是以对象模型的形式表示的。Dom能够在内存中保存整个文档的模型,可以方便对xml元素。
      当sax分析器对xml文档进行分析时,触发一系列事件,并激活相应的事件处理函数,从上到下的顺序读取,读取一行就处理一行。它不允许对xml文件随机存取,没有把xml文档完全加载到内存,占用内存少。

dom和sax解析方法的区别:
1.dom解析的优点是对文档增删改查比较方便,缺点占用内存比较大。
2.sax解析的优点占用内存少,解析速度快,缺点是只适合做文档的读取,不适合做文档的增删改查。

posted @ 2012-07-27 14:57 chen11-1 阅读(1095) | 评论 (0)编辑 收藏

用 java实现定时重启windows指定服务

package com.test.processManagement;  

 

import java.io.BufferedReader;  

import java.io.FileNotFoundException;  

import java.io.FileOutputStream;  

import java.io.IOException;  

import java.io.InputStream;  

import java.io.InputStreamReader;  

import java.io.PrintStream;  

import java.text.ParseException;  

import java.text.SimpleDateFormat;  

import java.util.Date;  

import java.util.Timer;  

import java.util.TimerTask;  

 

/**
* <title>ServRebootScheWin</title>
*  
* <project>Exam</project>
*  
* <package>com.test.processManagement</package>
*  
* <file>ServRebootScheWin.java</file>
*  
* <date>2012-7-11</date>
*  
* <brief>本程序用于每天定时重启windows系统上的指定服务,并记录日志</brief>
*  
* @author Wero
*  
*/


public
class ServRebootScheWin {  

 

public
static
void main(String[] args) {  

// store the console output


final PrintStream console = System.out;  

if (args.length < 2) {  
            LOG("参数不全,程序将退出...");  
            Runtime.getRuntime().exit(-1);  
        }  

 

final String timeStr = args[0];// 每tb天重启时间(HH:mm:ss)


final String servName = args[1];// 服务名


if (args.length >= 3) {  

try {  
                System.setOut(new PrintStream(new FileOutputStream(args[2])));  
            } catch (FileNotFoundException e) {  
                System.setOut(console);  
                LOG("日志文件无法建立...");  
            }  
        }  

 

// convert time string to Date type

        Date date = null;  

try {  
            date = new SimpleDateFormat("HH:mm:ss").parse(timeStr);  
        } catch (ParseException e1) {  
            LOG("日期格式(HH:mm:ss)错误,程序将退出...");  
            Runtime.getRuntime().exit(-1);  
        }  

 

// schedule the specific windows service to reboot at specific time


// every day

        rebootEveryDayTime(date, servName);  

 

// add shutdown hook to recover system.out to console when program exits

        Runtime.getRuntime().addShutdownHook(new Thread() {  

@Override


public
void run() {  
                System.setOut(console);  
            }  
        });  
    }  

 

private
static
void rebootEveryDayTime(Date date, final String servName) {  

new Timer().schedule(new TimerTask() {  

public
void run() {  

try {  
                    reboot(servName);  
                } catch (Exception e) {  
                    LOG("重启出现异常:" + e.getMessage());  
                }  
            }  
        }, date, 24 * 60 * 60 * 1000);  
    }  

 

private
static
void reboot(String servName) throws IOException, InterruptedException {  
        LOG("重启服务:" + servName);  
        Process procStop;  
        Process procStart;  

int stopState = -1;  

int startState = -1;  

 

// stop the specific service

        procStop = Runtime.getRuntime().exec("net stop \"" + servName + "\"");  


        stopState = getProcExecStat(procStop);  
        LOG(getProcOutput(procStop));  

 

// wait for 10 seconds 


try {  
            Thread.sleep(10 * 1000);  
        } catch (InterruptedException e) {  
            LOG("线程等待时中断...");  
            e.printStackTrace();  
        }  

 

// restart

        procStart=Runtime.getRuntime().exec("net start \"" + servName + "\"");  
        startState = getProcExecStat(procStart);  
        LOG(getProcOutput(procStart));  

 

//if stop exec and start exec both return with failed flag,exists


if (stopState != 0 && startState != 0) {  
            LOG("重启失败,请确认服务名是否有效,程序将退出...");  
        } else {  
            LOG("重启成功.");  
        }  
    }  

 

private
static
int getProcExecStat(Process proc) {  

try {  

return proc.waitFor();  
        } catch (InterruptedException e) {  
            LOG("线程等待时中断...");  
            e.printStackTrace();  
        }  

return -1;  
    }  

 

private
static String getProcOutput(Process proc) throws IOException, InterruptedException {  
        InputStream is = proc.getInputStream();  
        String line;  
        StringBuffer strResult = new StringBuffer();  


        BufferedReader reader = new BufferedReader(new InputStreamReader(is));  

while ((line = reader.readLine()) != null) {  
            strResult.append(line);  
        }  
        is.close();  

 

return strResult.toString().trim();  
    }  

 

private
static
void LOG(String info) {  

if (info != null && !info.equals("")) {  
            System.out.println("windows服务监控器--------" + getCurrentTime() + "----------->" + info);  
        }  
    }  

 

private
static String getCurrentTime() {  
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");  

return sdf.format(new Date());  
    }  

 

// public enum ExecuteStates {


//


// SUCCEED(0, ""), STATERR_STOPPED(1, "服务已停止"), STATERR_STATED(3, "服务已开始"),


// STATERR_NOTFOUND(


// 2, "服务名无效");


//


// ExecuteStates(int code, String desc) {


// this.code = code;


// this.desc = desc;


// }


//


// private final int code;


// private final String desc;


//


// // regular get method


// public String getDesc() {


// return desc;


// }


//


// public static String getDescByCode(int code){


// for (ExecuteStates e:ExecuteStates.values()){


// if(e.code==code){


// return e.desc;


// }


// }


// return null;


// }


// }

 


posted @ 2012-07-25 15:30 chen11-1| 编辑 收藏

文件FTP上传支持断点续传demo

package cn.eason.util.common;


import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;


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;


/**************************************************************
* 文件名称: ContinueFTP.java
* 功能描述: ftp文件上传功能,依赖commons-net-3.1.jar实现
* 创建日期: 2012-5-21
* 创建地址: 西安
* 作者:  Eric.Hao
**************************************************************/
public class ContinueFTP {
       
        private FTPClient ftpClient = new FTPClient();
       
        public ContinueFTP(){
               
                //设置将过程中使用到的命令输出到控制台
                this.ftpClient.addProtocolCommandListener(new PrintCommandListener(new PrintWriter(System.out)));
        }


        /**
     * java编程中用于连接到FTP服务器
     * @param hostname 主机名
     * @param port 端口
     * @param username 用户名
     * @param password 密码
     * @return 是否连接成功
     * @throws IOException
     */
         public boolean connect(String hostname,int port,String username,String password)
                 throws IOException {
                 //连接到FTP服务器
                 ftpClient.connect(hostname, port);
                 //如果采用默认端口,可以使用ftp.connect(url)的方式直接连接FTP服务器
                 if(FTPReply.isPositiveCompletion(ftpClient.getReplyCode()))
                 {
                     
                         if(ftpClient.login(username, password))
                         {
                                  return true;
                     }
                 }
               
                          disconnect();
                          return false;


         }


         /**
          * 从FTP服务器上下载文件,支持断点续传功能
          * @param remote 远程文件路径
          * @param local 本地文件路径
          * @param mode tb传输方式:PassiveMode方式,ActiveMode方式
          * @return 是否成功
          * @throws IOException
          */
         public DownloadStatus download(String remote,String local,String mode) throws IOException{


                         //设置ftp传输方式
                             if(mode.equalsIgnoreCase("P")){
                                     //PassiveMode传输
                                     ftpClient.enterLocalPassiveMode();
                             }
                             else {
                                     //ActiveMode传输
                                     ftpClient.enterLocalActiveMode();
                             }
         
                             //设置以二进制流的方式传输
                  ftpClient.setFileType(FTP.BINARY_FILE_TYPE);
                  
                  //下载状态
                  DownloadStatus result;   
                  
                  //本地文件列表
                  File f = new File(local);
                  
                  //检查远程文件是否存在   
                  FTPFile[] files = ftpClient.listFiles(new String(remote.getBytes("GBK"),"iso-8859-1"));   


                  if(files.length != 1){
                      System.out.println("远程文件不存在");   
                      return DownloadStatus.Remote_File_Noexist;   
                  }
                  
                  //获得远端文件大小
                  long lRemoteSize = files[0].getSize();
                  
                  //构建输出对象
              OutputStream ut = null ;
              
                  //本地存在文件,进行断点下载 ;不存在则新下载
                  if(f.exists()){
                          
                          //构建输出对象
                      out = new FileOutputStream(f,true);
                      
                      //本地文件大小
                      long localSize = f.length();   


                      System.out.println("本地文件大小为:"+localSize);
                      
                      
                      //判定本地文件大小是否大于远程文件大小   
                      if(localSize >= lRemoteSize){
                          System.out.println("本地文件大于远程文件,下载中止");   
                          return DownloadStatus.Local_Bigger_Remote;   
                      }
                      
                      //否则进行断点续传,并记录状态   
                      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 {
                          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上的路径指定方式,支持多级目录嵌套,支持递归创建不存在的目录结构
               * @param mode 传输方式:PassiveMode方式,ActiveMode方式
               * @return 上传结果
               * @throws IOException
               */
              public UploadStatus upload(String local,String remote,String mode) throws IOException{
                  //设置PassiveMode传输
                  ftpClient.enterLocalPassiveMode();
                  //设置以二进制流的方式传输
                  ftpClient.setFileType(FTP.BINARY_FILE_TYPE);
                  UploadStatus result;
                  //对远程目录的处理
                  String remoteFileName = remote;
                  if(remote.contains("/")){
                      remoteFileName = remote.substring(remote.lastIndexOf("/")+1);
                      String directory = remote.substring(0,remote.lastIndexOf("/")+1);
                      if(!directory.equalsIgnoreCase("/")&&!ftpClient.changeWorkingDirectory(directory)){
                          //如果远程目录不存在,则递归创建远程服务器目录
                          int start=0;
                          int end = 0;
                          if(directory.startsWith("/")){
                              start = 1;
                          }else{
                              start = 0;
                          }
                          end = directory.indexOf("/",start);
                          while(true){
                              String subDirectory = remote.substring(start,end);
                              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;
                              }
                          }
                      }
                  }
                     
                  //检查远程是否存在文件
                  FTPFile[] files = ftpClient.listFiles(remoteFileName);
                  if(files.length == 1){
                      long remoteSize = files[0].getSize();
                      File f = new File(local);
                      long localSize = f.length();
                      if(remoteSize==localSize){
                          return UploadStatus.File_Exits;
                      }else if(remoteSize > localSize){
                          return UploadStatus.Remote_Bigger_Local;
                      }
                         
                      //尝试移动文件内读取指针,实现断点续传
                      InputStream is = new FileInputStream(f);
                      if(is.skip(remoteSize)==remoteSize){
                          ftpClient.setRestartOffset(remoteSize);
                          if(ftpClient.storeFile(remote, is)){
                              return UploadStatus.Upload_From_Break_Success;
                          }
                      }
                      //如果断点续传没有成功,则删除服务器上文件,重新上传
                      if(!ftpClient.deleteFile(remoteFileName)){
                          return UploadStatus.Delete_Remote_Faild;
                      }
                      is = new FileInputStream(f);
                      if(ftpClient.storeFile(remote, is)){     
                          result = UploadStatus.Upload_New_File_Success;
                      }else{
                          result = UploadStatus.Upload_New_File_Failed;
                      }
                      is.close();
                  }else {
                      InputStream is = new FileInputStream(local);
                      if(ftpClient.storeFile(remoteFileName, is)){
                          result = UploadStatus.Upload_New_File_Success;
                      }else{
                          result = UploadStatus.Upload_New_File_Failed;
                      }
                      is.close();
                  }
                  return result;
              }
         
     /**
      * 断开与远程服务器的连接
      * @throws IOException
      */
     public void disconnect() throws IOException{
         if(ftpClient.isConnected()){
             ftpClient.disconnect();
         }
     }

posted @ 2012-07-25 15:29 chen11-1 阅读(2211) | 评论 (3)编辑 收藏

SpringBird Erp系统快速开发平台(组织机构,权限管理)、代码生成器……

SpringBird Erp系统快速开发平台基于通用的三层架构,数据访问层采用了无Sql注入风险的IBatis.net,表现层采用了微软最新的Asp.net mvc3 Razor模板解析引擎和轻量级的Jquery easyui,服务层采用了接口编程,整体使用成熟可靠的Ioc、Aop框架Spring.net进行服务层、数据访问层和表现层之间的整合,Erp系统快速开发平台默认包含组织机构和权限管理功能。  安装方式
    1、安装.net framework 4.0
    2、建立数据库Erp,用户名/密码:sa/sa
    3、执行Erp.sql
    4、将文件夹Erp拷贝到C:\inetpub\wwwroot下
    5、打开IIS7管理器,将默认网站下的Erp转换为应用程序,应用程序池选择ASP.NET v4.0集成模式
    6、将文件夹PermissionWs拷贝到C:\inetpub\wwwroot下
    7、打开IIS7管理器,将默认网站下的PermissionWs转换为应用程序,应用程序池选择ASP.NET v4.0 Classic经典模式
    8、在浏览器中输入http://localhost/Erp/,账号/密码:Admin/123456
  版本1.0.0.4,2011-8-11发布 下载  http://files.cnblogs.com/springbird/Erp.1.0.0.4.7z
  SpringBird 代码生成器基于通用的三层架构,数据访问层采用了无Sql注入风险的IBatis.net,表现层采用了微软的WinForm,服务层采用了接口编程,整体使用成熟可靠的Ioc、Aop框架Spring.net进行服务层、数据访问层和表现层之间的整合,模板定义使用NVelocity模板引擎。
  消息中间件利用高效可靠的消息传递机制进行平台无关的数据交流,并基于数据通信来进行分布式系统的集成。通过提供消息传递和消息排队模型,它可以在分布式环境下扩展进程间的通信。SpringBird 基础平台架构之消息中间件(Mom,Message Oriented Middleware)基于通用的三层架构,tb数据访问层采用了无Sql注入风险的IBatis.net,表现层采用了微软最新的Asp.net mvc3 Razor模板解析引擎和轻量级的Jquery easyui,服务层采用了接口编程,整体使用成熟可靠的Ioc、Aop框架Spring.net进行服务层、数据访问层和表现层之间的整合。

posted @ 2012-07-25 15:27 chen11-1| 编辑 收藏

JAVA SSH框架 学习

在Struts + Spring + Hibernate的组合框架模式中,三者各自的特点都是什么?
Struts 的MVC设计模式可以使我们的逻辑变得很清晰。
Spring 的IOC和AOP可以使我们的产品在最大限度上解藕。
hibernate的当然就是实体对象的持久化了
典型的J2EE三层结构,分为表现层、中间层(业务逻辑层)和数据服务层。三层体系将业务规则、数据访问及合法性校验等工作放在中间层处理。客户端不直接与数据库交互,而是通过组件与中间层建立连接,再由中间层与数据库交互。
表现层是传统的JSP技术,自1999年问世以来,经过多年的发展tb其广泛的应用和稳定的表现,为其作为表现层技术打下了坚实的基础。
中间层采用的是流行的Spring+Hibernate,为了将控制层与业务逻辑层分离,又细分为以下几种。
Web层,就是MVC模式里面的“C”(controller),负责控制业务逻辑层与表现层的交互,调用业务逻辑层,并将业务数据返回给表现层作组织表现,该系统的MVC框架采用Struts。
Service层(就是业务逻辑层),负责实现业务逻辑。业务逻辑层以DAO层为基础,通过对DAO组件的正面模式包装,完成系统所要求的业务逻辑。
DAO层,负责与持久化对象交互。该层封装了数据的增、删、查、改的操作。
PO,持久化对象。通过实体关系映射工具将关系型数据库的数据映射成对象,很方便地实现以面向对象方式操作数据库,该系统采用Hibernate作为ORM框架。
Spring的作用贯穿了整个中间层,将Web层、Service层、DAO层及PO无缝整合,其数据服务层用来存放数据。
一个良好的框架可以让开发人员减轻重新建立解决复杂问题方案的负担和精力;它可以被扩展以进行内部的定制化;并且有强大的用户社区来支持它。框架通常能很好的解决一个问题。然而,你的应用是分层的,可能每一个层都需要各自的框架。仅仅解决UI问题并不意味着你能够很好的将业务逻辑和持久性逻辑和UI 组件很好的耦合。

不可否认,对于简单的应用,采用ASP或者PHP的开发效率比采用J2EE框架的开发效率要高。甚至有人会觉得:这种分层的结构,比一般采用JSP + Servlet的系统开发效率还要低。
笔者从一下几个角度来阐述这个问题。
— 开发效率:软件工程是个特殊的行业,不同于传统的工业,例如电器、建筑及汽车等行业。这些行业的产品一旦开发出来,交付用户使用后将很少需要后续的维护。但软件行业不同,软件产品的后期运行维护是个巨大的工程,单纯从前期开发时间上考虑其开发效率是不理智的,也是不公平的。众所周知,对于传统的ASP和 PHP等脚本站点技术,将整个站点的业务逻辑和表现逻辑都混杂在ASP或PHP页面里,从而导致页面的可读性相当差,可维护性非常低。即使需要简单改变页面的按钮,也不得不打开页面文件,冒着破坏系统的风险。但采用严格分层J2EE架构,则可完全避免这个问题。对表现层的修改即使发生错误,也绝对不会将错误扩展到业务逻辑层,更不会影响持久层。因此,采用J2EE分层架构,即使前期的开发效率稍微低一点,但也是值得的。
— 需求的变更:以笔者多年的开发经验来看,很少有软件产品的需求从一开始就完全是固定的。客户对软件需求,是随着软件开发过程的深入,不断明晰起来的。因此,常常遇到软件开发到一定程度时,由于客户对软件需求发生了变化,使得软件的实现不得不随之改变。当软件实现需要改变时,是否可以尽可能多地保留软件的部分,尽可能少地改变软件的实现,从而满足客户需求的变更?答案是——采用优秀的解耦架构。这种架构就是J2EE的分层架构,在优秀的分层架构里,控制层依赖于业务逻辑层,但绝不与任何具体的业务逻辑组件耦合,只与接口耦合;同样,业务逻辑层依赖于DAO层,也不会与任何具体的DAO组件耦合,而是面向接口编程。采用这种方式的软件实现,即使软件的部分发生改变,其他部分也尽可能不要改变。
注意:即使在传统的硬件行业,也有大量的接口规范。例如PCI接口、显卡或者网卡,只要其遵守PCI的规范,就可以插入主板,与主板通信。至于这块卡内部的实现,不是主板所关心的,这也正是面向接口编程的好处。假如需要提高电脑的性能,需要更新显卡,只要更换另一块PCI接口的显卡,而不是将整台电脑抛弃。如果一台电脑不是采用各种接口组合在一起,而是做成整块,那将意味着即使只需要更新网卡,也要放弃整台电脑。同样,对于软件中的一个个组件,当一个组件需要重构时,尽量不会影响到其他组件。实际上,这是最理想的情况,即使采用目前最优秀的架构,也会有或多或少的影响,这也是软件工程需要努力提高的地方。
技术的更新,系统重构:软件行业的技术更新很快,虽然软件行业的发展不快,但小范围的技术更新特别快。一旦由于客观环境的变化,不得不更换技术时,如何保证系统的改变最小呢?答案还是选择优秀的架构。
在传统的Model 1的程序结构中,只要有一点小的需求发生改变,将意味着放弃整个页面。或者改写。虽然前期的开发速度快,除非可以保证以后永远不会改变应用的结构,否则不要采用Model 1的结构。
采用Hibernate作为持久层技术的最大的好处在于:可以完全以面向对象的方式进行系统分析、系统设计。
DAO模式需要为每个DAO组件编写DAO接口,同时至少提供一个实现类,根据不同需要,可能有多个实现类。用Spring容器代替DAO工厂
通常情况下,引入接口就不可避免需要引入工厂来负责DAO组件的生成。Spring实现了两种基本模式:单态模式和工厂模式。而使用Spring可以完全避免使用工厂模式,因为Spring就是个功能非常强大的工厂。因此,完全可以让Spring充当DAO工厂。
由Spring充当DAO工厂时,无须程序员自己实现工厂模式,只需要将DAO组件配置在Spring容器中,由ApplicationContext负责管理DAO组件的创建即可。借助于Spring提供的依赖注入,其他组件甚至不用访问工厂,一样可以直接使用DAO实例。
优点:
Struts跟Tomcat、Turbine等诸多Apache项目一样,是开源软件,这是它的一大优点。使开发者能更深入的了解其内部实现机制。
除此之外,Struts的优点主要集中体现在两个方面:Taglib和页面导航。Taglib是Struts的标记库,灵活动用,能大大提高开发效率。另外,就目前国内的JSP开发者而言,除了使用JSP自带的常用标记外,很少开发自己的标记,或许Struts是一个很好的起点。
关于页面导航,我认为那将是今后的一个发展方向,事实上,这样做,使系统的脉络更加清晰。通过一个配置文件,即可把握整个系统各部分之间的联系,这对于后期的维护有着莫大的好处。尤其是当另一批开发者接手这个项目时,这种优势体现得更加明显。
缺点:
Taglib是Struts的一大优势,但对于初学者而言,却需要一个持续学习的过程,甚至还会打乱你网页编写的习惯,但是,当你习惯了它时,你会觉得它真的很棒。
Struts将MVC的Controller一分为三,在获得结构更加清晰的同时,也增加了系统的复杂度。
Struts从产生到现在还不到半年,但已逐步越来越多运用于商业软件。虽然它现在还有不少缺点,但它是一种非常优秀的J2EE MVC实现方式,如果你的系统准备采用J2EE MVC架构,那么,不妨考虑一下Struts。

posted @ 2012-07-25 15:25 chen11-1| 编辑 收藏

AJAX的学习与理解 .

1>:今天重新回到对AJAX的认识,首先从AJAX的由来说起,由于感觉自己才疏学浅,

      我感觉只有了解了WEB的发展历史,我们才能更好地理解并运用AJAX。

2>:其实AJAX最大的应用就是我们要理解XMLHttpRequest这个对象。XMLHttpRequest可以提供不重新加载页面的情况下更新网页,在页面加载后在客户端向服务器请数 据, 在  页面加载后在服务器端接受数据,在后台向客户端发送数据。XMLHttpRequest 对象提供了对 HTTP 协议的完全的访问,包括做出 POST 和 HEAD 请求以及普通的 GET 请求的能力。XMLHttpRequest 可以同步或异步返回 Web 服务器的响应,并且能以文本或者一个 DOM 文档形式返回内容。

3>:我们如何创建一个XMLHttpRequest对象呢?

     首先我们要知道XMLHttpRequest对象开始时有微软开发的一个基于IE5,IE6的一个插件,所以他在IE浏览器中肯定有自己的创建方式,IE中把他实现成一个ActiveX对象,但其他浏览器如果也想使用  XMLHttpRequest对象,就必须依靠JAVASCRIPT创建本地对象。我们在使用时不需要判断浏览器的类型,只需要看浏览器提供对ActiveX的支持。

下面就是XMLHttpRequest的创建方式:

[javascript] view plaincopyprint?
01.function createXHR() 
02.{ 
03. if(window.ActiveXObject) 
04. { 
05.  xmlHttpRequest=new ActiveXObject("Microsoft.XMLHTTP"); 
06. } 
07. else if(window.XMLHttpRequest) 
08. { 
09.  xmlHttpRequest=new XMLHttpRequest(); 
10. } 
11. if(null==xmlHttpRequest) 
12. {  
13.  alert("浏览器不支持"); 
14. } 
15.} 
 function createXHR()
 {
  if(window.ActiveXObject)
  {
   xmlHttpRequest=new ActiveXObject("Microsoft.XMLHTTP");
  }
  else if(window.XMLHttpRequest)
  {
   xmlHttpRequest=new XMLHttpRequest();
  }
  if(null==xmlHttpRequest)
  {
   alert("浏览器不支持");
  }
 }4>:介绍XMLHttpRequest的常用属性、方法:

百度其实是个好东西,我没必要复制粘贴:大家可以参考http://baike.baidu.com/view/1105115.htm

5>:XMLHttpRequest的应用:

其实要理解AJAX并学会运用我们只要掌握三方面内容,第一就是XMLHttpRequest对象的创建。第二就是如何从表单获取值并传到服务器。第三就是如何从后台获取数据显示在前台。大家想想AJAX的应用是不是就是围绕这三方面。

下面我们来简单说一下如何从表单获取值的问题:其实只要稍微了解点JavaScript的热你都知道我们DOM文档模型,通过操纵文档对象模型中对象的属性并调用其方法,可以使脚本按照一定的方式显示Web页并与用户的动作进行交互。

我们常用的就是document.getElementById("id").value.来获取网页中的数据。其他的大家用到就百度。

我们获取到值之后就是把这个值传给后台:这里我们一般采用get:方式提交,采用url传参。通过调用:xmlHttpRequest.open("get","url?paramater="+value,true);

最后就是如何从后台获取值传到前台显示:这里是通过xmlHttpRequest.responseText(返回一个字符串)xmlHttpRequest.responseXML返回一个XML文件。

我们可以通过解析这两种值插入到页面中:通常我们用到的显示在htbml中方式是:通过document.getElementById("id").value=xmlHttpRequest.responseText;

或者document.getElementById("id").innerHTML=xmlHttpRequest.responseText;

知道了这些我们先做一个简单地例子:

[javascript] view plaincopyprint?
01.<script type="text/javascript"> 
02.    var xmlHttpRequest=null; 
03.    function createXHR() 
04.    { 
05.        if(window.ActiveXObject) 
06.        { 
07.            xmlHttpRequest=new ActiveXObject("Microsoft.XMLHTTP"); 
08.        } 
09.        else if(window.XMLHttpRequest) 
10.        { 
11.            xmlHttpRequest=new XMLHttpRequest(); 
12.        } 
13.        if(null!=xmlHttpRequest) 
14.        {    
15.            var v1=document.getElementById("num1").value; 
16.            var v2=document.getElementById("num2").value; 
17.            xmlHttpRequest.open("get","servlet/AjaxServlet?v1="+v1+"&v2="+v2,true); 
18.            xmlHttpRequest.onreadystatechange=callback; 
19.            xmlHttpRequest.send(null); 
20.        } 
21.    } 
22.    function callback() 
23.    { 
24.        if(xmlHttpRequest.readyState==4) 
25.        { 
26.            if(xmlHttpRequest.status==200) 
27.            { 
28.                var responseText=xmlHttpRequest.responseText; 
29.                document.getElementById("num3").innerHTML=responseText;//innerHTML不能小写  
30.            } 
31.        } 
32.    } 
33.    </script> 
<script type="text/javascript">
 var xmlHttpRequest=null;
 function createXHR()
 {
  if(window.ActiveXObject)
  {
   xmlHttpRequest=new ActiveXObject("Microsoft.XMLHTTP");
  }
  else if(window.XMLHttpRequest)
  {
   xmlHttpRequest=new XMLHttpRequest();
  }
  if(null!=xmlHttpRequest)
  { 
   var v1=document.getElementById("num1").value;
   var v2=document.getElementById("num2").value;
   xmlHttpRequest.open("get","servlet/AjaxServlet?v1="+v1+"&v2="+v2,true);
   xmlHttpRequest.onreadystatechange=callback;
   xmlHttpRequest.send(null);
  }
 }
 function callback()
 {
  if(xmlHttpRequest.readyState==4)
  {
   if(xmlHttpRequest.status==200)
   {
    var responseText=xmlHttpRequest.responseText;
    document.getElementById("num3").innerHTML=responseText;//innerHTML不能小写
   }
  }
 }
 </script>[html] view plaincopyprint?
01.<form method="" action=""> 
02.    <table border="1" borderstyle="solid" cellpacing="0" > 
03.        <tr><td><input type="text" id="num1"/></td></tr> 
04.        <tr><td><input type="text" id="num2"/></td></tr> 
05.        <tr><td><input type="button" value="submit" onclick="createXHR()"/></td></tr> 
06.        <tr><td><span id="num3"></span></td></tr> 
07.    </table>  
08.   </form> 
<form method="" action="">
    <table border="1" borderstyle="solid" cellpacing="0" >
     <tr><td><input type="text" id="num1"/></td></tr>
     <tr><td><input type="text" id="num2"/></td></tr>
     <tr><td><input type="button" value="submit" onclick="createXHR()"/></td></tr>
     <tr><td><span id="num3"></span></td></tr>
    </table>
   </form>以上代码有借鉴http://blog.csdn.net/csh624366188/article/details/7670500大家也可以去看。

 

还有两哥问题一:如何将结果显示在下拉列表,第二如何读取XML文件,这个稍后介绍。

 

posted @ 2012-07-24 16:49 chen11-1 阅读(1579) | 评论 (0)编辑 收藏

关于Jquery中的链式编程和动画效果(注意事项) .

1.

其实我本身对于链式编程一直不怎么感冒,因为看起来逻辑不怎么清晰,今天就将一个链式编程给拆开了,结果发现,其实JQuery的链式编程原来还是不一样的,这让我想起了java中的链式编程,以前也没怎么考虑过,现在想想,原来自己一直在误区当中。


想要说的就是,Jquery中的链式编程,其执行顺序是从后往前执行的。例如,在做类似qq的分组显示时,用Jquery语句:

$(this).siblings("li[class!=header]").hide().next().show("fast");

就是不可以的,要把它换为

$(this).next().show().siblings("li[class!=header]").hide();


2.

关于动画效果,开始也没怎么考虑,今天发现还是不太一样的。

比如说:

$(this).next().show();

alert(123)

 

$(this).next().show("fast");

alert(123)

二者是不一样的,没有加fast,其立即执行,因此,很tb可能是先执行后面的语句,再执行本语句。也就是说,加了速度的参数,产生的是一段延迟。

posted @ 2012-07-24 16:48 chen11-1| 编辑 收藏

函数式编程的10年演化:越来越纯

在过去10年中,函数式编程的定义一直在慢慢改变,在“Wikipedia page on Functional Programming”上可以显著地反映出来。

在2003年8月14号之前的定义是:函数式编程作为一种模式,强调函数的使用。例如在2011年10月14号,维基百科用了220个单词进行定义,在开头这样描述到:

函数式编程是一种编程风格,它关注的是函数表达式的计算,而不是执行命令。在这些语言上,表达式把函数与基本功能相结合。

函数式编程语言是一种支持和鼓励将电脑运算当成函数计算,比较古老的函数式编程莫过于Lisp,较现代的Scheme,ML,Haskell,Erlang,Clean。Lisp是第一个函数式编程语言,它和Scheme,ML,Haskell一样。

这样的定义一直维持到2003年8月14号,新百科全书在内容制作上有了结构化调整。Luxor把新百科全书的定义与维基百科相融合,创建了一个新的页面并且用了1640个单词进行重新定义,开头定义到:

函数式编程是一种编程范式,把计算看作是一种数学函数计算。与命令式编程相比,tb函数式编程关注的是函数表达式的计算而不是执行命令。在这些语言上,表达式把函数与基本功能相结合。

在这一点上,函数式编程并不强调函数的使用,相反,它意味着编程要与数学函数相结合。在这个定义里还隐藏着另外一个意思:函数越来越纯粹。这一条在定义里并没有明确的表达出来。直到2006年5月29号:

函数式编程是一种编程范式,把计算看作是一种数学函数计算。函数式编程关注的是函数定义而不是实现状态机,与过程式编程相比,它强调命令的连序执行。一个纯函数程序不会去修改状态产生的值(适用于命令式编程),它会构造新的值(但不会覆盖现有值)。

对函数式编程或函数式编程语言没有统一的共识。函数式编程语言的重要特征:高阶和一级函数、闭包、递归。其他还包括编程语言连续性、Hindley-Milner类型诊断系统、懒惰计算和单体。

这里还有一些小区别,关于(普通)函数编程和“纯”形式的函数编程,避免使用不稳定的状态。在2006年5月29号01:07分,在没有任何征兆的情况下,一个叫ideogram的用户进行了微小但是非常有意义的修改:

•函数式编程是一种编程风格,把计算看作是一种数学函数计算并且避免状态和可变数据。
•函数式编程关注函数定义,与过程式编程相比,它强调命令的连序执行。
•函数式编程的依赖λ演算(lambda calculus),Lisp和较新的Haskell。常常提到的是避免状态和副作用(它提供对引用透明),高阶函数,递归和闭包。
该账户仅仅在编辑前几天创建,后来就一直处于禁止状态。

最近,也就是在2012年7月14号,定义页面又出现了新的变化:

在计算机科学领域,函数式编程是一种编程范式,把计算看作是一种数学函数计算并且避免状态和可变数据。它强调函数的应用,与命令式编程语言相比,强调状态的变化。函数式编程根源于λ 演算,一个正式的函数式编程系统在20世纪30年代被开发,用来研究函数的定义,函数的应用和递归。许多函数式编程语言可以看作是对λ演算进行的阐述。

在实际操作中,数学函数和“函数”概念之间在命令式编程上的差异主要表现为命令式函数编程存在改变程序状态值这一缺点。因此,他们缺乏引用透明,相同的语言表达式根据执行应用程序状态,在不同的时间可以产生不同的值。相反,在函数代码上,函数的输出值仅仅依赖于函数的输入参数,所以,输入同一个参数X两次,那么输出结果都是Y。消除副作用也更容易理解和预测程序的行为,这是函数编程语言发展的一个重要推动。

[1]Hudak, Paul。“概念, 发展和函数式编程语言的应用”。ACM Computing Surveys 21 (3): 359–411。上述内容的含义是什么?这一变化是如何产生的?我们正卷入一场(小的)科学革命中,幕后推手又是谁?

根据最新的定义,ML和Lisp不在是函数式语言。用这些语言的子函数去写一些程序来避免可变状态的使用。第一个需求是在ML中使用“ref”或者在Lisp中使用分配和构造突变。然而,对于ML和Lisp来说并不足够,许多标准库都存在负面作用,对于任何IO库来说,都是如此。结果就是,程序在一个范围内可以很方便地编写比较单一的功能与风格,但这也是相当有限的。

 

posted @ 2012-07-24 16:45 chen11-1| 编辑 收藏

Java程序员应该了解的10个面向对象设计原则

面向对象设计原则是OOPS(Object-Oriented Programming System,面向对象的程序设计系统)编程的核心,但大多数Java程序员追逐像Singleton、Decorator、Observer这样的设计模式,而不重视面向对象的分析和设计。甚至还有经验丰富的Java程序员没有听说过OOPS和SOLID设计原则,他们根本不知道设计原则的好处,也不知道如何依照这些原则来进行编程。

众所周知,Java编程最基本的原则就是要追求高内聚和低耦合的解决方案和代码模块设计。查看Apache和Sun的开放源代码能帮助你发现其他Java设计原则在这些代码中的实际运用。Java Development Kit则遵循以下模式:BorderFactory类中的工厂模式、Runtime类中的单件模式。你可以通过Joshua Bloch的《Effective Java》一书来了解更多信息。我个人偏向的另一种面向对象的设计模式是Kathy Sierra的Head First Design Pattern以及Head Firstb Object Oriented Analysis and Design。

虽然实际案例是学习设计原则或模式的最佳途径,但通过本文的介绍,没有接触过这些原则或还在学习阶段的Java程序员也能够了解这10个面向对象的设计原则。其实每条原则都需要大量的篇幅才能讲清楚,但我会尽力做到言简意赅。

原则1:DRY(Don't repeat yourself)

即不要写重复的代码,而是用“abstraction”类来抽象公有的东西。如果你需要多次用到一个硬编码值,那么可以设为公共常量;如果你要在两个以上的地方使用一个代码块,那么可以将它设为一个独立的方法。SOLID设计原则的优点是易于维护,但要注意,不要滥用,duplicate 不是针对代码,而是针对功能。这意味着,即使用公共代码来验证OrderID和SSN,二者也不会是相同的。使用公共代码来实现两个不同的功能,其实就是近似地把这两个功能永远捆绑到了一起,如果OrderID改变了其格式,SSN验证代码也会中断。因此要慎用这种组合,不要随意捆绑类似但不相关的功能。

原则2:封装变化

在软件领域中唯一不变的就是“Change”,因此封装你认为或猜测未来将发生变化的代码。OOPS设计模式的优点在于易于测试和维护封装的代码。如果你使用Java编码,可以默认私有化变量和方法,并逐步增加访问权限,比如从private到protected和not public。有几种Java设计模式也使用封装,比如Factory设计模式是封装“对象创建”,其灵活性使得之后引进新代码不会对现有的代码造成影响。

原则3:开闭原则

即对扩展开放,对修改关闭。这是另一种非常棒的设计原则,可以防止其他人更改已经测试好的代码。理论上,可以在不修改原有的模块的基础上,扩展功能。这也是开闭原则的宗旨。

原则4:单一职责原则

类被修改的几率很大,因此应该专注于单一的功能。如果你把多个功能放在同一个类中,功能之间就形成了关联,改变其中一个功能,有可能中止另一个功能,这时就需要新一轮的测试来避免可能出现的问题。

原则5:依赖注入或倒置原则

这个设计原则的亮点在于任何被DI框架注入的类很容易用mock对象进行测试和维护,因为对象创建代码集中在框架中,客户端代码也不混乱。有很多方式可以实现依赖倒置,比如像AspectJ等的AOP(Aspect Oriented programming)框架使用的字节码技术,或Spring框架使用的代理等。

原则6:优先利用组合而非继承

如果可能的话,优先利用组合而不是继承。一些人可能会质疑,但我发现,组合比继承灵活得多。组合允许在运行期间通过设置类的属性来改变类的行为,也可以通过使用接口来组合一个类,它提供了更高的灵活性,并可以随时实现。《Effective Java》也推荐此原则。

原则7:里氏代换原则(LSP)

根据该原则,子类必须能够替换掉它们的基类,也就是说使用基类的方法或函数能够顺利地引用子类对象。LSP原则与单一职责原则和接口分离原则密切相关,如果一个类比子类具备更多功能,很有可能某些功能会失效,这就违反了LSP原则。为了遵循该设计原则,派生类或子类必须增强功能。

原则8:接口分离原则

采用多个与特定客户类有关的接口比采用一个通用的涵盖多个业务方法的接口要好。设计接口很棘手,因为一旦释放接口,你就无法在不中断执行的情况下改变它。在Java中,该原则的另一个优势在于,在任何类使用接口之前,接口不利于实现所有的方法,所以单一的功能意味着更少的实现方法。

原则9:针对接口编程,而不是针对实现编程

该原则可以使代码更加灵活,以便可以在任何接口实现中使用。因此,在Java中最好使用变量接口类型、方法返回类型、方法参数类型等。《Effective Java》 和《head first design pattern》书中也有提到。

原则10:委托原则

该原则最典型的例子是Java中的equals() 和 hashCode() 方法。为了平等地比较两个对象,我们用类本身而不是客户端类来做比较。这个设计原则的好处是没有重复的代码,而且很容易对其进行修改。

总之,希望这些面向对象的设计原则能帮助你写出更灵活更好的代码。理论是第一步,更重要的是需要开发者在实践中去运用和体会。

 

posted @ 2012-07-24 16:43 chen11-1 阅读(931) | 评论 (0)编辑 收藏

对互联网创新的看法 .


最近对如何在互联网创新进行了许多讨论,现在记下一些感想:
一:前提条件
最好是能解决市场中没有满足的需求,首先确定使用用户群,之后定向推广,有很大可能用户爆发增长。


能促进人与人之间的沟通,拉近人与人之间的距离,打破沟通障碍;


产品要简单,上手快。不要有太多门槛,每一级门槛都会流失大部分用户。


在自己强项和特长的基础上做产品;


创新不是凭空创造,更多的是很多小的改进的积累;


产品使用符合大众习惯,而不是开发者习惯。


小产品如果要快速发展,最好抓住简单,有趣,奇特,搞怪。。。这些特点去设计,产品可以简单,但是要做出精品,好用而且让人印象深刻。需要抛弃复杂思路和做法。


最好能帮助用户解决改进生活中的一个或者几个问题,而不是纯娱乐。


二:关于创造

创造不是凭空的,而是许多在现有基础上小的创新积累的结果,量变产生质变,才会产生伟大的创造。去了解硅谷公司的创新历史会知道这一点。
点点网是给小资的,4399(www.4399.com)是为更广大的底层用户服务的,同样服务底层的还有 掷出窗外(http://www.zccw.info/)后两者的访问量都是巨大的,掷出窗外服务器都顶不住了。这是两种创新思维,前者紧跟硅谷;tb后者贴近中国底层基础需求;两种思路,两种设计和展示方式。
互联网网站需要操作简单,设计简单,零门槛;手机app也需要很简单,越简单,功能单一,会容易传播;
网站展示应该简单,复杂的结果是使用门槛高,传播门槛高,挡住了大部分用户。需要的砍掉多余的设计,为用户呈现月简单越好,设计颜色也应该尽量的少,例如thislife和google的白色很百搭很大众。
网站的名字,如果类似 google 或者自己创造的一个词,没有特殊意义才会更容易赋予很多意义。
手机视频app的爆发期在3G用户量超过2G并且资费很便宜的时候,目前还处于前夜。相信很多大公司在做准备了。
互联网的另外很多机会在垂直领域,这些领域需要有很强的专业背景和资源,才可能在这个领域内做到最好;

三 关于国内网的差距
国外会以互动方式展示功能,功能使用的时候再展现出来,例如评论;而不是把所有功能都列出来web1.0的展示方式;

国外的网站在模拟现实环境,例如把照片排列在一面墙上,网站背景模拟的是白色的墙,照片挂到墙上,贴近现实生活,用户易懂。
网站也在尽可能在模拟触屏的滑动效果;

很简单易懂的表达方式,团队有很高的交互式设计能力;很有苹果风格;

功能用到的时候再展现给用户,而不是摆出所有功能让用户自助选择;如果把网站比喻为餐厅的话,国外很多网站的服务很到位,服务水平很高,国内网站像是小吃部,体验不好。

网站,app设计的最终目标是与真实环境越像越好,用户上手也会很快,他们的设计思路是:尽可能的模拟真实世界,无论是视觉上还是操作上;

差距在哪里? 技术上差距应该不大,差距在同一个思想如何表达给用户,国外强的地方是他们的表达方式和思维方式;点点网许朝军有过一句话:the product is the story we tell to the world。 国内很多创业者有很多故事,但是故事讲的方式不好,理解和认可的人少。

 

posted @ 2012-07-20 15:06 chen11-1 阅读(878) | 评论 (0)编辑 收藏

仅列出标题
共20页: First 上一页 9 10 11 12 13 14 15 16 17 下一页 Last