甜咖啡

我的IT空间

一、卸载jdk1.4

由于Redhat Enterprise Linux 5.6 中自带安装了jdk1.4.2的,所以在安装jdk1.6前我把jdk1.4.2的卸了,步骤如下:

1、打开终端输入 yum remove java
终端显示 Is this ok [y/N]:
输入y ,按回车。
终端显示 Complete! 此时jdk1.4已被卸了。
二、安装jdk1.6

1.下载:jdk-1_5_0_06-linux-i586-rpm.bin
   地址:http://java.sun.com/j2se/1.5.0/download.jsp
2.给文件加上可执行权限
   [root@esprit java]# chmod +x jdk-1_5_0_06-linux-i586-rpm.bin
chmod +x jdk-6u31-linux-i586-rpm.bin
3.执行jdk-1_5_0_06-linux-i586-rpm.bin
   [root@esprit java]# ./jdk-1_5_0_06-linux-i586-rpm.bin
./jdk-6u31-linux-i586-rpm.bin
   执行后生成jdk-6u31-linux-i586.rpm
4.安装jdk-6u31-linux-i586.rpm
rpm -ivh jdk-6u31-linux-i586.rpm
########################################### [100%]
package jdk-1.6.0_31-fcs is already installed
这里我jdk安装在/usr/java目录下

三、配置java环境变量

 环境变量配置有三种方法(分别是:修改/etc/profile文件,修改用户目录下的.bashrc文件,直接在shell下修改)
这里我只讲我用到的修改/etc/profile文件
   [root@esprit java]# vi /etc/profile
   打开文件后,按 I 键,在文件后添加:
 JAVA_HOME =/ usr / java / jdk1.6.0_31
 PATH = $JAVA_HOME / bin:$PATH
 CLASSPATH = .:$JAVA_HOME / lib / tools.jar:$JAVA_HOME / lib / dt.jar:$JAVA_HOME/lib
 export JAVA_HOME PATH CLASSPATH
 
   按esc 键
   输入:wq 保存退出。
   重新登入

四、检查jdk是否装好

在命令行输入: java -version

如果显示版本信息,表示已经安装配置成功

五、卸载jdk1.6

输入 rpm -qa|grep jdk
显示 jdk-1.6.0_24-fcs
卸载 rpm -e –nodeps jdk-1.6.0_24-fcs

posted @ 2012-09-19 14:19 甜咖啡 阅读(7054) | 评论 (1)编辑 收藏

package com.ky.ui.util;

import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileOutputStream;

import javax.imageio.ImageIO;

import com.sun.image.codec.jpeg.JPEGCodec;
import com.sun.image.codec.jpeg.JPEGImageEncoder;

 

/**
Email:

上午11:18:19
*/
public final class ImgRead{

// public final static String getPressImgPath(){
// return ApplicationContext.getRealPath("/template/data/util/shuiyin.gif");
// }

/** *//**
* 把图片印刷到图片上
* @param pressImg -- 水印文件
* @param targetImg -- 目标文件
* @param x
* @param y
*/
public final static void pressImage(String pressImg, String targetImg, int x, int y){
try {
File _file = new File(targetImg);
Image src = ImageIO.read(_file);
int wideth = src.getWidth(null);
int height = src.getHeight(null);
BufferedImage image = new BufferedImage(wideth, height,
BufferedImage.TYPE_INT_RGB);
Graphics g = image.createGraphics();
g.drawImage(src, 0, 0, wideth, height, null);

// 水印文件
File _filebiao = new File(pressImg);
Image src_biao = ImageIO.read(_filebiao);
int wideth_biao = src_biao.getWidth(null);
int height_biao = src_biao.getHeight(null);
g.drawImage(src_biao, wideth - wideth_biao - x, height - height_biao -y, wideth_biao,
height_biao, null);
// /
g.dispose();
FileOutputStream out = new FileOutputStream(targetImg);
JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(out);
encoder.encode(image);
out.close();
} catch (Exception e){
e.printStackTrace();
}
}

/** *//**
* 打印文字水印图片
* @param pressText --文字
* @param targetImg -- 目标图片
* @param fontName -- 字体名
* @param fontStyle -- 字体样式
* @param color -- 字体颜色
* @param fontSize -- 字体大小
* @param x -- 偏移量
* @param y
*/

public static void pressText(String pressText, String targetImg, String fontName,int fontStyle, int color, int fontSize, int x, int y){
try{
File _file = new File(targetImg);
Image src = ImageIO.read(_file);
int wideth = src.getWidth(null);
int height = src.getHeight(null);
BufferedImage image = new BufferedImage(wideth, height,
BufferedImage.TYPE_INT_RGB);
Graphics g = image.createGraphics();
g.drawImage(src, 0, 0, wideth, height, null);
// String s="www.qhd.com.cn";
g.setColor(Color.RED);
g.setFont(new Font(fontName, fontStyle, fontSize));

g.drawString(pressText, wideth - fontSize - x, height - fontSize/2 - y);
g.dispose();
FileOutputStream out = new FileOutputStream(targetImg);
JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(out);
encoder.encode(image);
out.close();
} catch (Exception e){
System.out.println(e);
}
}

public static void main(String[] args){
pressImage("C:/foot_05.gif", "c:/Chart.jpg", 20 ,20);
}
}

posted @ 2012-09-08 19:51 甜咖啡 阅读(273) | 评论 (0)编辑 收藏

//  获取屏幕的边界
  Insets screenInsets = Toolkit.getDefaultToolkit().getScreenInsets(frame.getGraphicsConfiguration());
//  获取底部任务栏高度
  int taskBarHeight = screenInsets.bottom; 

posted @ 2012-09-08 19:46 甜咖啡 阅读(1554) | 评论 (0)编辑 收藏

1、  下载vsftpd

# wget ftp://vsftpd.beasts.org/users/cevans/vsftpd-2.3.2.tar.gz

2、  解压、安装vsftpd

# tar xvfz vsftpd-2.3.2.tar.gz

# cd vsftpd-2.3.2

# make

make命令成功执行后,您将看到vsftpd文件获得当前目录中创建。

# ls -l vsftpd

3、  安装 vsftpd d Linux

# make install

make install,确保vsftpd文件复制到/ usr / local / sbin目录。

# ls -l /usr/local/sbin/vsftpd

4、  复制vsftpd手册页到/usr/share/man/man8,man5

# cp vsftpd.8 /usr/share/man/man8/

# cp vsftpd.conf.5 /usr/share/man/man5/

5、  拷贝vsftpd.cond配置文件

# cp vsftpd.conf /etc

6、   设置Anonymouse FTP访问vsftpd

# mkdir /var/ftp/

# chown root.root /var/ftp

# chmod og-w /var/ftp

 

ftp localhost

Connected to dotcom.

220 (vsFTPd 2.3.2)

530 Please login with USER and PASS.

KERBEROS_V4 rejected as an authentication type

Name (localhost:root): anonymous

331 Please specify the password.

Password:

230 Login successful.

Remote system type is UNIX.

Using binary mode to transfer files.

ftp>

在这个阶段,如果你试图登录与任何其他账户(除了匿名,和ftp),它就会失败,如下所示

# ftp localhost

Connected to dotcom.

220 (vsFTPd 2.3.2)

530 Please login with USER and PASS.

KERBEROS_V4 rejected as an authentication type

Name (localhost:root): ramesh

530 This FTP server is anonymous only.

Login failed.

ftp>

7、   允许LINIX登录使用vsftp

# cp RedHat/vsftpd.pam /etc/pam.d/ftp

#local_enable=YES

# ftp localhost

Connected to dotcom.

220 (vsFTPd 2.3.2)

530 Please login with USER and PASS.

KERBEROS_V4 rejected as an authentication type

Name (localhost:root): ramesh

Password:

230 Login successful.

Remote system type is UNIX.

Using binary mode to transfer files.

ftp>

切记再每次修改完vsftpd.conf文件之后要重启一下vsftpd

# ps -ef | grep vsftpd

# kill -9 {vsftpd-pid}

# /usr/local/sbin/vsftpd &

 

 

如果还不能登录成功,那么要关闭系统其他的ftp服务和防火墙

Service xinetd stop

Service iptables stop

posted @ 2012-08-22 16:15 甜咖啡 阅读(238) | 评论 (0)编辑 收藏
posted @ 2012-05-17 17:56 甜咖啡 阅读(162) | 评论 (0)编辑 收藏
     摘要: 各种排序算法:冒择路(入)兮(稀)快归堆,桶式排序,基数排序 冒泡排序,选择排序,插入排序,稀尔排序,快速排序,归并排序,堆排序,桶式排序,基数排序 一、冒泡排序(BubbleSort) 1. 基本思想:   两两比较待排序数据元素的大小,发现两个数据元素的次序相反时即进行交换,直到没有反序的数据元素为止。 2. 排序过程:   设想被排序的数组R[1..N]垂直竖立,将每个数据元素看作有重量的气...  阅读全文
posted @ 2012-05-17 17:52 甜咖啡 阅读(808) | 评论 (0)编辑 收藏
     摘要: Java反射机制是Java语言被视为准动态语言的关键性质。Java反射机制的核心就是允许在运行时通过Java Reflection APIs来取得已知名字的class类的相关信息,动态地生成此类,并调用其方法或修改其域(甚至是本身声明为private的域或方法)。 也许你使用Java已经很长时间了,可是几乎不会用到Java反射机制。你会嗤之以鼻地告诉我,Java反射机制没啥用...  阅读全文
posted @ 2012-05-17 17:07 甜咖啡 阅读(263) | 评论 (0)编辑 收藏
1.使用mysqladmin修改mysql密码
C:\>mysqladmin -udbuser -p password newpass
Enter password: oldpass
当然用此命令的前提是你把mysql加入了环境变量,如果没有加入环境变量的话那只能在命令行下cd到mysqladmin所在的目录下与此那个次命令了!
-----------------------------------------
2.重置root密码
方法一:
在my.ini的[mysqld]字段加入:
skip-grant-tables
重启mysql服务,这时的mysql不需要密码即可登录数据库
然后进入mysql
mysql>use mysql;
mysql>update user set password=password('新密码') WHERE User='root';
mysql>flush privileges;
运行之后最后去掉my.ini中的skip-grant-tables,重启mysqld即可。
修改mysql密码方法二:
不使用修改my.ini重启服务的方法,通过非服务方式加skip-grant-tables运行mysql来修改mysql密码
停止mysql服务
打开命令行窗口,在bin目录下使用mysqld-nt.exe启动,即在命令行窗口执行: mysqld-nt --skip-grant-tables
然后另外打开一个命令行窗口,登录mysql,此时无需输入mysql密码即可进入。
按以上方法修改好密码后,关闭命令行运行mysql的那个窗口,此时即关闭了mysql,如果发现mysql仍在运行的话可以结束掉对应进程来关闭。
启动mysql服务

-----------------------------------------

记住此方法,走遍天下无mysql密码

posted @ 2012-05-16 18:38 甜咖啡 阅读(180) | 评论 (0)编辑 收藏

先假设一个ftp地址 用户名 密码

      FTP Server: home4u.at.china.com

  User: yepanghuang

  Password: abc123

打开windows的开始菜单,执行“运行”命令,在对话框中输入ftp,按下“确定”按钮将会切换至DOS窗口,出现命令提示符

      ftp>键入命令连接FTP服务器

  ftp> open home4u.at.china.com (回车)

  稍等片刻,屏幕提示连接成功:

  ftp> connected to home4u.china.com

  接下来服务器询问用户名和口令,分别输入yepanghuang和abc123,待认证通过即可。

windows下ftp上传文件:

      比如要把 D:\index.html上传至服务器的根目录中,可以键入:

  ftp> put D:\index.html (回车)

  当屏幕提示你已经传输完毕,可以键入相关命令查看:

  ftp> dir (回车)

windows下ftp上传下载:

      假设要把服务器\images目录中的所有.jpg文件下载至本机中,可以输入指令:

  ftp> cd images(回车) [注:进入\images目录]

  ftp> mget *.jpg

  windows下ftp上传与下载工作完毕,键入bye中断连接。

  ftp> bye(回车)

下面是一些常用的FTP命令:

  1. open:与服务器相连接;

  2. send(put):上传文件;

  3. get:下载文件;

  4. mget:下载多个文件;

  5. cd:切换目录;

  6. dir:查看当前目录下的文件;

  7. del:删除文件;

  8. bye:中断与服务器的连接。

  如果想了解更多,可以键入

  ftp> help (回车)

查看命令集

  ascii: 设定以ASCII方式传送文件(缺省值)

  bell: 每完成一次文件传送,报警提示

  binary: 设定以二进制方式传送文件

  bye: 终止主机FTP进程,并退出FTP管理方式

  case: 当为ON时,用MGET命令拷贝的文件名到本地机器中,全部转换为小写字母

  cd: 同UNIX的CD命令

  cdup: 返回上一级目录

  chmod: 改变远端主机的文件权限

  close: 终止远端的FTP进程,返回到FTP命令状态,所有的宏定义都被删除

  delete: 删除远端主机中的文件

  dir [remote-directory] [local-file]: 列出当前远端主机目录中的文件.如果有本地文件,就将结果写至本地文件

  get [remote-file] [local-file]: 从远端主机中传送至本地主机中

  help [command]: 输出命令的解释

  lcd: 改变当前本地主机的工作目录,如果缺省,就转到当前用户的HOME目录

  ls [remote-directory] [local-file]: 同DIR

posted @ 2012-05-16 18:35 甜咖啡 阅读(9047) | 评论 (0)编辑 收藏

其实在网上也看到过一些文章,介绍如何让java程序以window服务的方式启动。

今天有空,就想用c写一个window服务,在服务启动时来启动一个java程序。

因为在c方面,我十足菜鸟,先到网上搜索了一下关于如何用c写出windows服务,找到一篇介绍的相当详细,参照介绍写了一个window服务。

测试的过程中遇到一个问题,由于我的java程序启动时会在系统托盘显示一个小图标,但通过c写的window服务启运这个java程序后,系统托盘里没有显示小图标。

再搜索,原来:

windows服务程序默认是工作于WinLogon桌面的,服务启动时不会显示GUI界面.可以打开控制面板->服务,查看服务的属性->[登录]-[允许服务与桌面交互],打上钩后,系统托盘就能显示在任务栏。

 

 

用C写一个windows服务

来源:http://www.vckbase.com/document/viewdoc/?id=1474

摘要

  Windows 服务被设计用于需要在后台运行的应用程序以及实现没有用户交互的任务。为了学习这种控制台应用程序的基础知识,C(不是C++)是最佳选择。本文将建立并实现一个简单的服务程序,其功能是查询系统中可用物理内存数量,然后将结果写入一个文本文件。最后,你可以用所学知识编写自己的 Windows 服务。
  当初我写第一个 NT 服务时,我到 MSDN 上找例子。在那里我找到了一篇 Nigel Thompson 写的文章:“Creating a Simple Win32 Service in C++”,这篇文章附带一个 C++ 例子。虽然这篇文章很好地解释了服务的开发过程,但是,我仍然感觉缺少我需要的重要信息。我想理解通过什么框架,调用什么函数,以及何时调用,但 C++ 在这方面没有让我轻松多少。面向对象的方法固然方便,但由于用类对底层 Win32 函数调用进行了封装,它不利于学习服务程序的基本知识。这就是为什么我觉得 C 更加适合于编写初级服务程序或者实现简单后台任务的服务。在你对服务程序有了充分透彻的理解之后,用 C++ 编写才能游刃有余。当我离开原来的工作岗位,不得不向另一个人转移我的知识的时候,利用我用 C 所写的例子就非常容易解释 NT 服务之所以然。
  服务是一个运行在后台并实现勿需用户交互的任务的控制台程序。Windows NT/2000/XP 操作系统提供为服务程序提供专门的支持。人们可以用服务控制面板来配置安装好的服务程序,也就是 Windows 2000/XP 控制面板|管理工具中的“服务”(或在“开始”|“运行”对话框中输入 services.msc /s——译者注)。可以将服务配置成操作系统启动时自动启动,这样你就不必每次再重启系统后还要手动启动服务。
  本文将首先解释如何创建一个定期查询可用物理内存并将结果写入某个文本文件的服务。然后指导你完成生成,安装和实现服务的整个过程。


第一步:主函数和全局定义

首先,包含所需的头文件。例子要调用 Win32 函数(windows.h)和磁盘文件写入(stdio.h):

#include <windows.h>
#include <stdio.h>

接着,定义两个常量:

#define SLEEP_TIME 5000
#define LOGFILE "C:\\MyServices\\memstatus.txt"

SLEEP_TIME 指定两次连续查询可用内存之间的毫秒间隔。在第二步中编写服务工作循环的时候要使用该常量。
LOGFILE 定义日志文件的路径,你将会用 WriteToLog 函数将内存查询的结果输出到该文件,WriteToLog 函数定义如下:

int WriteToLog(char* str)
{
    FILE* log;
    log = fopen(LOGFILE, "a+");
    if (log == NULL)
    return -1;
    fprintf(log, "%s\n", str);
    fclose(log);
    return 0;
}

声明几个全局变量,以便在程序的多个函数之间共享它们值。此外,做一个函数的前向定义:

SERVICE_STATUS ServiceStatus; 
SERVICE_STATUS_HANDLE hStatus; 

void ServiceMain(int argc, char** argv); 
void ControlHandler(DWORD request); 
int InitService();

  现在,准备工作已经就绪,你可以开始编码了。服务程序控制台程序的一个子集。因此,开始你可以定义一个 main 函数,它是程序的入口点。对于服务程序来说,main 的代码令人惊讶地简短,因为它只创建分派表并启动控制分派机。

void main() 
{ 
    SERVICE_TABLE_ENTRY ServiceTable[2];
    ServiceTable[0].lpServiceName = "MemoryStatus";
    ServiceTable[0].lpServiceProc = (LPSERVICE_MAIN_FUNCTION)ServiceMain;
    
    ServiceTable[1].lpServiceName = NULL;
    ServiceTable[1].lpServiceProc = NULL;

    // 启动服务的控制分派机线程
    StartServiceCtrlDispatcher(ServiceTable); 
}

  一个程序可能包含若干个服务。每一个服务都必须列于专门的分派表中(为此该程序定义了一个 ServiceTable 结构数组)。这个表中的每一项都要在 SERVICE_TABLE_ENTRY 结构之中。它有两个域:

  • lpServiceName: 指向表示服务名称字符串的指针;当定义了多个服务时,那么这个域必须指定;
  • lpServiceProc: 指向服务主函数的指针(服务入口点);

  分派表的最后一项必须是服务名和服务主函数域的 NULL 指针,文本例子程序中只宿主一个服务,所以服务名的定义是可选的。
  服务控制管理器(SCM:Services Control Manager)是一个管理系统所有服务的进程。当 SCM 启动某个服务时,它等待某个进程的主线程来调用 StartServiceCtrlDispatcher 函数。将分派表传递给 StartServiceCtrlDispatcher。这将把调用进程的主线程转换为控制分派器。该分派器启动一个新线程,该线程运行分派表中每个服务的 ServiceMain 函数(本文例子中只有一个服务)分派器还监视程序中所有服务的执行情况。然后分派器将控制请求从 SCM 传给服务。

注意:如果 StartServiceCtrlDispatcher 函数30秒没有被调用,便会报错,为了避免这种情况,我们必须在 ServiceMain 函数中(参见本文例子)或在非主函数的单独线程中初始化服务分派表。本文所描述的服务不需要防范这样的情况。

  分派表中所有的服务执行完之后(例如,用户通过“服务”控制面板程序停止它们),或者发生错误时。StartServiceCtrlDispatcher 调用返回。然后主进程终止。


第二步:ServiceMain 函数

  Listing 1 展示了 ServiceMain 的代码。该函数是服务的入口点。它运行在一个单独的线程当中,这个线程是由控制分派器创建的。ServiceMain 应该尽可能早早为服务注册控制处理器。这要通过调用 RegisterServiceCtrlHadler 函数来实现。你要将两个参数传递给此函数:服务名和指向 ControlHandlerfunction 的指针。
  它指示控制分派器调用 ControlHandler 函数处理 SCM 控制请求。注册完控制处理器之后,获得状态句柄(hStatus)。通过调用 SetServiceStatus 函数,用 hStatus 向 SCM 报告服务的状态。
Listing 1 展示了如何指定服务特征和其当前状态来初始化 ServiceStatus 结构,ServiceStatus 结构的每个域都有其用途:

  • dwServiceType:指示服务类型,创建 Win32 服务。赋值 SERVICE_WIN32;
  • dwCurrentState:指定服务的当前状态。因为服务的初始化在这里没有完成,所以这里的状态为 SERVICE_START_PENDING;
  • dwControlsAccepted:这个域通知 SCM 服务接受哪个域。本文例子是允许 STOP 和 SHUTDOWN 请求。处理控制请求将在第三步讨论;
  • dwWin32ExitCode 和 dwServiceSpecificExitCode:这两个域在你终止服务并报告退出细节时很有用。初始化服务时并不退出,因此,它们的值为 0;
  • dwCheckPoint 和 dwWaitHint:这两个域表示初始化某个服务进程时要30秒以上。本文例子服务的初始化过程很短,所以这两个域的值都为 0。

  调用 SetServiceStatus 函数向 SCM 报告服务的状态时。要提供 hStatus 句柄和 ServiceStatus 结构。注意 ServiceStatus 一个全局变量,所以你可以跨多个函数使用它。ServiceMain 函数中,你给结构的几个域赋值,它们在服务运行的整个过程中都保持不变,比如:dwServiceType。
  在报告了服务状态之后,你可以调用 InitService 函数来完成初始化。这个函数只是添加一个说明性字符串到日志文件。如下面代码所示:

// 服务初始化
int InitService() 
{ 
    int result;
    result = WriteToLog("Monitoring started.");
    return(result); 
}

  在 ServiceMain 中,检查 InitService 函数的返回值。如果初始化有错(因为有可能写日志文件失败),则将服务状态置为终止并退出 ServiceMain:

error = InitService(); 
if (error) 
{
    // 初始化失败,终止服务
    ServiceStatus.dwCurrentState = SERVICE_STOPPED; 
    ServiceStatus.dwWin32ExitCode = -1; 
    SetServiceStatus(hStatus, &ServiceStatus); 
    // 退出 ServiceMain
    return; 
}

如果初始化成功,则向 SCM 报告状态:

// 向 SCM 报告运行状态 
ServiceStatus.dwCurrentState = SERVICE_RUNNING; 
SetServiceStatus (hStatus, &ServiceStatus);

接着,启动工作循环。每五秒钟查询一个可用物理内存并将结果写入日志文件。

如 Listing 1 所示,循环一直到服务的状态为 SERVICE_RUNNING 或日志文件写入出错为止。状态可能在 ControlHandler 函数响应 SCM 控制请求时修改。
 

第三步:处理控制请求

  在第二步中,你用 ServiceMain 函数注册了控制处理器函数。控制处理器与处理各种 Windows 消息的窗口回调函数非常类似。它检查 SCM 发送了什么请求并采取相应行动。
  每次你调用 SetServiceStatus 函数的时候,必须指定服务接收 STOP 和 SHUTDOWN 请求。Listing 2 示范了如何在 ControlHandler 函数中处理它们。
  STOP 请求是 SCM 终止服务的时候发送的。例如,如果用户在“服务”控制面板中手动终止服务。SHUTDOWN 请求是关闭机器时,由 SCM 发送给所有运行中服务的请求。两种情况的处理方式相同:

  • 写日志文件,监视停止;
  • 向 SCM 报告 SERVICE_STOPPED 状态;

  由于 ServiceStatus 结构对于整个程序而言为全局量,ServiceStatus 中的工作循环在当前状态改变或服务终止后停止。其它的控制请求如:PAUSE 和 CONTINUE 在本文的例子没有处理。
  控制处理器函数必须报告服务状态,即便 SCM 每次发送控制请求的时候状态保持相同。因此,不管响应什么请求,都要调用 SetServiceStatus。


图一 显示 MemoryStatus 服务的服务控制面板


第四步:安装和配置服务

  程序编好了,将之编译成 exe 文件。本文例子创建的文件叫 MemoryStatus.exe,将它拷贝到 C:\MyServices 文件夹。为了在机器上安装这个服务,需要用 SC.EXE 可执行文件,它是 Win32 Platform SDK 中附带的一个工具。(译者注:Visaul Studio .NET 2003 IDE 环境中也有这个工具,具体存放位置在:C:\Program Files\Microsoft Visual Studio .NET 2003\Common7\Tools\Bin\winnt)。使用这个实用工具可以安装和移除服务。其它控制操作将通过服务控制面板来完成。以下是用命令行安装 MemoryStatus 服务的方法:

sc create MemoryStatus binpath= c:\MyServices\MemoryStatus.exe

  发出此创建命令。指定服务名和二进制文件的路径(注意 binpath= 和路径之间的那个空格)。安装成功后,便可以用服务控制面板来控制这个服务(参见图一)。用控制面板的工具栏启动和终止这个服务。


图二 MemoryStatus 服务的属性窗口

  MemoryStatus 的启动类型是手动,也就是说根据需要来启动这个服务。右键单击该服务,然后选择上下文菜单中的“属性”菜单项,此时显示该服务的属性窗口。在这里可以修改启动类型以及其它设置。你还可以从“常规”标签中启动/停止服务。以下是从系统中移除服务的方法:

sc delete MemoryStatus

指定 “delete” 选项和服务名。此服务将被标记为删除,下次西通重启后,该服务将被完全移除。


第五步:测试服务

  从服务控制面板启动 MemoryStatus 服务。如果初始化不出错,表示启动成功。过一会儿将服务停止。检查一下 C:\MyServices 文件夹中 memstatus.txt 文件的服务输出。在我的机器上输出是这样的:

Monitoring started.
273469440
273379328
273133568
273084416
Monitoring stopped.

  为了测试 MemoryStatus 服务在出错情况下的行为,可以将 memstatus.txt 文件设置成只读。这样一来,服务应该无法启动。
  去掉只读属性,启动服务,在将文件设成只读。服务将停止执行,因为此时日志文件写入失败。如果你更新服务控制面板的内容,会发现服务状态是已经停止。
 

开发更大更好的服务程序

  理解 Win32 服务的基本概念,使你能更好地用 C++ 来设计包装类。包装类隐藏了对底层 Win32 函数的调用并提供了一种舒适的通用接口。修改 MemoryStatus 程序代码,创建满足自己需要的服务!为了实现比本文例子所示范的更复杂的任务,你可以创建多线程的服务,将作业划分成几个工作者线程并从 ServiceMain 函数中监视它们的执行。


posted @ 2012-04-24 11:58 甜咖啡 阅读(1747) | 评论 (0)编辑 收藏

最近的机器内存又爆满了,除了新增机器内存外,还应该好好review一下我们的代码,有很多代码编写过于随意化,这些不好的习惯或对程序语言的不了解是应该好好打压打压了。

 

下面是参考网络资源总结的一些在Java编程中尽可能要做到的一些地方。
1. 尽量在合适的场合使用单例
使用单例可以减轻加载的负担,缩短加载的时间,提高加载的效率,但并不是所有地方都适用于单例,简单来说,单例主要适用于以下三个方面:
第一,控制资源的使用,通过线程同步来控制资源的并发访问;
第二,控制实例的产生,以达到节约资源的目的;
第三,控制数据共享,在不建立直接关联的条件下,让多个不相关的进程或线程之间实现通信。

2. 尽量避免随意使用静态变量
要知道,当某个对象被定义为stataic变量所引用,那么gc通常是不会回收这个对象所占有的内存,如
Java代码
  1. public class A{   
  2. static B b = new B();   
  3. }  
public class A{ static B b = new B(); }
 
此时静态变量b的生命周期与A类同步,如果A类不会卸载,那么b对象会常驻内存,直到程序终止。
3. 尽量避免过多过常的创建Java对象
尽量避免在经常调用的方法,循环中new对象,由于系统不仅要花费时间来创建对象,而且还要花时间对这些对象进行垃圾回收和处理,在我们可以控制的范围内,最大限度的重用对象,最好能用基本的数据类型或数组来替代对象。
4. 尽量使用final修饰符
带有final修饰符的类是不可派生的。在Java核心API中,有许多应用final的例子,例如java.lang.String。为String类指定final防止了使用者覆盖length()方法。另外,如果一个类是final的,则该类所有方法都是final的。Java编译器会寻找机会内联(inline)所有的final方法(这和具体的编译器实现有关)。此举能够使性能平均提高50%。
5. 尽量使用局部变量
调用方法时传递的参数以及在调用中创建的临时变量都保存在栈(Stack)中,速度较快。其他变量,如静态变量、实例变量等,都在堆(Heap)中创建,速度较慢。
6. 尽量处理好包装类型和基本类型两者的使用场所
虽然包装类型和基本类型在使用过程中是可以相互转换,但它们两者所产生的内存区域是完全不同的,基本类型数据产生和处理都在栈中处理,包装类型是对象,是在堆中产生实例。
在集合类对象,有对象方面需要的处理适用包装类型,其他的处理提倡使用基本类型。
7. 慎用synchronized,尽量减小synchronize的方法
都知道,实现同步是要很大的系统开销作为代价的,甚至可能造成死锁,所以尽量避免无谓的同步控制。synchronize方法被调用时,直接会把当前对象锁 了,在方法执行完之前其他线程无法调用当前对象的其他方法。所以synchronize的方法尽量小,并且应尽量使用方法同步代替代码块同步。
8. 尽量使用StringBuilder和StringBuffer进行字符串连接
这个就不多讲了。
9. 尽量不要使用finalize方法
实际上,将资源清理放在finalize方法中完成是非常不好的选择,由于GC的工作量很大,尤其是回收Young代内存时,大都会引起应用程序暂停,所以再选择使用finalize方法进行资源清理,会导致GC负担更大,程序运行效率更差。
10. 尽量使用基本数据类型代替对象
String str = "hello";
上面这种方式会创建一个“hello”字符串,而且JVM的字符缓存池还会缓存这个字符串;
String str = new String("hello");
此时程序除创建字符串外,str所引用的String对象底层还包含一个char[]数组,这个char[]数组依次存放了h,e,l,l,o
11. 单线程应尽量使用HashMap、ArrayList
HashTable、Vector等使用了同步机制,降低了性能。
12. 尽量合理的创建HashMap
当你要创建一个比较大的hashMap时,充分利用另一个构造函数
public HashMap(int initialCapacity, float loadFactor)
避免HashMap多次进行了hash重构,扩容是一件很耗费性能的事,在默认中initialCapacity只有16,而loadFactor是 0.75,需要多大的容量,你最好能准确的估计你所需要的最佳大小,同样的Hashtable,Vectors也是一样的道理。
13. 尽量减少对变量的重复计算
for(int i=0;i<list.size();i++)
应该改为
for(int i=0,len=list.size();i<len;i++)
并且在循环中应该避免使用复杂的表达式,在循环中,循环条件会被反复计算,如果不使用复杂表达式,而使循环条件值不变的话,程序将会运行的更快。 
14. 尽量避免不必要的创建
A a = new A();
if(i==1){list.add(a);}
应该改为
if(i==1){
A a = new A();
list.add(a);}
15. 尽量在finally块中释放资源
程序中使用到的资源应当被释放,以避免资源泄漏。这最好在finally块中去做。不管程序执行的结果如何,finally块总是会执行的,以确保资源的正确关闭。 
16. 尽量使用移位来代替'a/b'的操作
"/"是一个代价很高的操作,使用移位的操作将会更快和更有效
int num = a / 4;
int num = a / 8;
应该改为
int num = a >> 2;
int num = a >> 3;
但注意的是使用移位应添加注释,因为移位操作不直观,比较难理解
17.尽量使用移位来代替'a*b'的操作
同样的,对于'*'操作,使用移位的操作将会更快和更有效
int num = a * 4;
int num = a * 8;
应该改为
int num = a << 2;
int num = a << 3;
18. 尽量确定StringBuffer的容量
StringBuffer 的构造器会创建一个默认大小(通常是16)的字符数组。在使用中,如果超出这个大小,就会重新分配内存,创建一个更大的数组,并将原先的数组复制过来,再 丢弃旧的数组。在大多数情况下,你可以在创建 StringBuffer的时候指定大小,这样就避免了在容量不够的时候自动增长,以提高性能。 
如:StringBuffer buffer = new StringBuffer(1000);  
19. 尽量早释放无用对象的引用
大部分时,方法局部引用变量所引用的对象 会随着方法结束而变成垃圾,因此,大部分时候程序无需将局部,引用变量显式设为null。
例如:
Java代码
  1. Public void test(){   
  2. Object obj = new Object();   
  3. ……   
  4. Obj=null;   
  5. }  
Public void test(){ Object obj = new Object(); …… Obj=null; }
 
上面这个就没必要了,随着方法test()的执行完成,程序中obj引用变量的作用域就结束了。但是如果是改成下面:
Java代码
  1. Public void test(){   
  2. Object obj = new Object();   
  3. ……   
  4. Obj=null;   
  5. //执行耗时,耗内存操作;或调用耗时,耗内存的方法   
  6. ……   
  7. }  
Public void test(){ Object obj = new Object(); …… Obj=null; //执行耗时,耗内存操作;或调用耗时,耗内存的方法 …… }
 
这时候就有必要将obj赋值为null,可以尽早的释放对Object对象的引用。
20. 尽量避免使用二维数组
二维数据占用的内存空间比一维数组多得多,大概10倍以上。
21. 尽量避免使用split
除非是必须的,否则应该避免使用split,split由于支持正则表达式,所以效率比较低,如果是频繁的几十,几百万的调用将会耗费大量资源,如果确实需 要频繁的调用split,可以考虑使用apache的StringUtils.split(string,char),频繁split的可以缓存结果。
22. ArrayList & LinkedList
一 个是线性表,一个是链表,一句话,随机查询尽量使用ArrayList,ArrayList优于LinkedList,LinkedList还要移动指 针,添加删除的操作LinkedList优于ArrayList,ArrayList还要移动数据,不过这是理论性分析,事实未必如此,重要的是理解好2 者得数据结构,对症下药。
23. 尽量使用System.arraycopy ()代替通过来循环复制数组
System.arraycopy() 要比通过循环来复制数组快的多 
24. 尽量缓存经常使用的对象
尽可能将经常使用的对象进行缓存,可以使用数组,或HashMap的容器来进行缓存,但这种方式可能导致系统占用过多的缓存,性能下降,推荐可以使用一些第三方的开源工具,如EhCache,Oscache进行缓存,他们基本都实现了FIFO/FLU等缓存算法。
25. 尽量避免非常大的内存分配
有时候问题不是由当时的堆状态造成的,而是因为分配失败造成的。分配的内存块都必须是连续的,而随着堆越来越满,找到较大的连续块越来越困难。
26. 慎用异常
当创建一个异常时,需要收集一个栈跟踪(stack track),这个栈跟踪用于描述异常是在何处创建的。构建这些栈跟踪时需要为运行时栈做一份快照,正是这一部分开销很大。当需要创建一个 Exception 时,JVM 不得不说:先别动,我想就您现在的样子存一份快照,所以暂时停止入栈和出栈操作。栈跟踪不只包含运行时栈中的一两个元素,而是包含这个栈中的每一个元素。
如 果您创建一个 Exception ,就得付出代价。好在捕获异常开销不大,因此可以使用 try-catch 将核心内容包起来。从技术上讲,您甚至可以随意地抛出异常,而不用花费很大的代价。招致性能损失的并不是 throw 操作——尽管在没有预先创建异常的情况下就抛出异常是有点不寻常。真正要花代价的是创建异常。幸运的是,好的编程习惯已教会我们,不应该不管三七二十一就 抛出异常。异常是为异常的情况而设计的,使用时也应该牢记这一原则。

相关回复:
xuanyuan 写道
7.慎用synchronized,尽量减小synchronize的方法
re:同意,不过文中有个地方说错了,使用synchronized关键字并不一定都是锁定当前对象的,要看具体的锁是什么。如果是在方法上加的synchronized,则是以对象本身为锁的,如果是静态方法则锁的粒度是类。
---------------
9.尽量不要使用finalize方法
re:同意,其实不推荐用finalize方法的根本原因在于,JVM的规范并不保证何时执行该方法,所以用这个方法来释放资源很不合适,有可能造成长时间资源得不到释放。
---------------
16.尽量使用移位来代替'a/b'的操作;17.尽量使用移位来代替'a*b'的操作
re:个人不太同意这两条。这样做确实有更好的性能,但是却牺牲了可读性。这两个操作符对很多程序员来说并不直观。我认为在如今硬件价格不那么昂贵的情况下,略微牺牲一些性能,换来更好的可读性和可维护性是好的选择。
 
wuzhengju 写道
19.尽量早释放无用对象的引用
大部分时,方法局部引用变量所引用的对象 会随着方法结束而变成垃圾,因此,大部分时候程序无需将局部,引用变量显式设为null。
例如:
Public void test(){
Object obj = new Object();
……
Obj=null;
}
上面这个就没必要了,随着方法test()的执行完成,程序中obj引用变量的作用域就结束了。但是如果是改成下面:
Public void test(){
Object obj = new Object();
……
Obj=null;
//执行耗时,耗内存操作;或调用耗时,耗内存的方法
……
}
如果Object obj = new Object(); 如果这对象并不是大对象,这有必要吗?Obj=null;只是告诉jvm这个对象已经成为垃圾,至于什么时候回收,还不能确定! 这可读性也不好!
posted @ 2012-04-16 14:49 甜咖啡 阅读(185) | 评论 (0)编辑 收藏

下面的代码片段是由经过验证的程序修改而来。观察这些代码片段你会发现,跟以前的版本相比,在Java7里,文件相关的操作变得简单的多了。通过使用新的Files类里提供的各种方法,你可以只用一行代码就能完成下列的文件操作:

  • 创建文件
  • 删除文件
  • 复制文件
  • 文件移动/改名

这篇文件是以你对Java7里提供的新的Path类很熟悉为前提,如果你不熟悉这个类,这里就简单说一句,Path是文件系统里对位置的一个逻辑概念,例如c:\ 和../foobar.txt都是Path。

创建和删除文件

下面的代码片段向你展示的是用 Files.createFile (Path target) 方法创建文件的基本用法。

  1. Path target = Paths.get ("D:\\Backup\\MyStuff.txt");
    Path file = Files.createFile (target);  

很多时候,出于安全的原因,你可能希望在创建的文件上设置一下属性,例如:是否可读/可写/写执行。这些属性依赖于文件系统的种类,你需要使用跟文件系统相应的权限辅助类来完成这种操作。例如,PosixFilePermission和PosixFilePermissions为POSIX文件系统设计的。下面的是在POSIX文件系统上的文件设置读写权限的用法。

  1. Path target = Paths.get ("D:\\Backup\\MyStuff.txt");
    Set<PosixFilePermission> perms = PosixFilePermissions.fromString ("rw-rw-rw-");
    FileAttribute<Set<PosixFilePermission>> attr = PosixFilePermissions.asFileAttribute (perms);
    Files.createFile (target, attr);

这个java.nio.file.attribute包里提供了很多关于FilePermission的类。

警告当创建一个带有权限属性的文件时,请注意包含这个文件的文件夹是否有权限的强制约束。例如,你会发现,由于这些限制,尽管你给创建的文件指定了rw-rw-rw权限,实际创建的结果却是rw-r–r–。

删除文件更简单,使用Files.delete (Path)这个方法。

  1. Path target = Paths.get ("D:\\Backup\\MyStuff.txt");
    Files.delete (target);  

拷贝和移动文件

下面的代码向你展示的是使用Files.copy (Path source, Path target)方法做文件拷贝的基本用法。

  1. Path source = Paths.get ("C:\\My Documents\\Stuff.txt");  
  2. Path target = Paths.get ("D:\\Backup\\MyStuff.txt");
    Files.copy (source, target);  

经常的,在拷贝文件的过程中你可能希望指定一些操作设置。在Java7里,你可以通过使用StandardCopyOption enum来设置这些属性。下面看一个例子。

  1. import static java.nio.file.StandardCopyOption.*;  
  2. Path source = Paths.get ("C:\\My Documents\\Stuff.txt");  
  3. Path target = Paths.get ("D:\\Backup\\MyStuff.txt");
  4. Files.copy (source, target, REPLACE_EXISTING);  

拷贝操作时可以使用的属性还包括COPY_ATTRIBUTES (保留文件属性) 和ATOMIC_MOVE (确保移动事务操作的成功,否则进行回滚)。

移动文件的操作跟拷贝很相似,使用Files.move (Path source, Path target)方法。

同样,你也可以指定移动操作的属性,使用Files.move (Path source, Path target, CopyOptions...) 方法里的参数来设置。

  1. import static java.nio.file.StandardCopyOption.*;  
  2. Path source = Paths.get ("C:\\My Documents\\Stuff.txt");  
  3. Path target = Paths.get ("D:\\Backup\\MyStuff.txt");
    Files.move (source, target, REPLACE_EXISTING,COPY_ATTRIBUTES);  

可以看出,新的用于文件操作的NIO.2 API 非常便于使用。

posted @ 2012-04-16 10:25 甜咖啡 阅读(215) | 评论 (0)编辑 收藏

众所周知,随机数是任何一种编程语言最基本的特征之一。而生成随机数的基本方式也是相同的:产生一个0到1之间的随机数。看似简单,但有时我们也会忽略了一些有趣的功能。

我们从书本上学到什么?

最明显的,也是直观的方式,在Java中生成随机数只要简单的调用:

  1. java.lang.Math.random() 

在所有其他语言中,生成随机数就像是使用Math工具类,如abs, pow, floor, sqrt和其他数学函数。大多数人通过书籍、教程和课程来了解这个类。一个简单的例子:从0.0到1.0之间可以生成一个双精度浮点数。那么通过上面的信息,开发人员要产生0.0和10.0之间的双精度浮点数会这样来写:

  1. Math.random() * 10 

而产生0和10之间的整数,则会写成:

  1. Math.round(Math.random() * 10) 

进阶

通过阅读Math.random()的源码,或者干脆利用IDE的自动完成功能,开发人员可以很容易发现,java.lang.Math.random()使用一个内部的随机生成对象 - 一个很强大的对象可以灵活的随机产生:布尔值、所有数字类型,甚至是高斯分布。例如:

  1. new java.util.Random().nextInt(10) 

它有一个缺点,就是它是一个对象。它的方法必须是通过一个实例来调用,这意味着必须先调用它的构造函数。如果在内存充足的情况下,像上面的表达式是可以接受的;但内存不足时,就会带来问题。

一个简单的解决方案,可以避免每次需要生成一个随机数时创建一个新实例,那就是使用一个静态类。猜你可能想到了java.lang.Math,很好,我们就是改良java.lang.Math的初始化。虽然这个工程量低,但你也要做一些简单的单元测试来确保其不会出错。

假设程序需要生成一个随机数来存储,问题就又来了。比如有时需要操作或保护种子(seed),一个内部数用来存储状态和计算下一个随机数。在这些特殊情况下,共用随机生成对象是不合适的。

并发

在Java EE多线程应用程序的环境中,随机生成实例对象仍然可以被存储在类或其他实现类,作为一个静态属性。幸运的是,java.util.Random是线程安全的,所以不存在多个线程调用会破坏种子(seed)的风险。

另一个值得考虑的是多线程java.lang.ThreadLocal的实例。偷懒的做法是通过Java本身API实现单一实例,当然你也可以确保每一个线程都有自己的一个实例对象。

虽然Java没有提供一个很好的方法来管理java.util.Random的单一实例。但是,期待已久的Java 7提供了一种新的方式来产生随机数:

  1. java.util.concurrent.ThreadLocalRandom.current().nextInt(10) 

这个新的API综合了其他两种方法的优点:单一实例/静态访问,就像Math.random()一样灵活。ThreadLocalRandom也比其他任何处理高并发的方法要更快。

经验

Chris Marasti-Georg 指出:

  1. Math.round(Math.random() * 10) 

使分布不平衡,例如:0.0 - 0.499999将四舍五入为0,而0.5至1.499999将四舍五入为1。那么如何使用旧式语法来实现正确的均衡分布,如下:

  1. Math.floor(Math.random() * 11) 

幸运的是,如果我们使用java.util.Random或java.util.concurrent.ThreadLocalRandom就不用担心上述问题了。

Java实战项目里面介绍了一些不正确使用java.util.Random API的危害。这个教训告诉我们不要使用:

  1. Math.abs(rnd.nextInt())%n 

而使用:

  1. rnd.nextInt(n) 
posted @ 2012-04-16 10:01 甜咖啡 阅读(172) | 评论 (0)编辑 收藏
package com.wss;

import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.w3c.dom.Text;

public class GPS_GNSS_XML_Color {
    //删除节点时传入的参数
    private static String deleteNumber;
    
    //修改节点时传入的参数
    private static String updateNumber;
    
    //读取传入的路径,返回一个document对象
    public static Document loadInit(String filePath){
        Document document = null;
        try{
            DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
            DocumentBuilder builder = factory.newDocumentBuilder();
            document = builder.parse(new File(filePath));
            document.normalize();
            return document;
        }catch(Exception e){
            e.printStackTrace();
            System.out.println(e.getMessage());
            return null;
        }
    }

    /**
     * 删除制定的xml
     * @param filePath
     * @return
     */
    public static boolean deleteXML(String filePath){
        deleteNumber = "421f481e-790c-41be-91e3-27d215b73ce2";
        Document document = loadInit(filePath);
        try{
            NodeList nodeList = document.getElementsByTagName("color");
            for(int i=0; i<nodeList.getLength(); i++){
                String number_ = document.getElementsByTagName("number").item(i).getFirstChild().getNodeValue();
                //删除节点时传入的参数
                if(number_.equals(deleteNumber)){
                    Node node = nodeList.item(i);
                    node.getParentNode().removeChild(node);
                    saveXML(document, filePath);
                }
            }
            return true;
        }catch(Exception e){
            e.printStackTrace();
            System.out.println(e.getMessage());
            return false;
        }
    }
    
    /**
     * 修改制定的xml
     * @param filePath
     * @return
     */
    public static boolean updateXML(String filePath){
        updateNumber = "421f481e-790c-41be-91e3-27d215b73ce2";
         //读取传入的路径,返回一个document对象
         Document document = loadInit(filePath);
         try{
            //获取叶节点
             NodeList nodeList = document.getElementsByTagName("color");
            //遍历叶节点
             for(int i=0; i<nodeList.getLength(); i++){
                 String number = document.getElementsByTagName("number").item(i).getFirstChild().getNodeValue();
                 String colorValue = document.getElementsByTagName("colorValue").item(i).getFirstChild().getNodeValue();
                 Double minValue = Double.parseDouble(document.getElementsByTagName("minValue").item(i).getFirstChild().getNodeValue());
                 Double maxValue = Double.parseDouble(document.getElementsByTagName("maxValue").item(i).getFirstChild().getNodeValue());
                 //修改节点时传入的参数
                 if(number.equals(updateNumber)){
                     document.getElementsByTagName("colorValue").item(i).getFirstChild().setNodeValue("black");
                     document.getElementsByTagName("minValue").item(i).getFirstChild().setNodeValue("2222");
                     document.getElementsByTagName("maxValue").item(i).getFirstChild().setNodeValue("22222");
                     System.out.println();
                 }
             }
             saveXML(document, filePath);
             return true;
         }catch(Exception e){
             e.printStackTrace();
             System.out.println(e.getMessage());
             return false;
         }
    }
    
    /**
     * 添加节点
     * @param filePath
     * @return
     */
    public static boolean addXML(String filePath){
        try{
            //读取传入的路径,返回一个document对象
            Document document = loadInit(filePath);
            //创建叶节点
            Element eltColor = document.createElement("color");
            Element eltNumber = document.createElement("number");//创建叶节点的第一个元素
            Element eltColorValue = document.createElement("colorValue");//创建叶节点的第二个元素
            Element eltMinValue = document.createElement("minValue");//创建叶节点的第三个元素
            Element eltMaxValue = document.createElement("maxValue");//创建叶节点的第四个元素
            Text number_ = document.createTextNode(UUID.randomUUID().toString());//创建叶节点的第一个元素下的文本节点
            eltNumber.appendChild(number_);//把该文本节点加入到叶节点的第一个元素里面
            Text colorValue_ = document.createTextNode("colorValue");//创建叶节点的第二个元素下的文本节点
            eltColorValue.appendChild(colorValue_);//把该文本节点加入到叶节点的第二个元素里面
            Text minValue_ = document.createTextNode("100");//创建叶节点的第三个元素下的文本节点
            eltMinValue.appendChild(minValue_);//把该文本节点加入到叶节点的第三个元素里面
            Text maxValue_ = document.createTextNode("200");//创建叶节点的第四个元素下的文本节点
            eltMaxValue.appendChild(maxValue_);//把该文本节点加入到叶节点的第四个元素里面
            //把叶节点下的元素加入到叶节点下
            eltColor.appendChild(eltNumber);
            eltColor.appendChild(eltColorValue);
            eltColor.appendChild(eltMinValue);
            eltColor.appendChild(eltMaxValue);
            //获取根节点
            Element eltRoot = document.getDocumentElement();
            //把叶节点加入到根节点下
            eltRoot.appendChild(eltColor);
            //更新修改后的源文件
            saveXML(document, filePath);
            return true;
        }catch(Exception e){
            e.printStackTrace();
            System.out.println(e.getMessage());
            return false;
        }
    }
    
    /**
     * 把修改后的document写进源文件(更新源文件)
     * @param document
     * @param filePath
     * @return
     */
    public static boolean saveXML(Document document, String filePath){
        try{
            TransformerFactory tFactory = TransformerFactory.newInstance();
            Transformer transformer = tFactory.newTransformer();
            
            DOMSource source = new DOMSource(document);
            StreamResult result = new StreamResult(new File(filePath));
            transformer.transform(source, result);
            return true;
        }catch(Exception e){
            e.printStackTrace();
            System.out.println(e.getMessage());
            return false;
        }
    }
    
    /**
     * 获取xml文件的所有记录
     * @param filePath
     * @return
     */
    public static List<ColorValue> selectXML(String filePath){
         List<ColorValue> colorValueList = new ArrayList<ColorValue>();
         try{
             //读取传入的路径,返回一个document对象
             Document document = loadInit(filePath);
             //获取叶节点
             NodeList nodeList = document.getElementsByTagName("color");
             //遍历叶节点
             for(int i=0; i<nodeList.getLength(); i++){
                 ColorValue colorValue = new ColorValue();
                 String number_ = document.getElementsByTagName("number").item(i).getFirstChild().getNodeValue();
                 String colorValue_ = document.getElementsByTagName("colorValue").item(i).getFirstChild().getNodeValue();
                 Double minValue_ = Double.parseDouble(document.getElementsByTagName("minValue").item(i).getFirstChild().getNodeValue());
                 Double maxValue_ = Double.parseDouble(document.getElementsByTagName("maxValue").item(i).getFirstChild().getNodeValue());
                 colorValue.setNumber(number_);
                 colorValue.setColorValue(colorValue_);
                 colorValue.setMinValue(minValue_);
                 colorValue.setMaxValue(maxValue_);
                 colorValueList.add(colorValue);
             }
             return colorValueList;
         }catch(Exception e){
             e.printStackTrace();
             System.out.println(e.getMessage());
             return null;
         }
    }
}






package com.wss;

public class ColorValue {

    private String number;
    private String colorValue;
    private Double minValue;
    private Double maxValue;
    public String getNumber() {
        return number;
    }
    public void setNumber(String number) {
        this.number = number;
    }
    public String getColorValue() {
        return colorValue;
    }
    public void setColorValue(String colorValue) {
        this.colorValue = colorValue;
    }
    public Double getMinValue() {
        return minValue;
    }
    public void setMinValue(Double minValue) {
        this.minValue = minValue;
    }
    public Double getMaxValue() {
        return maxValue;
    }
    public void setMaxValue(Double maxValue) {
        this.maxValue = maxValue;
    }
}



<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<Colors>
    <color>
        <number>7007b384-fab3-4779-9171-229d0664b6b5</number>
        <colorValue>black</colorValue>
        <minValue>2222</minValue>
        <maxValue>22222</maxValue>
    </color>
    <color>
        <number>421f481e-790c-41be-91e3-27d215b73ce2</number>
        <colorValue>colorValue</colorValue>
        <minValue>100</minValue>
        <maxValue>200</maxValue>
    </color>
</Colors>
posted @ 2011-11-08 21:56 甜咖啡 阅读(9521) | 评论 (1)编辑 收藏

 

        // 写文件UTF-8格式 写一行
  public static void writerTxtFile(String filePath, String text) {
  OutputStreamWriter fs;
  try {
  fs = new OutputStreamWriter(new FileOutputStream(filePath, true), "UTF-8");
  fs.write(text + "\n");
  fs.flush();
  fs.close();
  } catch (UnsupportedEncodingException e1) {
  e1.printStackTrace();
  } catch (FileNotFoundException e1) {
  e1.printStackTrace();
  } catch (IOException e) {
  e.printStackTrace();
  }
  }
 
  // 写文件UTF-8格式 写一行
  public static void writerStringBuffer(String filePath, StringBuffer text) {
  OutputStreamWriter fs;
  try {
  fs = new OutputStreamWriter(new FileOutputStream(filePath, true), "UTF-8");
  fs.write(text + "\n");
  fs.flush();
  fs.close();
  } catch (UnsupportedEncodingException e1) {
  e1.printStackTrace();
  } catch (FileNotFoundException e1) {
  e1.printStackTrace();
  } catch (IOException e) {
  e.printStackTrace();
  }
  }
 
  // 写文件
  public static void writerTxtFile(String filePath, List<String> list) {
  OutputStreamWriter fs;
  try {
  fs = new OutputStreamWriter(new FileOutputStream(filePath, true), "UTF-8");
  for(int i=0; i<list.size(); i++){
  fs.write(list.get(i) + "\n");
  }
  fs.flush();
  fs.close();
  } catch (UnsupportedEncodingException e1) {
  e1.printStackTrace();
  } catch (FileNotFoundException e1) {
  e1.printStackTrace();
  } catch (IOException e) {
  e.printStackTrace();
  }
  }

 

posted @ 2011-11-04 12:33 甜咖啡 阅读(200) | 评论 (0)编辑 收藏

package dateapp;

import java.util.Date;
import java.util.Calendar;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.text.ParseException;
import java.awt.Color;
import java.awt.Font;
import java.awt.Point;
import java.awt.Dimension;
import java.awt.BorderLayout;
import java.awt.FlowLayout;
import java.awt.GridLayout;
import java.awt.Component;
import java.awt.Cursor;
import java.awt.Frame;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
//import javax.swing.JFrame;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JDialog;
import javax.swing.JPanel;
import javax.swing.JLabel;
import javax.swing.JSpinner;
import javax.swing.JSpinner.NumberEditor;
import javax.swing.SpinnerNumberModel;
import javax.swing.SwingUtilities;
import javax.swing.SwingConstants;
import javax.swing.event.ChangeListener;
import javax.swing.event.ChangeEvent;
import javax.swing.border.LineBorder;

public class DateChooseJButton extends JButton {

 private DateChooser dateChooser = null;

 private String preLabel = "";

 public DateChooseJButton() {
  this(getNowDate());
 }

 public DateChooseJButton(SimpleDateFormat df, String dateString) {
  this();
  setText(df, dateString);
 }

 public DateChooseJButton(Date date) {
  this("", date);
 }

 public DateChooseJButton(String preLabel, Date date) {
  if (preLabel != null)
   this.preLabel = preLabel;
  setDate(date);
  setBorder(null);
  setCursor(new Cursor(Cursor.HAND_CURSOR));
  super.addActionListener(new ActionListener() {
   public void actionPerformed(ActionEvent e) {
    if (dateChooser == null)
     dateChooser = new DateChooser();
    Point p = getLocationOnScreen();
    p.y = p.y + 30;
    dateChooser.showDateChooser(p);
   }
  });
 }

 private static Date getNowDate() {
  return Calendar.getInstance().getTime();
 }

 private static SimpleDateFormat getDefaultDateFormat() {
  return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
 }

 // 覆盖父类的方法
 public void setText(String s) {
  Date date;
  try {
   date = getDefaultDateFormat().parse(s);
  } catch (ParseException e) {
   date = getNowDate();
  }
  setDate(date);
 }

 public void setText(SimpleDateFormat df, String s) {
  Date date;
  try {
   date = df.parse(s);
  } catch (ParseException e) {
   date = getNowDate();
  }
  setDate(date);
 }

 public void setDate(Date date) {
  super.setText(preLabel + getDefaultDateFormat().format(date));
 }

 public Date getDate() {
  String dateString = getText().substring(preLabel.length());
  try {
   return getDefaultDateFormat().parse(dateString);
  } catch (ParseException e) {
   return getNowDate();
  }

 }

 // 覆盖父类的方法使之无效
 public void addActionListener(ActionListener listener) {
 }

 private class DateChooser extends JPanel implements ActionListener,
   ChangeListener {
  int startYear = 1980; // 默认【最小】显示年份
  int lastYear = 2050; // 默认【最大】显示年份
  int width = 400; // 界面宽度
  int height = 200; // 界面高度

  Color backGroundColor = Color.gray; // 底色
  // 月历表格配色----------------//
  Color palletTableColor = Color.white; // 日历表底色
  Color todayBackColor = Color.orange; // 今天背景色
  Color weekFontColor = Color.blue; // 星期文字色
  Color dateFontColor = Color.black; // 日期文字色
  Color weekendFontColor = Color.red; // 周末文字色

  // 控制条配色------------------//
  Color controlLineColor = Color.pink; // 控制条底色
  Color controlTextColor = Color.white; // 控制条标签文字色

  Color rbFontColor = Color.white; // RoundBox文字色
  Color rbBorderColor = Color.red; // RoundBox边框色
  Color rbButtonColor = Color.pink; // RoundBox按钮色
  Color rbBtFontColor = Color.red; // RoundBox按钮文字色

  JDialog dialog;
  JSpinner yearSpin;
  JSpinner monthSpin;
  JSpinner hourSpin;
  JComboBox minSpin;
  JComboBox secondBox;
  JButton[][] daysButton = new JButton[6][7];

  DateChooser() {

   setLayout(new BorderLayout());
   setBorder(new LineBorder(backGroundColor, 2));
   setBackground(backGroundColor);

   JPanel topYearAndMonth = createYearAndMonthPanal();
   add(topYearAndMonth, BorderLayout.NORTH);
   JPanel centerWeekAndDay = createWeekAndDayPanal();
   add(centerWeekAndDay, BorderLayout.CENTER);

  }

  private JPanel createYearAndMonthPanal() {

   Calendar c = getCalendar();
   int currentYear = c.get(Calendar.YEAR);
   int currentMonth = c.get(Calendar.MONTH) + 1;
   int currentHour = c.get(Calendar.HOUR_OF_DAY);
   int currentMin = c.get(Calendar.MINUTE);
   int currentSecond = c.get(Calendar.SECOND);

   JPanel result = new JPanel();
   result.setLayout(new FlowLayout());
   result.setBackground(controlLineColor);

   yearSpin = new JSpinner(new SpinnerNumberModel(currentYear,
     startYear, lastYear, 1));
   yearSpin.setPreferredSize(new Dimension(48, 20));
   yearSpin.setName("Year");
   yearSpin.setEditor(new JSpinner.NumberEditor(yearSpin, "####"));
   yearSpin.addChangeListener(this);
   result.add(yearSpin);

   JLabel yearLabel = new JLabel("年");
   yearLabel.setForeground(controlTextColor);
   result.add(yearLabel);

   monthSpin = new JSpinner(new SpinnerNumberModel(currentMonth, 1,
     12, 1));
   monthSpin.setPreferredSize(new Dimension(35, 20));
   monthSpin.setName("Month");
   monthSpin.addChangeListener(this);
   result.add(monthSpin);

   JLabel monthLabel = new JLabel("月");
   monthLabel.setForeground(controlTextColor);
   result.add(monthLabel);

   hourSpin = new JSpinner(new SpinnerNumberModel(currentHour, 0, 23,
     1));
   hourSpin.setPreferredSize(new Dimension(35, 20));
   hourSpin.setName("Hour");
   hourSpin.addChangeListener(this);
   result.add(hourSpin);

   JLabel hourLabel = new JLabel("时");
   hourLabel.setForeground(controlTextColor);
   result.add(hourLabel);

   minSpin = new JComboBox();
   ;
   addComboBoxItem(minSpin);
   minSpin.setPreferredSize(new Dimension(45, 20));
   minSpin.setName("Min");
   minSpin.addItemListener(new java.awt.event.ItemListener() {
    public void itemStateChanged(java.awt.event.ItemEvent e) {
     JComboBox source = (JComboBox) e.getSource();
     Calendar c = getCalendar();
     if (source.getName().equals("Min")) {
      c.set(Calendar.MINUTE, getSelectedMin());
      setDate(c.getTime());
      return;
     }
    }
   });
   result.add(minSpin);

   JLabel minLabel = new JLabel("分");
   hourLabel.setForeground(controlTextColor);
   result.add(minLabel);

   secondBox = new JComboBox();
   addComboBoxItem(secondBox);
   secondBox.setPreferredSize(new Dimension(45, 20));
   secondBox.setName("Second");
   // secondBox.addActionListener(this) ;
   secondBox.addItemListener(new java.awt.event.ItemListener() {
    public void itemStateChanged(java.awt.event.ItemEvent e) {
     JComboBox source = (JComboBox) e.getSource();
     Calendar c = getCalendar();
     if (source.getName().equals("Second")) {
      c.set(Calendar.SECOND, getSelectedSecond());
      setDate(c.getTime());
      return;
     }
    }
   });

   result.add(secondBox);

   JLabel secondLabel = new JLabel("秒");
   hourLabel.setForeground(controlTextColor);
   result.add(secondLabel);

   return result;
  }

  private void addComboBoxItem(JComboBox comboBox) {
   for (int i = 0; i < 60; i++) {
    comboBox.addItem(i);
   }

  }

  private JPanel createWeekAndDayPanal() {
   String colname[] = { "日", "一", "二", "三", "四", "五", "六" };
   JPanel result = new JPanel();
   // 设置固定字体,以免调用环境改变影响界面美观
   result.setFont(new Font("宋体", Font.PLAIN, 12));
   result.setLayout(new GridLayout(7, 7));
   result.setBackground(Color.white);
   JLabel cell;

   for (int i = 0; i < 7; i++) {
    cell = new JLabel(colname[i]);
    cell.setHorizontalAlignment(JLabel.RIGHT);
    if (i == 0 || i == 6)
     cell.setForeground(weekendFontColor);
    else
     cell.setForeground(weekFontColor);
    result.add(cell);
   }

   int actionCommandId = 0;
   for (int i = 0; i < 6; i++)
    for (int j = 0; j < 7; j++) {
     JButton numberButton = new JButton();
     numberButton.setBorder(null);
     numberButton.setHorizontalAlignment(SwingConstants.RIGHT);
     numberButton.setActionCommand(String
       .valueOf(actionCommandId));
     numberButton.addActionListener(this);
     numberButton.setBackground(palletTableColor);
     numberButton.setForeground(dateFontColor);
     if (j == 0 || j == 6)
      numberButton.setForeground(weekendFontColor);
     else
      numberButton.setForeground(dateFontColor);
     daysButton[i][j] = numberButton;
     result.add(numberButton);
     actionCommandId++;
    }

   return result;
  }

  private JDialog createDialog(Frame owner) {
   JDialog result = new JDialog(owner, "日期时间选择", true);
   result.setDefaultCloseOperation(JDialog.HIDE_ON_CLOSE);
   result.getContentPane().add(this, BorderLayout.CENTER);
   result.pack();
   result.setSize(width, height);
   return result;
  }

  void showDateChooser(Point position) {
   Frame owner = (Frame) SwingUtilities
     .getWindowAncestor(DateChooseJButton.this);
   if (dialog == null || dialog.getOwner() != owner)
    dialog = createDialog(owner);
   dialog.setLocation(getAppropriateLocation(owner, position));
   flushWeekAndDay();
   dialog.show();
  }

  Point getAppropriateLocation(Frame owner, Point position) {
   Point result = new Point(position);
   Point p = owner.getLocation();
   int offsetX = (position.x + width) - (p.x + owner.getWidth());
   int offsetY = (position.y + height) - (p.y + owner.getHeight());

   if (offsetX > 0) {
    result.x -= offsetX;
   }

   if (offsetY > 0) {
    result.y -= offsetY;
   }

   return result;

  }

  private Calendar getCalendar() {
   Calendar result = Calendar.getInstance();
   result.setTime(getDate());
   return result;
  }

  private int getSelectedYear() {
   return ((Integer) yearSpin.getValue()).intValue();
  }

  private int getSelectedMonth() {
   return ((Integer) monthSpin.getValue()).intValue();
  }

  private int getSelectedHour() {
   return ((Integer) hourSpin.getValue()).intValue();
  }

  private int getSelectedMin() {
   return (Integer) this.minSpin.getSelectedItem();
  }

  private int getSelectedSecond() {
   return (Integer) this.secondBox.getSelectedItem();
  }

  private void dayColorUpdate(boolean isOldDay) {
   Calendar c = getCalendar();
   int day = c.get(Calendar.DAY_OF_MONTH);
   c.set(Calendar.DAY_OF_MONTH, 1);
   int actionCommandId = day - 2 + c.get(Calendar.DAY_OF_WEEK);
   int i = actionCommandId / 7;
   int j = actionCommandId % 7;
   if (isOldDay)
    daysButton[i][j].setForeground(dateFontColor);
   else
    daysButton[i][j].setForeground(todayBackColor);
  }

  private void flushWeekAndDay() {
   Calendar c = getCalendar();
   c.set(Calendar.DAY_OF_MONTH, 1);
   int maxDayNo = c.getActualMaximum(Calendar.DAY_OF_MONTH);
   int dayNo = 2 - c.get(Calendar.DAY_OF_WEEK);
   for (int i = 0; i < 6; i++) {
    for (int j = 0; j < 7; j++) {
     String s = "";
     if (dayNo >= 1 && dayNo <= maxDayNo)
      s = String.valueOf(dayNo);
     daysButton[i][j].setText(s);
     dayNo++;
    }
   }
   dayColorUpdate(false);
  }

  public void stateChanged(ChangeEvent e) {
   JSpinner source = (JSpinner) e.getSource();
   Calendar c = getCalendar();
   if (source.getName().equals("Hour")) {
    c.set(Calendar.HOUR_OF_DAY, getSelectedHour());
    setDate(c.getTime());
    return;
   }

   dayColorUpdate(true);

   if (source.getName().equals("Year"))
    c.set(Calendar.YEAR, getSelectedYear());
   else
    // (source.getName().equals("Month"))
    c.set(Calendar.MONTH, getSelectedMonth() - 1);
   setDate(c.getTime());
   flushWeekAndDay();
  }

  public void actionPerformed(ActionEvent e) {
   JButton source = (JButton) e.getSource();
   if (source.getText().length() == 0)
    return;
   dayColorUpdate(true);
   source.setForeground(todayBackColor);
   int newDay = Integer.parseInt(source.getText());
   Calendar c = getCalendar();
   c.set(Calendar.DAY_OF_MONTH, newDay);
   setDate(c.getTime());
  }

 }

 public static void main(String[] args){
  new JButton();
 }
}

上述日期控件继承JButton,使用时只要构造出来JButton对象就行了。


posted @ 2011-11-04 12:32 甜咖啡 阅读(4417) | 评论 (1)编辑 收藏

package com.wss;

import java.awt.BorderLayout;

public class SearchTest extends JFrame {

 /**
  *
  */
 private static final long serialVersionUID = 1L;
 private JPanel contentPane;
 private JTextField latitude;
 private JTextField longitude;
 private JTextField max;
 private JTextField min;
 private JTextField center;
 private JComboBox begin;
 private JComboBox end;
 private JTable table;
 private DefaultTableModel dm;
 /**
  * Launch the application.
  */
 public static void main(String[] args) {
  EventQueue.invokeLater(new Runnable() {
   public void run() {
    try {
     SearchTest frame = new SearchTest();
     frame.setVisible(true);
    } catch (Exception e) {
     e.printStackTrace();
    }
   }
  });
 }

 /**
  * Create the frame.
  */
 public SearchTest() {
  setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
  getToolkit();
  setSize(Toolkit.getDefaultToolkit().getScreenSize());
  contentPane = new JPanel();
  contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
  contentPane.setLayout(new BorderLayout(0, 0));
  setContentPane(contentPane);
  
  JPanel panel = new JPanel();
  contentPane.add(panel, BorderLayout.NORTH);
  
  JLabel label = new JLabel("纬度:");
  panel.add(label);
  
  latitude = new JTextField();
  panel.add(latitude);
  latitude.setColumns(10);
  
  JLabel label_1 = new JLabel("经度:");
  panel.add(label_1);
  
  longitude = new JTextField();
  panel.add(longitude);
  longitude.setColumns(10);
  
  JLabel label_2 = new JLabel("时间:");
  panel.add(label_2);
  
  //获取数据库里的时间正序输出
  List<GPSBean> list_ = BusinessSelect.selectTime("select distinct to_char(obvdatetime,'YYYY-mm-dd HH24:MI:SS') t from gps order by t asc");
  String[] time = new String[list_.size()];
  for(int a=0; a<list_.size(); a++){
   time[a] = list_.get(a).getTime();
  }
  begin = new JComboBox(time);
  panel.add(begin);
  
  JLabel label_3 = new JLabel("至");
  panel.add(label_3);
  
  end = new JComboBox(time);
  panel.add(end);
    
  JButton close = new DateChooseJButton();
  panel.add(close);
  
  //点击事件
  search.addActionListener(new SearchTest_search_actionAdapter(this));
  
  JPanel panel_1 = new JPanel();
  contentPane.add(panel_1, BorderLayout.CENTER);
  
  String name[] = {"ID","时间","纬度","经度","值"};
  String sql = "select * from gps order by id desc";
  List<GPSBean> list = BusinessSelect.selectGPS(sql);
  Object gpsValue[][] = new Object[list.size()][5];
  
  for(int i=0; i<list.size(); i++){
   GPSBean gpsBean = list.get(i);
   Object value[] =
    {
     gpsBean.getId(),
     gpsBean.getObvdateTime(),
     gpsBean.getLongitude(),
     gpsBean.getLatitude(),
     gpsBean.getTecvalue()
    };
   for(int j=0; j<value.length; j++){
    gpsValue[i][j] = value[j];
   }
  }
  
  dm = new DefaultTableModel(gpsValue, name);
  table = new JTable(dm);
  table.setPreferredScrollableViewportSize(new Dimension(800,600));
  
  JScrollPane scrollPane = new JScrollPane(table);
  panel_1.add(scrollPane);
  
  JPanel panel_s = new JPanel();
  contentPane.add(panel_s, BorderLayout.SOUTH);
  
  JLabel max_ = new JLabel("最大值:");
  panel_s.add(max_);
  
  max = new JTextField();
  panel_s.add(max);
  max.setColumns(10);
  
  JLabel min_ = new JLabel("最小值:");
  panel_s.add(min_);
  
  min = new JTextField();
  panel_s.add(min);
  min.setColumns(10);
  
  JLabel center_ = new JLabel("中值:");
  panel_s.add(center_);
  
  center = new JTextField();
  panel_s.add(center);
  center.setColumns(10);
 }
 
 public void search_actionPerformed(ActionEvent e){
  dm.setRowCount(0);
  String latitude_value = latitude.getText();
  String longitude_value = longitude.getText();
  
  String begin_value = begin.getSelectedItem().toString();
  String end_value = end.getSelectedItem().toString();
  
  String sql = "";
  
  if(latitude_value.equals("") && longitude_value.equals("")){
   sql = "select * from (select id, to_char(obvdateTime,'YYYY-mm-dd HH24:MI:SS') as d, latitude, longitude, tecvalue, abs(latitude-0) a, abs(longitude-0) b " +
     "from gps where obvdateTime>=TO_DATE('"+begin_value
    +"','YYYY-mm-dd HH24:MI:SS') and obvdateTime<=TO_DATE('"+end_value
    +"','YYYY-mm-dd HH24:MI:SS') order by a asc, b asc) where a<3 and b<5 order by d asc, a asc,b asc";
  }else{
   sql = "select * from (select id, to_char(obvdateTime,'YYYY-mm-dd HH24:MI:SS') as d, latitude, longitude, tecvalue, abs(latitude-"
     +Double.parseDouble(latitude_value)
     +") a, abs(longitude-"+Double.parseDouble(longitude_value)
     +") b from gps where obvdateTime>=TO_DATE('"+begin_value
     +"','YYYY-mm-dd HH24:MI:SS') and obvdateTime<=TO_DATE('"+end_value
     +"','YYYY-mm-dd HH24:MI:SS') order by a asc, b asc) where a<3 and b<5 order by d asc, a asc,b asc";
  }
  
  ResultSet rs = CommontDAO.selectFile(sql);
  Vector<Object> v;
  String time = "2011-02-28 00:00:00";
  List<GPSBean> gpsBeanList = new ArrayList<GPSBean>();
  try{
   while(rs.next()){
    if(time.equals(rs.getString(2)) || time == rs.getString(2)){
    }else{
     GPSBean gpsBean = new GPSBean();
     gpsBean.setId(Integer.parseInt(rs.getString(1)));
     gpsBean.setObvdateTime(rs.getString(2));
     gpsBean.setLatitude(Double.parseDouble(rs.getString(3)));
     gpsBean.setLongitude(Double.parseDouble(rs.getString(4)));
     gpsBean.setTecvalue(Double.parseDouble(rs.getString(5)));
     gpsBeanList.add(gpsBean);
     
     time = rs.getString(2);
     v = new Vector<Object>();
     v.add(rs.getString(1));
     v.add(rs.getString(2));
     v.add(rs.getString(3));
     v.add(rs.getString(4));
     v.add(rs.getString(5));
     dm.addRow(v);
    }
   }
  }catch(Exception ex){
   ex.printStackTrace();
   System.out.println(ex.getMessage());
  }finally{
   CommontDAO.cloes(rs);
   Double tecValue[] = new Double[gpsBeanList.size()];
   for(int i=0; i<gpsBeanList.size(); i++){
    tecValue[i] = gpsBeanList.get(i).getTecvalue();
   }
   
   Double center_value = Sort.center(tecValue);
   Double max_value = Sort.max(tecValue);
   Double min_value = Sort.min(tecValue);
   
   
   max.setText(max_value+"");
   min.setText(min_value+"");
   center.setText(center_value+"");
  }
 }
}
class SearchTest_search_actionAdapter implements ActionListener {
 private SearchTest adaptee;

 SearchTest_search_actionAdapter(SearchTest adaptee) {
  this.adaptee = adaptee;
 }

 public void actionPerformed(ActionEvent e) {
  adaptee.search_actionPerformed(e);
 }
}




package com.wss;

import java.io.File;
import java.io.FileOutputStream;
import java.io.OutputStream;
import java.sql.*;
import java.util.*;

public class BusinessSelect {

 //根据sql查询记录
 public static List<GPSBean> selectGPS(String sql){
  ResultSet rs = null;
  List<GPSBean> list = new ArrayList<GPSBean>();
  try{
   rs = CommontDAO.selectFile(sql);
   while(rs.next()){
    GPSBean gpsBean = new GPSBean();
    gpsBean.setId(Integer.parseInt(rs.getString(1)));
    gpsBean.setObvdateTime(rs.getString(2));
    gpsBean.setLongitude(Double.parseDouble(rs.getString(3)));
    gpsBean.setLatitude(Double.parseDouble(rs.getString(4)));
    gpsBean.setTecvalue(Double.parseDouble(rs.getString(5)));
    list.add(gpsBean);
//    System.out.println(rs.getString(1)+","+rs.getString(2)+","+rs.getString(3)+","+rs.getString(4)+","+rs.getString(5));
   } 
   return list;
  }catch(Exception e){
   e.printStackTrace();
   System.out.println(e.getMessage());
   return null;
  }finally{
   CommontDAO.cloes(rs);
  }
 }
 
 //搜索(根据经度和纬度查询最近一点的记录)
 public static List<GPSBean> selectGPS(Double latitude_, Double longitude_){
  ResultSet rs = null;
  List<GPSBean> list = new ArrayList<GPSBean>();
  try{
   //获取比指定点大的最近的1个值
   String sql = "select id, to_char(obvdateTime,'YYYY-mm-dd HH24:MI:SS'), latitude, longitude, tecvalue, abs(latitude-"+latitude_+") a from gps order by a desc";
   rs = CommontDAO.selectFile(sql);
   while(rs.next()){
    System.out.println(rs.getString(1)+","+rs.getString(2)+","+rs.getString(3)+","+rs.getString(4)+","+rs.getString(5)+","+rs.getString(6));
   }
   System.out.println("---------------------------------------------------------------------------");
   
   sql = "select id, to_char(obvdateTime,'YYYY-mm-dd HH24:MI:SS'), latitude, longitude, tecvalue, abs(longitude-"+longitude_+") b from gps order by b desc";
   rs = CommontDAO.selectFile(sql);
   while(rs.next()){
//    System.out.println(rs.getString(1)+","+rs.getString(2)+","+rs.getString(3)+","+rs.getString(4)+","+rs.getString(5));
    System.out.println(rs.getString(1)+","+rs.getString(2)+","+rs.getString(3)+","+rs.getString(4)+","+rs.getString(5)+","+rs.getString(6));
   }
   System.out.println("+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++");
   
   sql = "select id, to_char(obvdateTime,'YYYY-mm-dd HH24:MI:SS'), latitude, longitude, tecvalue, abs(latitude-"+latitude_+") a, abs(longitude-"+longitude_+") b from gps order by a asc, b asc";
   //重要
//   sql = "select id, to_char(obvdateTime,'YYYY-mm-dd HH24:MI:SS'), latitude, longitude, tecvalue, abs(latitude-"+latitude_+") a, abs(longitude-"+longitude_+") b from gps where obvdateTime>=TO_DATE('2011-03-01 00:00:00','YYYY-mm-dd HH24:MI:SS') and obvdateTime<=TO_DATE('2011-03-01 02:00:00','YYYY-mm-dd HH24:MI:SS') order by a asc, b asc";
   while(rs.next()){
//    System.out.println(rs.getString(1)+","+rs.getString(2)+","+rs.getString(3)+","+rs.getString(4)+","+rs.getString(5));
    System.out.println(rs.getString(1)+","+rs.getString(2)+","+rs.getString(3)+","+rs.getString(4)+","+rs.getString(5)+","+rs.getString(6)+","+rs.getString(7));
   }
   
   return list;
  }catch(Exception e){
   e.printStackTrace();
   System.out.println(e.getMessage());
   return null;
  }finally{
   CommontDAO.cloes(rs);
  }
 }
 
 //搜索(根据经度和纬度查询最近一点的记录)
 public static List<GPSBean> selectGPS(Double latitude_, Double longitude_, String begin, String end){
  ResultSet rs = null;
  List<GPSBean> list = new ArrayList<GPSBean>();
  String sql = "select id, to_char(obvdateTime,'YYYY-mm-dd HH24:MI:SS'), latitude, longitude, tecvalue, abs(latitude-"+latitude_+") a, abs(longitude-"+longitude_+") b from gps where obvdateTime>=TO_DATE('"+begin+"','YYYY-mm-dd HH24:MI:SS') and obvdateTime<=TO_DATE('"+end+"','YYYY-mm-dd HH24:MI:SS') order by a asc, b asc";
  rs = CommontDAO.selectFile(sql);
  String test = "";
  try{
   while(rs.next()){
    GPSBean gpsBean = new GPSBean();
    gpsBean.setId(Integer.parseInt(rs.getString(1)));
    gpsBean.setObvdateTime(rs.getString(2));
    gpsBean.setLatitude(Double.parseDouble(rs.getString(3)));
    gpsBean.setLongitude(Double.parseDouble(rs.getString(4)));
    gpsBean.setTecvalue(Double.parseDouble(rs.getString(5)));
    list.add(gpsBean);
//    System.out.println(rs.getString(1)+","+rs.getString(2)+","+rs.getString(3)+","+rs.getString(4)+","+rs.getString(5)+","+rs.getString(6)+","+rs.getString(7));
//    System.out.println(rs.getString(1)+","+rs.getString(2)+","+rs.getString(3)+","+rs.getString(4)+","+rs.getString(5));
//    test += rs.getString(1)+","+rs.getString(2)+","+rs.getString(3)+","+rs.getString(4)+","+rs.getString(5)+","+rs.getString(6)+","+rs.getString(7)+"\r\n";
   }
//   File f = new File("D:/test.txt");
//   OutputStream out = new FileOutputStream(f,true);
//   out.write(test.getBytes());
   return list;
  }catch(Exception e){
   e.printStackTrace();
   System.out.println(e.getMessage());
   return null;
  }finally{
   CommontDAO.cloes(rs);
  }
 }
 
 //获取时间
 public static List<GPSBean> selectTime(String sql){
  ResultSet rs = null;
  List<GPSBean> list = new ArrayList<GPSBean>();
  try{
   rs = CommontDAO.selectFile(sql);
   while(rs.next()){
    GPSBean gpsBean = new GPSBean();
    gpsBean.setTime(rs.getString(1));
    list.add(gpsBean);
   } 
   return list;
  }catch(Exception e){
   e.printStackTrace();
   System.out.println(e.getMessage());
   return null;
  }finally{
   CommontDAO.cloes(rs);
  }
 }
}

 




package com.wss;

public class GPSBean {

 private int id;
 private String obvdateTime;
 private double longitude;
 private double latitude;
 private double tecvalue;
 private String time;
 public int getId() {
  return id;
 }
 public void setId(int id) {
  this.id = id;
 }
 public String getObvdateTime() {
  return obvdateTime;
 }
 public void setObvdateTime(String obvdateTime) {
  this.obvdateTime = obvdateTime;
 }
 public double getLongitude() {
  return longitude;
 }
 public void setLongitude(double longitude) {
  this.longitude = longitude;
 }
 public double getLatitude() {
  return latitude;
 }
 public void setLatitude(double latitude) {
  this.latitude = latitude;
 }
 public double getTecvalue() {
  return tecvalue;
 }
 public void setTecvalue(double tecvalue) {
  this.tecvalue = tecvalue;
 }
 public String getTime() {
  return time;
 }
 public void setTime(String time) {
  this.time = time;
 }
}





package com.wss;

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.Statement;

import com.db.DBConnectionManager;

public class CommontDAO {

 private static DBConnectionManager dbcm = DBConnectionManager.getInstance();
 
 //insert语句(支持多条sql)
 public static boolean insertFile(String sql){
  Connection con = null;
  Statement st = null;
  try{
   con = dbcm.getConnection();
   st = con.createStatement();
   sql = sql.substring(0, sql.length()-1);
   String[] num = sql.split(";");
   for(int i=0; i<num.length; i++){
    st.addBatch(num[i]);
   }
   st.executeBatch();
   return true;
  }catch(Exception e){
   e.printStackTrace();
   System.out.println(e.getMessage());
   return false;
  }finally{
   close(con, st);
  }
 }

 //select语句(返回一个ResultSet)
 public static ResultSet selectFile(String sql){
  Connection con = null;
  Statement st = null;
  ResultSet rs = null;
  try{
   con = dbcm.getConnection();
   st = con.createStatement();
   rs = st.executeQuery(sql);
   return rs;
  }catch(Exception e){
   e.printStackTrace();
   System.out.println(e.getMessage());
   return rs;
  }
 }

 public static void close(Connection con){
  try{
   if(con != null){
    con.close();
   }
  }catch(Exception e){
   e.printStackTrace();
   System.out.println(e.getMessage());
  }
 }

 public static void close(Connection con, Statement st){
  try{
   if(st != null){
    st.close();
   }
  }catch(Exception e){
   e.printStackTrace();
   System.out.println(e.getMessage());
  }
  close(con);
 }
 
 public static void close(Connection con, Statement st, ResultSet rs){
  try{
   if(rs != null){
    rs.close();
   }
  }catch(Exception e){
   e.printStackTrace();
   System.out.println(e.getMessage());
  }
  close(con, st);
 }
 
 public static void cloes(ResultSet rs){
  try{
   if(rs != null){
    rs.close();
   }
  }catch(Exception e){
   e.printStackTrace();
   System.out.println(e.getMessage());
  }
 }
}






package com.wss;

public class Sort {

 //求最大值
 public static Double max(Double[] value){
  //把数组第一个值最为一个标志
  Double num1 = value[0];
  //中间变量
  Double temp = 0.0;
  for(int i=1; i<value.length; i++){
   if(num1 < value[i]){
    temp = num1;
    num1 = value[i];
    value[i] = temp;
   }
  }
  return num1;
 }
 
 //求最小值
 public static Double min(Double[] value){
  //把数组第一个值最为一个标志
  Double num1 = value[0];
  //中间变量
  Double temp = 0.0;
  for(int i=0; i<value.length; i++){
   if(num1 > value[i]){
    temp = num1;
    num1 = value[i];
    value[i] = temp;
   }
  }
  return num1;
 }
 
 //求中值
 public static Double center(Double[] value){
  Double temp = 0.0;
  //排序
  for(int i=0; i<value.length; i++){
   for(int j=i+1; j<value.length; j++){
    if(value[i] > value[j]){
     temp = value[j];
     value[j] = value[i];
     value[i] = temp;
    }
   }
  }
  //求中值所在的下标位置
  int num = value.length/2;
  return value[num];
  
 }
 
 public static void main(String[] args){
  Double value[] = {4.0, 1.0, 2.0, 3.0};
  System.out.println(Sort.center(value));
 }
}







posted @ 2011-11-04 12:31 甜咖啡 阅读(1572) | 评论 (0)编辑 收藏
DWR(Direct Web Remoting)是一个WEB远程调用框架.利用这个框架可以让AJAX开发变得很简单.利用DWR可以在客户端利用JavaScript直接调用服务端的Java方法并返回值给JavaScript就好像直接本地客户端调用一样(DWR根据Java类来动态生成JavaScrip代码).它的最新版本DWR0.6添加许多特性如:支持Dom Trees的自动配置,支持Spring(JavaScript远程调用spring bean),更好浏览器支持,还支持一个可选的commons-logging日记操作.

以上摘自open-open,它通过反射,将java翻译成javascript,然后利用回调机制,轻松实现了javascript调用Java代码。

其大概开发过程如下:
1.编写业务代码,该代码是和dwr无关的。
2.确认业务代码中哪些类、哪些方法是要由javascript直接访问的。
3.编写dwr组件,对步骤2的方法进行封装。
4.配置dwr组件到dwr.xml文件中,如果有必要,配置convert,进行java和javascript类型互转。
5.通过反射机制,dwr将步骤4的类转换成javascript代码,提供给前台页面调用。
5.编写网页,调用步骤5的javascript中的相关方法(间接调用服务器端的相关类的方法),执行业务逻辑,将执行结果利用回调函数返回。
6.在回调函数中,得到执行结果后,可以继续编写业务逻辑的相关javascript代码。

下面以用户注册的例子,来说明其使用。(注意,本次例子只是用于演示,说明DWR的使用,类设计并不是最优的)。

1.先介绍下相关的Java类

  User: 用户类,
  public class User {
//登陆ID,主键唯一
private String id;
//姓名
private String name;
//口令
private String password;
//电子邮件
private String email;
        
//以下包含getXXX和setXXX方法
.......
  }

  UserDAO:实现User的数据库访问,这里作为一个演示,编写测试代码
  public class UserDAO {
    //存放保存的数据
    private static Map dataMap = new HashMap();

    //持久用户
    public boolean save(User user) {
      if (dataMap.containsKey(user.getId()))
        return false;
      System.out.println("下面开始保存用户");
      System.out.println("id:"+user.getId());
      System.out.println("password:"+user.getPassword());
      System.out.println("name:"+user.getName());
      System.out.println("email:"+user.getEmail());
      dataMap.put(user.getId(), user);
      System.out.println("用户保存结束");
      return true;
    }

    //查找用户
    public User find(String id) {
      return (User)dataMap.get(id);
    }
}

  DWRUserAccess:DWR组件,提供给javascript访问的。

  public class DWRUserAccess {

      UserDAO userDAO = new UserDAO();

      public boolean save(User user) {
        return userDAO.save(user);
      }

      public User find(String id) {
        return userDAO.find(id);
      }
  }
  

  下面说明下程序执行的流程

  1.用户在页面上输入相关注册信息,id、name、password、email,点击“提交”按钮
  2.javascript代码开始执行,根据用户填写相关信息,通过dwr提供的DWRUserAccess.js里save的方法,调用服务器端的DWRUserAccess类save方法,将注册信息保存。
  3.通过DWRUserAccess.jsp里的find方法,调用服务器端DWRUserAccess类里的find方法,执行用户信息查找。

  注意,在以上的执行过程中,DWRUserAccess是供DWR调用的,是DWR组件,因此需要将DWRUserAccess类配置到dwr中。

  接下来讲解本次dwr测试环境的配置。

  1.新建一个webapp,命名为testApp
  2.将dwr.jar拷贝到testApp的WEB-INF的lib目录下
  3.编译上面的User,UserDAO,DWRUserAccess类,放到classes目录下
  4.在web.xml中配置servlet,适配路径到dwr目录下,如下所示
    <servlet>
    <servlet-name>dwr-invoker</servlet-name>
    <display-name>DWR Servlet</display-name>
    <description>Direct Web Remoter Servlet</description>
    <servlet-class>uk.ltd.getahead.dwr.DWRServlet</servlet-class>
    <init-param>
      <param-name>debug</param-name>
      <param-value>true</param-value>
    </init-param>
    <init-param>
      <param-name>scriptCompressed</param-name>
      <param-value>false</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
  </servlet>

  <servlet-mapping>
    <servlet-name>dwr-invoker</servlet-name>
    <url-pattern>/dwr/*</url-pattern>
  </servlet-mapping>

  以上的配置可以拦截testApp下所有指向dwr的请求,关于这个拦截器,我们会在后面介绍。

  5.WEB-INF下新建一个dwr.xml文件,内容如下:
  < xml version="1.0" encoding="UTF-8" >
<!DOCTYPE dwr PUBLIC "-//GetAhead Limited//DTD Direct Web Remoting 1.0//EN" "http://www.getahead.ltd.uk/dwr/dwr10.dtd">

<dwr>
  <allow>
<create creator="new" javascript="DWRUserAccess">
      <param name="class" value="test.DWRUserAccess"/>
    </create>
<convert converter="bean" match="test.User"/>
  </allow>
</dwr>

  这里我们把DWRUserAccess配置到了dwr中,create元素中,creater="new"表示每调用一次DWRUserAccess时,需要new一个这样的类;javascript="DWRUserAccess",表示提供给前台页面调用的javascirpt文件是DWRUserAccess.js。

  convert元素用于数据类型转换,即java类和javascript之间相互转换,因为和前台交换的是User对象,因此需要对此使用bean转换,我们将在后面介绍这个类。

  4.编写测试的HTML页面 test.html
   <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML>
<HEAD>
<TITLE>DWR测试</TITLE>
<meta http-equiv=Content-Type content="text/html; charset=gb2312">
<script src="/oblog312/dwr/engine.js"></script>
<script src="/oblog312/dwr/util.js"></script>
<script src="/oblog312/dwr/interface/DWRUserAccess.js"></script>
</HEAD>
<BODY>
<B>用户注册</B><br>
------------------------------------------------
<Br>
<form name="regForm">
登陆ID:<input type="text" name="id"><br>
口  令:<input type="password" name="password"><br>
姓  名:<input type="text" name="name"><br>
电子邮件:<input type="text" name="email"><br>
<input type="button" name="submitBtn" value="提交" onclick="OnSave()"><br>
    </form>

<br>
<br><B>用户查询</B><br>
------------------------------------------------
<Br>
<form name="queryForm">
登陆ID:<input type="text" name="id"><br>
<input type="button" name="submitBtn" value="提交" onclick="OnFind()"><br>
</form>
<br>
</BODY>
</HTML>
<SCRIPT LANGUAGE="JavaScript">
<!--
function saveFun(data) {
if (data) {
  alert("注册成功!");
} else {
  alert("登陆ID已经存在!");
}
}

function OnSave() {
var userMap = {};
userMap.id = regForm.id.value;
userMap.password = regForm.password.value;
userMap.name = regForm.name.value;
userMap.email = regForm.email.value;
DWRUserAccess.save(userMap, saveFun);
}

function findFun(data) {
if (data == null) {
  alert("无法找到用户:"+queryForm.id.value);
  return;
}

alert("找到用户,nid:"+data.id+",npassword:"+data.password+",nname:"+data.name+",nemail:"+data.email);

}

function OnFind() {
DWRUserAccess.find(queryForm.id.value, findFun);
}
//-->
</SCRIPT>


以下对页面的javascript进行解释

<script src="/oblog312/dwr/engine.js"></script>
<script src="/oblog312/dwr/util.js"></script>
这两个是dwr提供的,用户可以不必关心,只需要导入即可

<script src="/oblog312/dwr/interface/DWRUserAccess.js"></script>
是我们编写的DWRUserAccess类,经dwr反射后,生成的javascript代码,它和DWRUserAccess.java是对应的,供用户调用,实际上我们就是通过这个js文件去调用服务器端的DWRUserAccess类的。

<SCRIPT LANGUAGE="JavaScript">
<!--
function saveFun(data) {
if (data) {
  alert("注册成功!");
} else {
  alert("用户名已经存在!");
}
}

function OnSave() {
var userMap = {};
userMap.id = regForm.id.value;
userMap.password = regForm.password.value;
userMap.name = regForm.name.value;
userMap.email = regForm.email.value;
DWRUserAccess.save(userMap, saveFun);
}

function findFun(data) {
if (data == null) {
  alert("无法找到用户:"+queryForm.id.value);
  return;
}

alert("找到用户,nid:"+data.id+",npassword:"+data.password+",nname:"+data.name+",nemail:"+data.email);

}

function OnFind() {
DWRUserAccess.find(queryForm.id.value, findFun);
}
//-->
</SCRIPT>

这段javascirpt代码,我们来看下OnSave函数,首先它构造一个map,将表单数据都设置到map中,然后调用DWRUserAccess.save(userMap, saveFun),执行save操作。大家可以注意到,服务器端的DWRUserAccess中的save方法是这样的:boolean save(User user),其参数是一个User对象,返回一个boolean值;而客户端的方法是这样的:save(userMap,saveFun),第一个参数userMap是javascirpt中的map对象,在这里相当于服务器端的User对象(在服务器端执行时,会通过convert转换成User对象),前面我们提到dwr是利用回调函数来返回执行结果的,第二个参数saveFun即是一个回调函数。在函数function saveFun(data)中,data是执行结果,这里是一个bool值,非常简单的,我们通过判断data是否为真,可以知道用户名是否重复,用户是否注册成功。

看一下OnFind查找函数,执行结果在回调函数findFun(data)中,因为服务器端返回的是一个User对象,通过convert,将会转换成javascript的一个map对象,
于是在findFun中,通过data.id、data.name、data.password、data.email我们可以轻松的访问到这个User对象。


好了配置完毕,启动服务器,在目录中打入localhost/testApp/test.html。

1.在“用户注册”表单中,id框中输入admin,password中输入123456,name中输入chenbug,email中输入chenbug@zj.com,点击提交按钮,弹出对话框:“注册成功”,在服务器后台可以看到信息如下:

下面开始保存用户
id:admin
password:123456
name:chenbug
email:chenbug@zj.com
用户保存结束

再次点击提交按钮,弹出对话框“登陆ID已经存在”。

2.在“用户查询”对话框中,输入登陆ID为admin,点击提交按钮,提示找到用户,并显示相关信息,输入admin123,点击提交按钮,提示无法找到用户。

至此,测试结束。


后续:
1。拦截器 uk.ltd.getahead.dwr.DWRServlet
该类拦截所有指向dwr目录下的请求,并调用Processor的handler方法进行处理,在uk.ltd.getahead.dwr.impl.DefaultProcessor下,我们可以看到详细的处理过程。
if (pathInfo.length() == 0 ||
            pathInfo.equals(HtmlConstants.PATH_ROOT) ||
            pathInfo.equals(req.getContextPath()))
        {
            resp.sendRedirect(req.getContextPath() + servletPath + HtmlConstants.FILE_INDEX);
        }
        else if (pathInfo.startsWith(HtmlConstants.FILE_INDEX))
        {
            index.handle(req, resp);
        }
        else if (pathInfo.startsWith(HtmlConstants.PATH_TEST))
        {
            test.handle(req, resp);
        }
        else if (pathInfo.startsWith(HtmlConstants.PATH_INTERFACE))
        {
            iface.handle(req, resp);
        }
        else if (pathInfo.startsWith(HtmlConstants.PATH_EXEC))
        {
            exec.handle(req, resp);
        }
        else if (pathInfo.equalsIgnoreCase(HtmlConstants.FILE_ENGINE))
        {
            file.doFile(req, resp, HtmlConstants.FILE_ENGINE, HtmlConstants.MIME_JS);
        }
        else if (pathInfo.equalsIgnoreCase(HtmlConstants.FILE_UTIL))
        {
            file.doFile(req, resp, HtmlConstants.FILE_UTIL, HtmlConstants.MIME_JS);
        }
        else if (pathInfo.equalsIgnoreCase(HtmlConstants.FILE_DEPRECATED))
        {
            file.doFile(req, resp, HtmlConstants.FILE_DEPRECATED, HtmlConstants.MIME_JS);
        }
        else
        {
            log.warn("Page not found (" + pathInfo + "). In debug/test mode try viewing /[WEB-APP]/dwr/"); //$NON-NLS-1$ //$NON-NLS-2$
            resp.sendError(HttpServletResponse.SC_NOT_FOUND);
        }

通过判断request请求的servlet路径,进行处理,大家可以自己去参看,这里不详细讨论。


2.bean转换器,<convert converter="bean" match="test.User"/>
将dwr.jar解压缩,在路径ukltdgetaheaddwr下可以看到dwr.xml,这里配置了系统默认的一些转换器,
<converter id="bean" class="uk.ltd.getahead.dwr.convert.BeanConverter"/>即是刚才用到User类的转换器,进入代码我们来看看它是如何在javascript和java间进行转换的。

打开BeanConverter代码,定位到函数

public Object convertInbound(Class paramType, InboundVariable iv, InboundContext inctx) throws ConversionException

即是将javascript对象转换成java对象的,其中
paramType即Class类型,在上面的例子中是test.User,
InboundVariable iv,是传入的值,通过iv.getValue可以得到传入的javascript值串
InboundContext inctx,是入口参数上下文,用于保存转换的后java对象。

因为前台传入的是一个javascript的map类型,而map肯定是以{开始和以}结束的,于是在这个函数一开始进行了判断
if (!value.startsWith(ConversionConstants.INBOUND_MAP_START))
        {
            throw new IllegalArgumentException(Messages.getString("BeanConverter.MissingOpener", ConversionConstants.INBOUND_MAP_START)); //$NON-NLS-1$
        }

        if (!value.endsWith(ConversionConstants.INBOUND_MAP_END))
        {
            throw new IllegalArgumentException(Messages.getString("BeanConverter.MissingCloser", ConversionConstants.INBOUND_MAP_START)); //$NON-NLS-1$
        }

javascript中,map里各个项是用逗号连接的,如var userMap = {id:'admin',password:'123456',name:'chenbug',email:'chenbug@zj.com'};而每个项的键值对是用冒号连接的,
在convertInbound函数的接下来的处理中,即是通过分析map字串,通过paramType构造java实例(即User类),然后通过反射,将这些键值对设置到java实例中,并返回。
这样就完成了javascript到java的转换。


另一个函数
public String convertOutbound(Object data, String varname, OutboundContext outctx) throws ConversionException

即是将java对象转换为javascript对象(其实是声明和赋值语句)。
Object data ,是待转换的java对象
String varname,是javascript中的该对象的变量名
OutboundContext outctx,传出参数上下文,用于保存转换后的javascript值

StringBuffer buffer = new StringBuffer();
        buffer.append("var "); //$NON-NLS-1$
        buffer.append(varname);
        buffer.append("={};"); //$NON-NLS-1$
这里声明了map类型的变量。

即下来来的代码即是通过反射进行变量赋值,如下
  buffer.append(varname);
                    buffer.append('.');
                    buffer.append(name);
                    buffer.append('=');
                    buffer.append(nested.getAssignCode());
                    buffer.append(';');
大家可以自己去参看更多的代码。

3.dwr本身提供了一个测试环境,大家在配置完后,可以在IE中输入地址http://localhost/testApp/dwr/index.html,看到配置的各DWR组件,并进行相关测试。
posted @ 2011-10-13 09:36 甜咖啡 阅读(270) | 评论 (0)编辑 收藏

先准备好软件:

Apache官方下载地址:apache_2.0.55-win32-x86-no_ssl.msi更多版本在这里

php官方下载地址:php-5.0.5-Win32.zip更多镜像下载地址更多版本下载

mysql官方下载地址:mysql-4.1.14-win32.zip更多镜像下载地址更多版本下载

一、安装Apache,配置成功一个普通网站服务器

运行下载好的“apache_2.0.55-win32-x86-no_ssl.msi”,出现如下界面:

 

出现Apache HTTP Server 2.0.55的安装向导界面,点“Next”继续

 

确认同意软件安装使用许可条例,选择“I accept the terms in the license agreement”,点“Next”继续

 

将Apache安装到Windows上的使用须知,请阅读完毕后,按“Next”继续

 

设置系统信息,在Network Domain下填入您的域名(比如:goodwaiter.com),在Server Name下填入您的服务器名称(比如:www.goodwaiter.com,也就是主机名加上域名),在Administrator's Email Address下填入系统管理员的联系电子邮件地址(比如:yinpeng@xinhuanet.com),上述三条信息仅供参考,其中联系电子邮件地址会在当系统故障时提供给访问者,三条信息均可任意填写,无效的也行。下面有两个选择,图片上选择的是为系统所有用户安装,使用默认的80端口,并作为系统服务自动启动;另外一个是仅为当前用户安装,使用端口8080,手动启动。一般选择如图所示。按“Next”继续。]

 

选择安装类型,Typical为默认安装,Custom为用户自定义安装,我们这里选择Custom,有更多可选项。按“Next”继续

 

出现选择安装选项界面,如图所示,左键点选“Apache HTTP Server 2.0.55”,选择“This feature, and all subfeatures, will be installed on local hard drive.”,即“此部分,及下属子部分内容,全部安装在本地硬盘上”。点选“Change...”,手动指定安装目录。

 

我这里选择安装在“D:\”,各位自行选取了,一般建议不要安装在操作系统所在盘,免得操作系统坏了之后,还原操作把Apache配置文件也清除了。选“OK”继续。

 

返回刚才的界面,选“Next”继续。

 

确认安装选项无误,如果您认为要再检查一遍,可以点“Back”一步步返回检查。点“Install”开始按前面设定的安装选项安装。

 

正在安装界面,请耐心等待,直到出现下面的画面。

 

安装向导成功完成,这时右下角状态栏应该出现了下面的这个绿色图标,表示Apache服务已经开始运行,按“Finish”结束Apache的软件安装

 

我们来熟悉一下这个图标,很方便的,在图标上左键单击,出现如下界面,有“Start(启动)”、“Stop(停止)”、“Restart(重启动)”三个选项,可以很方便的对安装的Apache服务器进行上述操作。

 

好了现在我们来测试一下按默认配置运行的网站界面,在IE地址栏打“http://127.0.0.1”,点“转到”,就可以看到如下页面,表示Apache服务器已安装成功。

 

现在开始配置Apache服务器,使它更好的替我们服务,事实上,如果不配置,你的安装目录下的Apache2\htdocs文件夹就是网站的默认根目录,在里面放入文件就可以了。这里我们还是要配置一下,有什么问题或修改,配置始终是要会的,如图所示,“开始”、“所有程序”、“Apache HTTP Server 2.0.55”、“Configure Apache Server”、“Edit the Apache httpd conf Configuration file”,点击打开。

 

XP的记事本有了些小变化,很实用的一个功能就是可以看到文件内容的行、列位置,按下图所示,点“查看”,勾选“状态栏”,界面右下角就多了个标记,“Ln 78, Col 10”就表示“行 78,列 10”,这样可以迅速的在文件中定位,方便解说。当然,你也可以通过“编辑”,“查找”输入关键字来快速定位。每次配置文件的改变,保存后,必须在 Apache服务器重启动后生效,可以用前面讲的小图标方便的控制服务器随时“重启动”。

 

现在正式开始配置Apache服务器,“Ln 228”,或者查找关键字“DocumentRoot”(也就是网站根目录),找到如下图所示地方,然后将""内的地址改成你的网站根目录,地址格式请照图上的写,主要是一般文件地址的“\”在Apache里要改成“/”。

 

“Ln 253”,同样,你也可以通过查找“

 

“Ln321”,DirectoryIndex(目录索引,也就是在仅指定目录的情况下,默认显示的文件名),可以添加很多,系统会根据从左至右的顺序来优先显示,以单个半角空格隔开,比如有些网站的首页是index.htm,就在光标那里加上“index.htm ”文件名是任意的,不一定非得“index.html”,比如“test.php”等,都可以。

 

这里有一个选择配置选项,以前可能要配置,现在好像修正过来了,不用配置了,就是强制所有输出文件的语言编码,html文件里有语言标记(,这个就是设定文档语言为gb2312)的也会强制转换。如果打开的网页出现乱码,请先检查网页内有没有上述 html语言标记,如果没有,添加上去就能正常显示了。把“# DefaultLanguage nl”前面的“# ”去掉,把“nl”改成你要强制输出的语言,中文是“zh-cn”,保存,关闭。

 

好了,简单的Apache配置就到此结束了,现在利用先前的小图标重启动,所有的配置就生效了,你的网站就成了一个网站服务器,如果你加载了防火墙,请打开80或8080端口,或者允许Apache程序访问网络,否则别人不能访问。如果你有公网IP(一般ADSL或电话拨号上网的都是),就可以邀请所有能上网的朋友访问使用http://你的IP地址(IP地址查询可访问http://www.goodwaiter.com,查询内容内即是)你的网站了;如果你没有公网IP,也可以把内网IP地址告诉局域网内的其它用户,让他们通过http://你的内网IP地址,访问你的网站。

二、php的安装、以module方式,将php与apache结合使你的网站服务器支持php服务器脚本程序

将下载的php安装文件php-5.0.5-Win32.zip右键解压缩。

 

指定解压缩的位置,我的设定在“D:\php”

 

查看解压缩后的文件夹内容,找到“php.ini-dist”文件,将其重命名为“php.ini”,打开编辑,找到下面图中的地方, Ln385,有一个“register_globals = Off”值,这个值是用来打开全局变量的,比如表单送过来的值,如果这个值设为“Off”,就只能用“$_POST['变量名']、$_GET['变量名 ']”等来取得送过来的值,如果设为“On”,就可以直接使用“$变量名”来获取送过来的值,当然,设为“Off”就比较安全,不会让人轻易将网页间传送的数据截取。这个值是否改成“On”就看自己感觉了,是安全重要还是方便重要?

 

这里还有一个地方要编辑,功能就是使php能够直接调用其它模块,比如访问mysql,如下图所示,Ln563,选择要加载的模块,去掉前面的 “;”,就表示要加载此模块了,加载的越多,占用的资源也就多一点,不过也多不到哪去,比如我要用mysql,就要把“;extension= php_mysql.dll”前的“;”去掉。所有的模块文件都放在php解压缩目录的“ext”之下,我这里的截图是把所有能加载的模块都加载上去了,前面的“;”没去掉的,是因为“ext”目录下默认没有此模块,加载会提示找不到文件而出错。这里只是参考,一般不需要加载这么多,需要的加载上就可以了,编辑好后保存,关闭。

 

如果上一步加载了其它模块,就要指明模块的位置,否则重启Apache的时候会提示“找不到指定模块”的错误,这里介绍一种最简单的方法,直接将php安装路径、里面的ext路径指定到windows系统路径中——在“我的电脑”上右键,“属性”,选择“高级”标签,点选“环境变量”,在“系统变量”下找到“Path”变量,选择,双击或点击“编辑”,将“;D:\php;D:\php\ext”加到原有值的后面,当然,其中的“D:\php” 是我的安装目录,你要将它改为自己的php安装目录,如下图所示,全部确定。系统路径添加好后要重启电脑才能生效,可以现在重启,也可以在所有软件安装或配置好后重启。

 

现在开始将php以module方式与Apache相结合,使php融入Apache,照先前的方法打开Apache的配置文件,Ln 173,找到这里,添加进如图所示选中的两行,第一行“LoadModule php5_module D:/php/php5apache2.dll”是指以module方式加载php,第二行“PHPIniDir "D:/php"”是指明php的配置文件php.ini的位置,是当然,其中的“D:/php”要改成你先前选择的php解压缩的目录。

 

还是Apache的配置文件,Ln 757,加入“AddType application/x-httpd-php .php”、“AddType application/x-httpd-php .html”两行,你也可以加入更多,实质就是添加可以执行php的文件类型,比如你再加上一行“AddType application/x-httpd-php .htm”,则.htm文件也可以执行php程序了,你甚至还可以添加上一行“AddType application/x-httpd-php .txt”,让普通的文本文件格式也能运行php程序。

 

前面所说的目录默认索引文件也可以改一下,因为现在加了php,有些文件就直接存为.php了,我们也可以把“index.php”设为默认索引文件,优先顺序就自己排了,我的是放在第一位。编辑完成,保存,关闭。

 

现在,php的安装,与Apache的结合已经全部完成,用屏幕右下角的小图标重启Apache,你的Apache服务器就支持了php。

三、mysql的安装,与php、Apache相结合

打开下载的mysql安装文件mysql-4.1.14-win32.zip,双击解压缩,运行“setup.exe”,出现如下界面

 

mysql安装向导启动,按“Next”继续

 

选择安装类型,有“Typical(默认)”、“Complete(完全)”、“Custom(用户自定义)”三个选项,我们选择“Custom”,有更多的选项,也方便熟悉安装过程

 

在“Developer Components(开发者部分)”上左键单击,选择“This feature, and all subfeatures, will be installed on local hard drive.”,即“此部分,及下属子部分内容,全部安装在本地硬盘上”。在上面的“MySQL Server(mysql服务器)”、“Client Programs(mysql客户端程序)”、“Documentation(文档)”也如此操作,以保证安装所有文件。点选“Change...”,手动指定安装目录。

 

填上安装目录,我的是“D:\mysql”,也建议不要放在与操作系统同一分区,这样可以防止系统备份还原的时候,数据被清空。按“OK”继续。

 

返回刚才的界面,按“Next”继续。

 

确认一下先前的设置,如果有误,按“Back”返回重做。按“Install”开始安装。

 

正在安装中,请稍候,直到出现下面的界面

 

这里是询问你是否要注册一个mysql.com的账号,或是使用已有的账号登陆mysql.com,一般不需要了,点选“Skip Sign-Up”,按“Next”略过此步骤。

 

现在软件安装完成了,出现上面的界面,这里有一个很好的功能,mysql配置向导,不用向以前一样,自己手动乱七八糟的配置my.ini了,将 “Configure the Mysql Server now”前面的勾打上,点“Finish”结束软件的安装并启动mysql配置向导。

 

mysql配置向导启动界面,按“Next”继续。

 

选择配置方式,“Detailed Configuration(手动精确配置)”、“Standard Configuration(标准配置)”,我们选择“Detailed Configuration”,方便熟悉配置过程。

 

选择服务器类型,“Developer Machine(开发测试类,mysql占用很少资源)”、“Server Machine(服务器类型,mysql占用较多资源)”、“Dedicated MySQL Server Machine(专门的数据库服务器,mysql占用所有可用资源)”,大家根据自己的类型选择了,一般选“Server Machine”,不会太少,也不会占满。

 

选择mysql数据库的大致用途,“Multifunctional Database(通用多功能型,好)”、“Transactional Database Only(服务器类型,专注于事务处理,一般)”、“Non-Transactional Database Only(非事务处理型,较简单,主要做一些监控、记数用,对MyISAM数据类型的支持仅限于non-transactional),随自己的用途而选择了,我这里选择“Transactional Database Only”,按“Next”继续。

 

对InnoDB Tablespace进行配置,就是为InnoDB 数据库文件选择一个存储空间,如果修改了,要记住位置,重装的时候要选择一样的地方,否则可能会造成数据库损坏,当然,对数据库做个备份就没问题了,这里不详述。我这里没有修改,使用用默认位置,直接按“Next”继续

 

选择您的网站的一般mysql访问量,同时连接的数目,“Decision Support(DSS)/OLAP(20个左右)”、“Online Transaction Processing(OLTP)(500个左右)”、“Manual Setting(手动设置,自己输一个数)”,我这里选“Online Transaction Processing(OLTP)”,自己的服务器,应该够用了,按“Next”继续

 

是否启用TCP/IP连接,设定端口,如果不启用,就只能在自己的机器上访问mysql数据库了,我这里启用,把前面的勾打上,Port Number:3306,按“Next”继续

 

这个比较重要,就是对mysql默认数据库语言编码进行设置,第一个是西文编码,第二个是多字节的通用utf8编码,都不是我们通用的编码,这里选择第三个,然后在Character Set那里选择或填入“gbk”,当然也可以用“gb2312”,区别就是gbk的字库容量大,包括了gb2312的所有汉字,并且加上了繁体字、和其它乱七八糟的字——使用mysql的时候,在执行数据操作命令之前运行一次“SET NAMES GBK;”(运行一次就行了,GBK可以替换为其它值,视这里的设置而定),就可以正常的使用汉字(或其它文字)了,否则不能正常显示汉字。按 “Next”继续。

 

选择是否将mysql安装为windows服务,还可以指定Service Name(服务标识名称),是否将mysql的bin目录加入到Windows PATH(加入后,就可以直接使用bin下的文件,而不用指出目录名,比如连接,“mysql.exe -uusername -ppassword;”就可以了,不用指出mysql.exe的完整地址,很方便),我这里全部打上了勾,Service Name不变。按“Next”继续。

 

这一步询问是否要修改默认root用户(超级管理)的密码(默认为空),“New root password”如果要修改,就在此填入新密码(如果是重装,并且之前已经设置了密码,在这里更改密码可能会出错,请留空,并将“Modify Security Settings”前面的勾去掉,安装配置完成后另行修改密码),“Confirm(再输一遍)”内再填一次,防止输错。“Enable root access from remote machines(是否允许root用户在其它的机器上登陆,如果要安全,就不要勾上,如果要方便,就勾上它)”。最后“Create An Anonymous Account(新建一个匿名用户,匿名用户可以连接数据库,不能操作数据,包括查询)”,一般就不用勾了,设置完毕,按“Next”继续。

 

确认设置无误,如果有误,按“Back”返回检查。按“Execute”使设置生效。

 

设置完毕,按“Finish”结束mysql的安装与配置——这里有一个比较常见的错误,就是不能“Start service”,一般出现在以前有安装mysql的服务器上,解决的办法,先保证以前安装的mysql服务器彻底卸载掉了;不行的话,检查是否按上面一步所说,之前的密码是否有修改,照上面的操作;如果依然不行,将mysql安装目录下的data文件夹备份,然后删除,在安装完成后,将安装生成的 data文件夹删除,备份的data文件夹移回来,再重启mysql服务就可以了,这种情况下,可能需要将数据库检查一下,然后修复一次,防止数据出错。

与Apache及php相结合,前面已提过,这里再说一下,在php安装目录下,找到先前重命名并编辑过的 php.ini,如下图所示,Ln563,把“;extension=php_mysql.dll”前的“;”去掉,加载mysql模块。保存,关闭后,重启apache就可以了。这里也可以选择其它要加载的模块,去掉前面的“;”,就表示要加载此模块了,加载的越多,占用的资源也就多一点,不过也多不到哪去。所有的模块文件都放在php解压缩目录的“ext”之下,我这里的截图是把所有能加载的模块都加载上去了,前面的“;”没去掉的,是因为“ext” 目录下默认没有此模块,加载会提示找不到文件而出错。这里只是参考,一般不需要加载这么多,需要的加载上就可以了,编辑好后保存,关闭。

 

同样,加载了模块后,就要指明模块的位置,否则重启Apache的时候会提示“找不到指定模块”的错误,这里介绍一种最简单的方法,直接将 php安装路径、里面的ext路径指定到windows系统路径中——在“我的电脑”上右键,“属性”,选择“高级”标签,点选“环境变量”,在“系统变量”下找到“Path”变量,选择,双击或点击“编辑”,将“;D:\php;D:\php\ext”加到原有值的后面,当然,其中的“D:\php”是我的安装目录,你要将它改为自己的php安装目录,如下图所示,全部确定。系统路径添加好后要重启电脑才能生效,可以现在重启,也可以在所有软件安装或配置好后重启。

 
posted @ 2011-09-27 13:06 甜咖啡 阅读(175) | 评论 (0)编辑 收藏
系统主要是通过tomcat运行,将tomcat和jre打包后发送给客户使用,绿色的方式安装使用,由于客户也不搞开发,所以就仅仅是jre和tomcat和应用程序
我使用的jre6,免安装版版的tomcat6;目录结构是这样的

[我的应用名字]
  |-jre6
  |-tomcat6
  |-go_tomcat.bat

go_tomcat.bat文件内容

@ECHO OFF
set JRE_HOME=.\jre6
set PATH=%JRE_HOME%\bin;%PATH%
set TOMCAT_HOME=.\tomcat6
cd .\%TOMCAT_HOME%\bin
rem 启动tomcat服务
.\startup.bat
posted @ 2011-09-16 18:01 甜咖啡 阅读(1900) | 评论 (1)编辑 收藏
仅列出标题
共5页: 上一页 1 2 3 4 5 下一页 

导航

<2024年4月>
31123456
78910111213
14151617181920
21222324252627
2829301234
567891011

统计

常用链接

留言簿(1)

我参与的团队

随笔档案

搜索

最新评论

阅读排行榜

评论排行榜