2013年2月28日
下载的docker镜像默认存储路径是/var/lib/docker .具体的镜像文件就在containers文件夹中
docker save -o d:/docker/zen.tar easysoft/zentao:15.5
docker run -d -p 80:80 \
-e ADMINER_USER="admin" -e ADMINER_PASSWD="qqzj126" -e MYSQL_ROOT_PASSWORD=qqzj126 \
-e BIND_ADDRESS="false" \
-v /opt/data/zbox/:/opt/zbox/ \
-v /opt/mysqldata:/var/lib/mysql \
--name zentao-server \
easysoft/zentao:15.5
docker logs -f
运行命令(注意路径)
java -jar /web/share-book.jar > /web/log.txt &
该命令的意思是:执行share-book.jar这个文件,并且输出到log.txt文件,&表示后台运行
解决更新项目带来的频繁重启操作,创建2个脚本
start.sh
#! /bin/bash
#注意:必须有&让其后台执行,否则没有pid生成 jar包路径为绝对路径
java -jar /web/share-book.jar > /web/log.txt &
# 将jar包启动对应的pid写入文件中,为停止时提供pid
echo $! > /web/pid.txt
stop.sh
#! /bin/bash
PID=$(cat /web/pid.txt)
kill -9 $PID
启动项目:./start.sh
停止项目:./stop.sh
一.问题描述:windows本地调试Hadoop程序时报错错误信息:
其原因是需要在windows本地搭建Hadoop环境,下载winutils文件,并将hadoop-2.8.4包内的bin文件替换,将下载文件中hadoop.dll放到C:\Windows\System32下
二.解决过程如下:
1.下载hadoop,去官网下载对应的hadoop版本,我在linux集群搭建的是hadoop-2.8.4,因此将hadoop-2.8.4下载到windows本地
https://www.jianshu.com/p/a65a95108620
如果不配置.gitignore的文件,带push代码的时候就会把一写不必要的文件push到远程仓库,如.idea文件。如果不小心出现此文件在远程仓库可以通过一下步骤delete此文件:
1.配置.gitignore文件(新建/编辑)
echo '.idea' >> .gitignore
2.将.gitignore文件上传到远程仓库
git pull git add .gitignore git commit -m 'edit .gitignore' git push origin master
3.删除git的.idea文件
git rm --cached -r .idea
4.同步到远程仓库
git commit -m 'delete .idea' git push origin master
完成之后就可以发现git仓库中的.idea文件已经被删除,而且之后push代码也不会再把.idea文件上传。
PS:我在使用PyCharm编写python代码,一般是通过new -> .ignore file -> .gitignore file
自动生成.gitignore文件。
下面是我自己比较常用的.gitignore文件简短配置:
.project .settings/ .prefs .pydevproject .idea/ .idea .DS_Store .cache *.pyc *.html *.xlm
1、java heap space 一次申请太大的内存空间
2、GC overhead limit exceeded 创建太多的对象,gc收集不完
1、 vim /etc/rc.d/rc.local
2、添加内容
export JAVA_HOME=/usr/java/jdk1.8.0_111
/app/tomcat/bin/startup.sh start
3、
chmod 777 /etc/rc.d/rc.local
/**
* synchronized 放在普通方法上,内置锁就是当前类的实例
* @return
*/
public synchronized int getNext() {
return value ++;
}
/**
* 修饰静态方法,内置锁是当前的Class字节码对象
* Sequence.class
* @return
*/
public static synchronized int getPrevious() {
// return value --;
return 0;
}
1、数据库配置
首先使用canal需要修改数据库配置
[mysqld]
log-bin=mysql-bin # 开启
binlog binlog-format=ROW # 选择 ROW 模式
server_id=1 # 配置 MySQL replaction 需要定义,不要和 canal 的 slaveId 重复
创建canal数据库用户
CREATE USER canal IDENTIFIED BY 'canal';
GRANT SELECT, REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO 'canal'@'%';
FLUSH PRIVILEGES;
2、安装canal
下载:https://github.com/alibaba/canal/releases
解压(修改版本号):tar zxvf canal.deployer-1.1.4.tar.gz -C ./canal
配置开放服务器端口:11110、11111、11112
修改canal配置文件(这里设置了两个instance,即两个数据库):
vi canal/conf/canal.properties
canal.destinations = example1,example2
配置instance:
cp -R canal/conf/example conf/example1
mv conf/example conf/example2
第一个数据库配置
vi canal/conf/example1/instance.properties
canal.instance.master.address=32.1.2.140:3306
第二个数据库配置
vi canal/conf/example2/instance.properties
canal.instance.master.address=32.1.2.140:3307
#如果需要新增一个instance,只需要修改canal.properties文件,并新增一个instance配置即可,无需重启canal。
运行:
sh canal/bin/startup.sh # 查看日志
cat canal/logs/canal/canal
3、Java使用样例
引入pom依赖,需要与安装的canal版本一致
<dependencies> <dependency> <groupId>com.alibaba.otter</groupId> <artifactId>canal.client</artifactId> <version>1.1.4</version> </dependency> </dependencies>
示例代码(异步打印两个数据库的修改内容):

package cn.spicybar.dblog; import com.alibaba.otter.canal.client.CanalConnector; import com.alibaba.otter.canal.client.CanalConnectors; import com.alibaba.otter.canal.protocol.CanalEntry.Entry; import com.alibaba.otter.canal.protocol.CanalEntry.EntryType; import com.alibaba.otter.canal.protocol.CanalEntry.RowChange; import com.alibaba.otter.canal.protocol.Message; import java.net.InetSocketAddress; import java.util.List; public class CanalClient { public static void main(String[] args) { new Thread(() -> initConnector("example1")).start(); new Thread(() -> initConnector("example2")).start(); } private static void initConnector(String destination) { CanalConnector connector = CanalConnectors.newSingleConnector(new InetSocketAddress("32.1.0.237", 11111), destination, "", ""); try { connector.connect(); connector.subscribe(".*\\..*"); connector.rollback(); while (true) { Message message = connector.getWithoutAck(1000); if (message.getId() != -1 && message.getEntries().size() > 0) { printEntry(message.getEntries()); } connector.ack(message.getId()); } } finally { connector.disconnect(); } } private static void printEntry(List<Entry> entries) { for (Entry entry : entries) { if (entry.getEntryType() == EntryType.TRANSACTIONBEGIN || entry.getEntryType() == EntryType.TRANSACTIONEND) { continue; } try { RowChange rowChange = RowChange.parseFrom(entry.getStoreValue()); System.out.println(rowChange.getSql()); } catch (Exception e) { throw new RuntimeException("ERROR ## parser error, data:" + entry.toString(), e); } } }
public int binarySearch(long value) {
int middle = 0;
int low = 0;
int pow = arr.length;
while(true) {
middle = (pow + low) / 2;
if(arr[middle] == value) {
return middle;
} else if(low > pow) {
return -1;
} else {
if(arr[middle] > value) {
pow = middle - 1;
} else {
low = middle + 1;
}
}
}
}
1.首先先把下载的压缩包解压到一个文件夹中
2.打开cmd指令窗口3.输入你刚才解压的文件路径4.然后输入redis-server redis.windows.conf 命令
接下来部署Redis为windows下的服务 首先关掉上一个窗口再打开一个新的cmd命令窗口
然后输入指令redis-server --service-install redis.windows.conf
随后,进入右击此电脑–管理–服务和应用程序–服务 启动服务
Redis常用的指令
卸载服务:redis-server --service-uninstall
开启服务:redis-server --service-start
停止服务:redis-server --service-stop
测试redis,通过cd到我们解压的目录,输入指令通过Set get指令查看是否成功
检查配置文件/canal.deployer-1.1.1/conf/canal.properties
canal.instance.tsdb.spring.xml=classpath:spring/tsdb/h2-tsdb.xml
以及
# table meta tsdb info
canal.instance.tsdb.enable=true
canal.instance.tsdb.dir=${canal.file.data.dir:../conf}/${canal.instance.destination:}
canal.instance.tsdb.url=jdbc:h2:${canal.instance.tsdb.dir}/h2;CACHE_SIZE=1000;MODE=MYSQL;
canal.instance.tsdb.dbUsername=canal
canal.instance.tsdb.dbPassword=canal
检查 tsdb是否已经开启
如果都已开启还是有这个问题 则需要清除canal对表结构的缓存
conf/example/h2.mv.db
问题2:找不到binlog日志文件
清空缓存
canal.deployer-1.1.1/conf/example/meta.dat
常规的windows操作
- 根目录下创建gitignore.txt;
- 编辑gitignore.txt,写下你的规则,例如加上node_modules/;
- 打开命令行窗口,切换到根目录(可以直接在文件夹上面的地址栏输入cmd回车);
- 执行命令ren gitignore.txt .gitignore。
在.gitignore中已经声明了忽略路径也是不起作用的,
这时候我们就应该先把本地缓存删除,然后再进行git的提交,这样就不会出现忽略的文件了。
解决方法: git清除本地缓存(改变成未track状态),然后再提交:
[root@kevin ~]
# git rm -r --cached .
[root@kevin ~]
# git add .
[root@kevin ~]
# git commit -m 'update .gitignore'
[root@kevin ~]
# git push -u origin master
安装k8s
systemctl disable firewalld
systemctl stop firewalld
yum update
yum install -y etcd kubernetes
vim /etc/kubernetes/apiserver
KUBE_ADMISSION_CONTROL改为下面的值
KUBE_ADMISSION_CONTROL="--admission-control=NamespaceLifecycle,NamespaceExists,LimitRange
vi /etc/kubernetes/manifests/kube-apiserver.yaml
--service-node-port-range: 1-65535
systemctl start etcd
systemctl start docker
如果启动docker 失败,修改 /etc/sysconfig/selinux
把 selinux后面改成 disabled , 重启机器,reboot -n 再启动docker就好了
systemctl start kube-apiserver
systemctl start kube-controller-manager
systemctl start kube-scheduler
systemctl start kubelet
systemctl start kube-proxy
kubectl create -f mytomcat-rc.yaml
clean package docker:build -DpushImage
1.使用DockerMaven,可以实现我们项目一键式部署,简便操作流程。
Maven插件自动部署步骤:
a.首先我们要设置docker的宿主机开启权限.
修改宿主机的docker配置,让其可以远程访问 vi /lib/systemd/system/docker.service
其中ExecStart=后添加配置 -H tcp://0.0.0.0:2375 -H unix:///var/run/docker.sock
b.刷新配置,重启服务
systemctl daemon-reload
systemctl restart docker
docker start registry
c.在工程pom.xml 增加配置
<build>
<finalName>app</finalName>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<!-- docker的maven插件,官网:https://github.com/spotify/docker-maven-plugin
-->
<plugin>
<groupId>com.spotify</groupId>
<artifactId>docker-maven-plugin</artifactId>
<version>0.4.13</version>
<configuration>
<imageName>192.168.184.141:5000/${project.artifactId}:${project.version}
</imageName>
<baseImage>jdk1.8</baseImage>
<entryPoint>["java", "-jar", "/${project.build.finalName}.jar"]
</entryPoint>
<resources>
<resource>
<targetPath>/</targetPath>
<directory>${project.build.directory}</directory>
<include>${project.build.finalName}.jar</include>
</resource>
</resources>
<dockerHost>http://192.168.184.141:2375</dockerHost>
</configuration>
</plugin>
</plugins>
</build>
create table SAP_E_DSOQQZT_TMP
(
id NUMBER not null,
request NUMBER,
)
tablespace USERS
pctfree 10
initrans 1
maxtrans 255
storage
(
initial 16K
next 8K
minextents 1
maxextents unlimited
)
partition by range(request) interval(1000000)
(
partition SAP_E_DSOQQZT_part values less than(700000000)
);
-- Add comments to the columns
comment on column SAP_E_DSOQQZT_TMP.id
is 'ID';
comment on column SAP_E_DSOQQZT_TMP.request
is '请求号';
-- Create/Recreate indexes
create index FCREATETIMEA on SAP_E_DSOQQZT_TMP ( REQUEST)
tablespace ZHFXBEMS
pctfree 10
initrans 2
maxtrans 255
storage
(
initial 1847M
next 1M
minextents 1
maxextents unlimited
);
-- Create/Recreate primary, unique and foreign key constraints
alter table SAP_E_DSOQQZT_TMP
add constraint PK_SAP_E_DSOQQZTA primary key (ID)
using index
tablespace USERS
pctfree 10
initrans 2
maxtrans 255
storage
(
initial 112M
next 1M
minextents 1
maxextents unlimited
);
第二步:判断表是否可以在线从新定义
begin
dbms_redefinition.can_redef_table('ERPSU','SAP_E_DSOQQZT',DBMS_REDEFINITION.CONS_USE_PK);
end;
第三步:开始执行数据的迁移(30分钟)
begin
DBMS_REDEFINITION.START_REDEF_TABLE('ERPSU','SAP_E_DSOQQZT', 'SAP_E_DSOQQZT_TMP');
end;
第四步:进行权限对象的迁移
DECLARE
num_errors PLS_INTEGER;
BEGIN
DBMS_REDEFINITION.COPY_TABLE_DEPENDENTS('ERPSU','SAP_E_DSOQQZT', 'SAP_E_DSOQQZT_TMP',
DBMS_REDEFINITION.CONS_ORIG_PARAMS, TRUE, TRUE, TRUE, TRUE, num_errors);
END;
第五步:结束整个重定义
BEGIN
DBMS_REDEFINITION.FINISH_REDEF_TABLE('ERPSU','SAP_E_DSOQQZT', 'SAP_E_DSOQQZT_TMP');
END;
第六步,删除临时表 SAP_E_DSOQQZT_TMP
万一哪一步出错,执行:
BEGIN
DBMS_REDEFINITION.ABORT_REDEF_TABLE(uname => 'ERPSU',
orig_table => 'SAP_E_DSOQQZT',
int_table => 'SAP_E_DSOQQZT_TMP'
);
END;
-----------------------------------------------------------------------------
删除所有的docker镜像
docker rmi `docker images -q` (`符号是esc下面的按键)
交互式方式创建容器
docker run -it --name=容器名称 镜像名称:标签 /bin/bash
进入守护式的容器
docker exec -it 容器名称 /bin/bash
-i 表示运行容器
-t 表示容器启动后进入容器命令行,容器创建后可以登录进去
--name 给容器命名
-v 表示目录映射关系(前者是宿主机目录,后者是容器目录),可以用多个-v做多个目录或者文件映射,最好做目录映射,在宿主机上做修改,然后共享到容器上。
-d 创建一个守护容器在后台运行,如果只加-i-t,创建后会自动进去容器。
-p 表示端口映射,前者是宿主机端口,后者是容器内的端口,可以多个端口映射
docker stop 容器id (停止容器)
docker start 容器id (停止容器)
向容器内复制文件
docker cp 需要复制的文件目录 容器:容器内的目录
从容器内复制文件
docker cp 容器:容器内的目录 需要复制的文件目录
1、yum包更新到最新
sudo yum update
2 、安装需要的软件包
sudo yum install -y yum-utils device-mapper-persistent-data lvm2
3、设置yum源为阿里云
sudo yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
4、 安装docker
sudo yum install docker-ce
5、查看版本
docker -v
6、修改镜像下载源
vi /etc/docker/daemon.json
写入:
{
"registry-mirrors": ["http://docker.mirrors.ustc.edu.cn"]
}
7、启动docker
systemctl start docker
8、docker 开机自动启动
systemctl enable docker
编写完Dockerfile,执行构建命令
docker build -t 192.168.1.9:5000/admin-service .
docker run -p 8888:8888 192.168.1.9:5000/admin-service
1、在分布上系统环境下,一个方法在同一时间只能被一个机器上的一个线程访问
2、高可用的获取锁和释放锁
3、高效的获取锁和释放锁
4、具备可重入特性(重新进入,由多个任务并发使用,不比担心数据错误)
5、具备锁的失效机制,防止死锁
6、具备非阻塞锁的特性,没有获取到锁,直接返回获取锁失败
1。新建/usr/local/docker/registry 文件夹
2、在registry中新建docker-compose.yml文件,编辑此文件
version: '3.1'
services:
registry:
image: registry:2.7.1
restart: always
container_name: registry
ports:
- 5000:5000
volumes:
- /usr/local/docker/registry/data:/var/lib/registry
frontend:
image: konradkleine/docker-registry-frontend:v2
ports:
- 8080:80
volumes:
- ./certs/frontend.crt:/etc/apache2/server.crt:ro
- ./certs/frontend.key:/etc/apache2/server.key:ro
environment:
- ENV_DOCKER_REGISTRY_HOST=192.168.1.8
- ENV_DOCKER_REGISTRY_PORT=50003.运行 docker-compose up4.上传镜像docker tag tomcat 192.168.1.8:5000/tomcat:8.1
docker push 192.168.1.8:5000/tomcat:8.1
version: '3.1' services: mysql: restart: always image: mysql:5.7.22 container_name: mysql ports: - 3306:3306 environment: TZ: Asia/Shanghai MYSQL_ROOT_PASSWORD: 123456 command: --character-set-server=utf8mb4 --collation-server=utf8mb4_general_ci --explicit_defaults_for_timestamp=true --lower_case_table_names=1 --max_allowed_packet=128M --sql-mode="STRICT_TRANS_TABLES,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION,NO_ZERO_DATE,NO_ZERO_IN_DATE,ERROR_FOR_DIVISION_BY_ZERO" volumes: - mysql-data:/var/lib/mysql volumes: mysql-data:
version: '3.1' services: db: image: mysql restart: always environment: MYSQL_ROOT_PASSWORD: 123456 command: --default-authentication-plugin=mysql_native_password --character-set-server=utf8mb4 --collation-server=utf8mb4_general_ci --explicit_defaults_for_timestamp=true --lower_case_table_names=1 ports: - 3306:3306 volumes: - ./data:/var/lib/mysql adminer: image: adminer restart: always ports: - 8080:8080
批量安装依赖包:rpm -Uvh *.rpm --nodeps --force
安装 container-selinux-2.9-4.el7.noarch.rpm
: rpm -Uvh container-selinux-2.9-4.el7.noarch.rpm
pasting
安装 docker
:rpm -Uvh docker-ce-18.03.1.ce-1.el7.centos.x86_64.rpm
pasting
- 启动docker:
systemctl start docker
- 查看
docker
启动容器列表: docker ps
select d.file_name,d.tablespace_name,d.autoextensible from dba_temp_files d;
select d.file_name,d.tablespace_name,d.autoextensible from DBA_DATA_FILES d;
drop tablespace tablespace_name including contents and datafiles;
ALTER TABLESPACE users ADD DATAFILE
'/app/oradata/orclnew/orclnew/users02.dbf'
size 7167M autoextend on ;
SELECT sid, serial#, username, osuser FROM v$session where sid in (select session_id from v$locked_object);
删除连接的session
ALTER SYSTEM KILL SESSION '9,4335';
导出oracle数据
exp xxx/xxx@orclnew file=/app/backup.dmp owner=xxx rows=n
当导出报错信息是 EXP-00091: Exporting questionable statistics时,执行下面的语句
select userenv('language') from dual;
export NLS_LANG=AMERICAN_AMERICA.ZHS16GBK
1、使用反编译工具找到需要修改的class文件,保存成Java文件。
2、新建Java项目,导入所有需要的jar,在src中放入需要修改的Java文件。
3、修改完毕后,在bin中找到新生成的class文件,解压原来的jar,替换class文件。
4.有三种方式重新打包,a 把解压替换过的jar文件导入到eclipse中,导出jar
b 使用zip压缩格式,修改后缀名jar
c 进入文件目录,使用
执行jar -cvf aa.jar
public interface Data {
String getResult();
}
public class FutureData implements Data{
protected Data data=null;
protected boolean f=false;
public synchronized void setData(Data data) {
if(f) {
return;
}
f=true;
this.data=data;
notifyAll();
}
@Override
public synchronized String getResult() {
while (!f) {
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
return data.getResult();
}
}
public class RealData implements Data{
protected String s;
public RealData(String name) {
StringBuffer sb=new StringBuffer("");
for (int i = 0; i < 10; i++) {
sb.append(name);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
s=sb.toString();
}
@Override
public String getResult() {
// TODO Auto-generated method stub
return s;
}
}
public class Client {
public Data request(final String ss) {
final FutureData f=new FutureData();
new Thread() {
public void run() {
RealData r=new RealData(ss);//模拟复杂的数据封装和处理
f.setData(r);
};
}.start();
return f;
}
public static void main(String[] args) {
Client client=new Client();
Data d = client.request("123");
System.out.println(d.getResult());
}
}
public class FutureTest {
public static void main(String[] args) throws InterruptedException, ExecutionException {
ExecutorService e=Executors.newFixedThreadPool(11);
FutureTask<String> f=new FutureTask<>(new Callable<String>() {
@Override
public String call() throws Exception {
Thread.sleep(5000);
return "aa";
}
});
e.submit(f);
System.out.println(f.get());
}
}
vi clean.sh
logs_path="/appqqq/tomcat/logs"
find $logs_path -mtime +3 -name "localhost.*.log" -exec rm -rf {} \;
find $logs_path -mtime +3 -name "localhost_access_log.*.txt" -exec rm -rf {} \;
find $logs_path -mtime +3 -name "catalina.*.log" -exec rm -rf {} \;
find $logs_path -mtime +3 -name "manager.*.log" -exec rm -rf {} \;
find $logs_path -mtime +3 -name "host-manager.*.log" -exec rm -rf {} \;
find $logs_path -mtime +3 -name "fileservice.log.*" -exec rm -rf {} \;
>$logs_path/catalina.out;
chmod 777 clean.sh
crontab -e
0 2 * * * sh /appqqq/tomcat/logs/clean.sh
课程大纲
1、document数据格式
2、电商网站商品管理案例:背景介绍
3、简单的集群管理
4、商品的CRUD操作(document CRUD操作)
----------------------------------------------------------------------------------------------------------------------------
1、document数据格式
面向文档的搜索分析引擎
(1)应用系统的数据结构都是面向对象的,复杂的
(2)对象数据存储到数据库中,只能拆解开来,变为扁平的多张表,每次查询的时候还得还原回对象格式,相当麻烦
(3)ES是面向文档的,文档中存储的数据结构,与面向对象的数据结构是一样的,基于这种文档数据结构,es可以提供复杂的索引,全文检索,分析聚合等功能
(4)es的document用json数据格式来表达
2、电商网站商品管理案例背景介绍
有一个电商网站,需要为其基于ES构建一个后台系统,提供以下功能:
(1)对商品信息进行CRUD(增删改查)操作
(2)执行简单的结构化查询
(3)可以执行简单的全文检索,以及复杂的phrase(短语)检索
(4)对于全文检索的结果,可以进行高亮显示
(5)对数据进行简单的聚合分析
----------------------------------------------------------------------------------------------------------------------------
3、简单的集群管理
(1)快速检查集群的健康状况
es提供了一套api,叫做cat api,可以查看es中各种各样的数据
GET /_cat/health?v
epoch timestamp cluster status node.total node.data shards pri relo init unassign pending_tasks max_task_wait_time active_shards_percent
1488006741 15:12:21 elasticsearch yellow 1 1 1 1 0 0 1 0 - 50.0%
epoch timestamp cluster status node.total node.data shards pri relo init unassign pending_tasks max_task_wait_time active_shards_percent
1488007113 15:18:33 elasticsearch green 2 2 2 1 0 0 0 0 - 100.0%
epoch timestamp cluster status node.total node.data shards pri relo init unassign pending_tasks max_task_wait_time active_shards_percent
1488007216 15:20:16 elasticsearch yellow 1 1 1 1 0 0 1 0 - 50.0%
如何快速了解集群的健康状况?green、yellow、red?
green:每个索引的primary shard和replica shard都是active状态的
yellow:每个索引的primary shard都是active状态的,但是部分replica shard不是active状态,处于不可用的状态
red:不是所有索引的primary shard都是active状态的,部分索引有数据丢失了
为什么现在会处于一个yellow状态?
我们现在就一个笔记本电脑,就启动了一个es进程,相当于就只有一个node。现在es中有一个index,就是kibana自己内置建立的index。由于默认的配置是给每个index分配5个primary shard和5个replica shard,而且primary shard和replica shard不能在同一台机器上(为了容错)。现在kibana自己建立的index是1个primary shard和1个replica shard。当前就一个node,所以只有1个primary shard被分配了和启动了,但是一个replica shard没有第二台机器去启动。
做一个小实验:此时只要启动第二个es进程,就会在es集群中有2个node,然后那1个replica shard就会自动分配过去,然后cluster status就会变成green状态。
(2)快速查看集群中有哪些索引
GET /_cat/indices?v
health status index uuid pri rep docs.count docs.deleted store.size pri.store.size
yellow open .kibana rUm9n9wMRQCCrRDEhqneBg 1 1 1 0 3.1kb 3.1kb
(3)简单的索引操作
创建索引:PUT /test_index?pretty
health status index uuid pri rep docs.count docs.deleted store.size pri.store.size
yellow open test_index XmS9DTAtSkSZSwWhhGEKkQ 5 1 0 0 650b 650b
yellow open .kibana rUm9n9wMRQCCrRDEhqneBg 1 1 1 0 3.1kb 3.1kb
删除索引:DELETE /test_index?pretty
health status index uuid pri rep docs.count docs.deleted store.size pri.store.size
yellow open .kibana rUm9n9wMRQCCrRDEhqneBg 1 1 1 0 3.1kb 3.1kb
----------------------------------------------------------------------------------------------------------------------------
4、商品的CRUD操作
(1)新增商品:新增文档,建立索引
PUT /index/type/id
{
"json数据"
}
PUT /ecommerce/product/1
{
"name" : "gaolujie yagao",
"desc" : "gaoxiao meibai",
"price" : 30,
"producer" : "gaolujie producer",
"tags": [ "meibai", "fangzhu" ]
}
{
"_index": "ecommerce",
"_type": "product",
"_id": "1",
"_version": 1,
"result": "created",
"_shards": {
"total": 2,
"successful": 1,
"failed": 0
},
"created": true
}
PUT /ecommerce/product/2
{
"name" : "jiajieshi yagao",
"desc" : "youxiao fangzhu",
"price" : 25,
"producer" : "jiajieshi producer",
"tags": [ "fangzhu" ]
}
PUT /ecommerce/product/3
{
"name" : "zhonghua yagao",
"desc" : "caoben zhiwu",
"price" : 40,
"producer" : "zhonghua producer",
"tags": [ "qingxin" ]
}
es会自动建立index和type,不需要提前创建,而且es默认会对document每个field都建立倒排索引,让其可以被搜索
(2)查询商品:检索文档
GET /index/type/id
GET /ecommerce/product/1
{
"_index": "ecommerce",
"_type": "product",
"_id": "1",
"_version": 1,
"found": true,
"_source": {
"name": "gaolujie yagao",
"desc": "gaoxiao meibai",
"price": 30,
"producer": "gaolujie producer",
"tags": [
"meibai",
"fangzhu"
]
}
}
(3)修改商品:替换文档
PUT /ecommerce/product/1
{
"name" : "jiaqiangban gaolujie yagao",
"desc" : "gaoxiao meibai",
"price" : 30,
"producer" : "gaolujie producer",
"tags": [ "meibai", "fangzhu" ]
}
{
"_index": "ecommerce",
"_type": "product",
"_id": "1",
"_version": 1,
"result": "created",
"_shards": {
"total": 2,
"successful": 1,
"failed": 0
},
"created": true
}
{
"_index": "ecommerce",
"_type": "product",
"_id": "1",
"_version": 2,
"result": "updated",
"_shards": {
"total": 2,
"successful": 1,
"failed": 0
},
"created": false
}
PUT /ecommerce/product/1
{
"name" : "jiaqiangban gaolujie yagao"
}
替换方式有一个不好,即使必须带上所有的field,才能去进行信息的修改
(4)修改商品:更新文档
POST /ecommerce/product/1/_update
{
"doc": {
"name": "jiaqiangban gaolujie yagao"
}
}
{
"_index": "ecommerce",
"_type": "product",
"_id": "1",
"_version": 8,
"result": "updated",
"_shards": {
"total": 2,
"successful": 1,
"failed": 0
}
}
我的风格,其实有选择的情况下,不太喜欢念ppt,或者照着文档做,或者直接粘贴写好的代码,尽量是纯手敲代码
(5)删除商品:删除文档
DELETE /ecommerce/product/1
{
"found": true,
"_index": "ecommerce",
"_type": "product",
"_id": "1",
"_version": 9,
"result": "deleted",
"_shards": {
"total": 2,
"successful": 1,
"failed": 0
}
}
{
"_index": "ecommerce",
"_type": "product",
"_id": "1",
"found": false
}
where (select count(*) from student where class=a.class and a.score<score)<3
order by a.class,a.score desc;
git config --global http.sslVerify false
public class Test {
//不能正确调换值
public static void swap(Integer a,Integer b){
Integer t=a;
a=b;
b=t;
System.out.println("a="+a);
System.out.println("b="+b);
}
public static void main(String[] args) {
Integer a=1;
Integer b=2;
System.out.println("a="+a);
System.out.println("b="+b);
System.out.println("----------");
swap(a, b);
System.out.println("----------");
System.out.println("a="+a);
System.out.println("b="+b);
}
}
在内存中,真实的值放在heap中,变量a,b放在栈中,a,b保存的是值在heap中的地址,当调用swap方法时,形参也是保存在栈中,是新的变量,指向heap中真的值,并没有修改原先a,b的指向,所以无法交换值。
matches方法返回true,装配bean,返回false,不装配bean,在需要可能装配的bean的方法和类上加上注解@Conditional(XXXCondition.class)
@Component
public class AllBeanPostProcessor implements BeanPostProcessor{
//对象属性设置方法完成后,init方法执行前执行
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
System.out.println("BeforeInit="+beanName);
return bean;
}
//init方法执行后执行
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
System.out.println("AfterInit="+beanName);
return bean;
}
}
@Component
public class MyBeanFactoryPostProcessor2 implements BeanDefinitionRegistryPostProcessor{
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
// TODO Auto-generated method stub
}
//可以动态把对象注入spring对象
@Override
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
for (int i = 0; i < 10; i++) {
BeanDefinitionBuilder b=BeanDefinitionBuilder.rootBeanDefinition(User.class);
b.addPropertyValue("name", "admin"+i);
registry.registerBeanDefinition("user"+i, b.getBeanDefinition());
}
}
}
关键字
package test;
public class TestThread extends Thread{
private volatile boolean stop=false;
@Override
public void run() {
int i=0;
while(!stop){
i++;
}
System.out.println("完成="+i);
}
public void setStop(){
stop=true;
}
public boolean getStop(){
return stop;
}
}
volatile关键字只能保证多个线程间的可见性,但是不具备同步性,可以算得上是轻量级的
synchronized,性能要比synchronized高,不会造成阻塞。一般volatile用于多个线程之间的可见的变量操作,并不能代替synchronized的同步功能。
例如:9点的时候,客户A发起select语句,大概需要执行10分钟,返回结果100,在9点5分的时候,客户B发起一条update语句,把100更新为200.当10分钟后,客户A得到的结果还是100或者返回异常snapshot too old。因为oracle数据库有数据一致性的保证,客户9点查询时,数据库会把数据复制到undo的副本,给客户返回的就是这个副本,如果同时多个客户端进行update操作,可能导致副本找不到,但是无论如何,不会返回修改过的数值。
在一个对象中的多个方法上都加上synchronized,代表同时执行这些方法时,是同步的,同步锁是属于对象的不是单个方法的。
package test;
public class Test6 {
public synchronized void get1(String s){
System.out.println(s);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public synchronized void get2(String s){
try {
Thread.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(s);
}
public static void main(String[] args) {
final Test6 t =new Test6();
new Thread(new Runnable() {
@Override
public void run() {
t.get1("a");
}
}).start();
new Thread(new Runnable() {
@Override
public void run() {
t.get2("b");
}
}).start();
}
}
多个线程访问同多个对象,同步方法加static,表示此方法属于类,所有此对象的此方法执行需要同步
package test;
public class Test5 {
public static synchronized void get(String s){
if("a".equals(s)){
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println(s);
}
public static void main(String[] args) {
final Test5 t =new Test5();
final Test5 t1 =new Test5();
new Thread(new Runnable() {
@Override
public void run() {
t.get("a");
}
}).start();
new Thread(new Runnable() {
@Override
public void run() {
t1.get("b");
}
}).start();
}
}
多个线程使用一把锁,多个线程访问同一个对象的方法或者属性。
package test;
public class Test4 {
public synchronized void get(String s){
if("c".equals(s)){
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println(s);
}
public static void main(String[] args) {
final Test4 t =new Test4();
new Thread(new Runnable() {
@Override
public void run() {
t.get("a");
}
}).start();
new Thread(new Runnable() {
@Override
public void run() {
t.get("b");
}
}).start();
new Thread(new Runnable() {
@Override
public void run() {
t.get("c");
}
}).start();
new Thread(new Runnable() {
@Override
public void run() {
t.get("d");
}
}).start();
}
}
1、安装cmake (可能需要安装 yum install gcc-c++)
2、安装yum install ncurses-devel -y
3.创建用户和组 groupadd mysql
useradd mysql -s /sbin/nologin -M -g mysql
4、tar xf mysql-5.5.32.tar.gz
5、进入MySQL目录,(可能需要 yum install bison)执行
cmake . -DCMAKE_INSTALL_PREFIX=/usr/local/mysql -DMYSQL_DATADIR=/usr/local/mysql/data -DMYSQL_UNIX_ADDR=/tmp/mysql.sock -DDEFAULT_CHARSET=utf8 -DDEFAULT_COLLATION=utf8_general_ci -DEXTRA_CHARSETS=all -DENABLED_LOCAL_INFILE=ON -DWITH_INNOBASE_STORAGE_ENGINE=1 -DWITH_BLACKHOLE_STORAGE_ENGINE=1 -DWITHOUT_EXAMPLE_STORAGE_ENGINE=1 -DWITHOUT_PARTITION_STORAGE_ENGINE=1 -DWITH_FAST_MUTEXES=1 -DWITH_ZLIB=bundled -DENABLED_LOCAL_INFILE=1 -DWITH_READLINE=1 -DWITH_EMBEDDED_SERVER=1 -DWITH_DEBUG=0 -DMYSQL_TCP_PORT=3306
6、make && make install
7、cp mysql-5.5.32/support-files/my-small.cnf /etc/my.cnf
8、添加环境变量 export PATH=/usr/local/mysql/bin:$PATH
9、授权 chown -R mysql.mysql /usr/local/mysql/data/
10、chmod -R 1777 /tmp/
11、在MySQL的安装目录下的scripts文件夹下,执行./mysql_install_db --basedir=/usr/local/mysql/ --datadir=/usr/local/mysql/data/ --user=mysql
12、负责MySQL启动命令 cp support-files/mysql.server /etc/init.d/mysqld
13、授权chmod +x /etc/init.d/mysqld
14、启动MySQL /etc/init.d/mysqld start
15、查看运行的进程 netstat -lntup|grep 3306
16、删除无用的用户和host,select user,host from mysql.user ;
删除test数据库
17、删除root用户,添加别的数据库管理员
delete from mysql.user;
grant all privileges on *.* to system@'localhost' identified by 'yjw' with grant option;
/usr/local/mysql//bin/mysqladmin -u root password 'new-password' --设置密码
/usr/local/mysql//bin/mysqladmin -u root -h bogon password 'root' --修改密码
linux下GTK+的一键安装和配置:(fedora16和centos下配置成功)
必要组件:
yum install gtk2 gtk2-devel gtk2-devel-docs
可选组件:
yum install gnome-devel gnome-devel-docs
A Java Runtime Environment (JRE) or Java Development Kit (JDK)
must be available in order to run Eclipse. No Java virtual machine
was found after searching the following locations:
/home/injavawetrust/program/eclipse/jre/bin/java
java in your current PATH
解决办法是在终端进入你的eclipse目录,然后输入:
mkdir jre
cd jre
ln -s 你的JDK目录/bin bin
方法一:
如果你是用命令行提交的,可以用以下命令设置临时环境变量GIT_SSL_NO_VERIFY。
Windows下:
set GIT_SSL_NO_VERIFY=true git push
Linux下:
env GIT_SSL_NO_VERIFY=true git push
设置好之后,然后用Git提交。
当然,你也可以把GIT_SSL_NO_VERIFY设置成非临时环境变量,这样就不用每次提交都要执行上面的命令了。
方法二:
你也可以在命令行执行以下命令,之后再提交。
git config --global http.sslVerify false
以上两个方法,亲测有效,建议第二个,直接去掉git的ssl验证
1、不在启动类同级的包目录中新建ribbon配置类
@Configuration
public class TestConfiguration {
@Autowired
IClientConfig config;
@Bean
public IRule ribbonRule(IClientConfig config) {
return new RandomRule();
}
}
在启动类中添加注解@RibbonClient
@SpringBootApplication
@EnableEurekaClient //针对Eureka服务注册使用
//@EnableDiscoveryClient //可以对其他服务注册软件使用
@RibbonClient(name="a-microservice-provider-user",configuration=TestConfiguration.class)
public class ConsumerMovieRibbonApplication {
@Bean
@LoadBalanced//客户端负载均衡,先把服务提供这所有的节点读取到ribbon注册表中,默认轮询请求服务
public RestTemplate getRestTemplate() {
return new RestTemplate();
}
public static void main(String[] args) {
SpringApplication.run(ConsumerMovieRibbonApplication.class, args);
}
}
3.在controller中添加方法
@GetMapping("/movie/{userid}")
public TUser test2(@PathVariable(name="userid") String userId) {
//服务的自动发现,不用配置死的IP和端口,只有在RestTemplate添加了@LoadBalanced接口,才能使用应用名称访问
return restTemplate.getForObject("http://a-microservice-provider-user/users/"+userId, TUser.class);
}
4、启动服务发现服务eureka和服务提供类,调用目标方法,可以成功 调用。
一、服务端的搭建
1、在pom文件中添加eureka服务依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka-server</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
2、编写application.yml 配置
security:
basic:
enabled: true
user:
name: user
password: password123
server:
port: 8761
eureka:
client:
register-with-eureka: false #只把此服务当成eurekaservice,不要当成client
fetch-registry: false #只把此服务当成eurekaservice,不要当成client
service-url:
defaultZone: http://user:password123@localhost:8761/eureka
3、在启动类上添加注解
@SpringBootApplication
@EnableEurekaServer
就可以启动服务发现的服务端程序了。
二、客户端的搭建
1、在pom文件中添加依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka</artifactId>
</dependency>
2、编写application.yml 配置
server:
port: 7901
session-timeout: 30
tomcat.max-threads: 0
tomcat.uri-encoding: UTF-8
spring:
application:
name: a-microservice-consumer-movie
logging:
level:
root: INFO
com.example.demo: debug
eureka:
client:
serviceUrl:
defaultZone: http://user:password123@localhost:8761/eureka
instance: #eureka管理页面客户端服务的地址显示实际IP
prefer-ip-address: true #默认是false
3、在启动类添加注解
@SpringBootApplication
@EnableEurekaClient //针对Eureka服务注册使用
//@EnableDiscoveryClient //可以对其他服务注册软件使用
这样客户端配置完毕,先启动服务端,再启动客户端,服务端就可以自动发现客户端服务了。
springboot的应用打包默认是打成jar包,并且如果是web应用的话,默认使用内置的tomcat充当servlet容器,但毕竟内置的tomcat有时候并不满足我们的需求,如有时候我们想集群或者其他一些特性优化配置,因此我们需要把springboot的jar应用打包成war包,并能够在外部tomcat中运行。
很多人会疑问,你直接打成war包并部署到tomcat的webapp下不就行了么?No,springboot的如果在类路径下有tomcat相关类文件,就会以内置tomcat启动的方式,经过你把war包扔到外置的tomcat的webapp文件下启动springBoot应用也无事于补。
要把springboot应用转至外部tomcat的操作主要有以下三点:
1、把pom.xml文件中打包结果由jar改成war,如下:
- <modelVersion>4.0.0</modelVersion>
- <groupId>spring-boot-panminlan-mybatis-test</groupId>
- <artifactId>mybatis-test</artifactId>
- <packaging>war</packaging>
- <version>0.0.1-SNAPSHOT</version>
2、添加maven的war打包插件如下:并且给war包起一个名字,tomcat部署后的访问路径会需要,如:http:localhost:8080/myweb/****
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-war-plugin</artifactId>
- <configuration>
- <warSourceExcludes>src/main/resources/**</warSourceExcludes>
- <warName>myweb</warName>
- </configuration>
- </plugin>
3、排除org.springframework.boot依赖中的tomcat内置容器,这是很重要的一步
- <dependency>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-starter-web</artifactId>
- <exclusions>
- <exclusion>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-starter-tomcat</artifactId>
- </exclusion>
- </exclusions>
- </dependency>
4、添加对servlet API的依赖
- <dependency>
- <groupId>javax.servlet</groupId>
- <artifactId>javax.servlet-api</artifactId>
- </dependency>
5、继承SpringBootServletInitializer
,并覆盖它的 configure
方法,如下图代码,为什么需要提供这样一个SpringBootServletInitializer子类并覆盖它的config方法呢,我们看下该类原代码的注释:
/**Note that a WebApplicationInitializer is only needed if you are building a war file and
* deploying it. If you prefer to run an embedded container then you won't need this at
* all.
如果我们构建的是wai包并部署到外部tomcat则需要使用它,如果使用内置servlet容器则不需要,外置tomcat环境的配置需要这个类的configure方法来指定初始化资源。
//@ServletComponentScan
public class JobManagementApplication extends SpringBootServletInitializer{
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(JobManagementApplication.class);
}
public static void main(String[] args) {
SpringApplication.run(JobManagementApplication.class, args);
}
}
经过以上配置,我们把构建好的war包拷到tomcat的webapp下,启动tomcat就可以访问啦
在pom文件中加入
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<optional>true</optional>
<scope>true</scope>
</dependency>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<fork>true</fork>
</configuration>
</plugin>
第一种配置方法:
在实体类中加入格式化属性的注解
public class User implements Serializable{
/**
*
*/
private static final long serialVersionUID = 1L;
private Integer id;
private String username;
private Date birthday;
private Integer age;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
@JSONField(format="yyyy-MM-dd hh:MM:ss")
public Date getBirthday() {
return birthday;
}
public void setBirthday(Date birthday) {
this.birthday = birthday;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
2.在启动类中继承类
@SpringBootApplication
public class Demo1Application2 extends WebMvcConfigurerAdapter{
@Override
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
super.configureMessageConverters(converters);
FastJsonHttpMessageConverter fastConverter=new FastJsonHttpMessageConverter();
FastJsonConfig fastJsonConfig = new FastJsonConfig();
fastJsonConfig.setSerializerFeatures(SerializerFeature.PrettyFormat);
fastConverter.setFastJsonConfig(fastJsonConfig);
converters.add(fastConverter);
}
public static void main(String[] args) {
SpringApplication app=new SpringApplication(Demo1Application2.class);
ConfigurableApplicationContext context = app.run( args);
//context.close();
}
}
3.访问页面,请求方法,得到结果
{ "age":11, "birthday":"2018-03-15 10:03:55", "id":1, "username":"dddd" }第二种配置方法:在启动类加入一个bean@SpringBootApplication
public class Demo1Application3 {
@Bean
public HttpMessageConverters fastJsonHttpMessageConverters() {
FastJsonHttpMessageConverter fastConverter=new FastJsonHttpMessageConverter();
FastJsonConfig fastJsonConfig = new FastJsonConfig();
fastJsonConfig.setSerializerFeatures(SerializerFeature.PrettyFormat);
fastConverter.setFastJsonConfig(fastJsonConfig);
HttpMessageConverter<?> converters=fastConverter;
return new HttpMessageConverters(converters);
}
public static void main(String[] args) {
SpringApplication app=new SpringApplication(Demo1Application3.class);
ConfigurableApplicationContext context = app.run( args);
//context.close();
}
}
1、aop的简单实现
public class User implements InitializingBean,DisposableBean{
public String toString() {
System.out.println("userdddd");
return "444";
}
@Override
public void afterPropertiesSet() throws Exception {
System.out.println(" user afterPropertiesSet");
}
@Override
public void destroy() throws Exception {
System.out.println("user destroy");
}
}
public class LogUser extends User{
public String toString() {
System.out.println("log start");
super.toString();
System.out.println("log end");
return "";
}
}
public interface MyApplicationContextAware {
void setApplicationContext(ApplicationContext applicationContext) throws BeansException;
}
@Component
public class Dog4 implements MyApplicationContextAware{
ApplicationContext applicationContext;
public ApplicationContext getApplicationContext() {
return applicationContext;
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext=applicationContext;
}
}
@Component
public class MyBeanPostProcessor implements BeanPostProcessor{
@Autowired
ApplicationContext applicationContext;
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
System.out.println("postProcessAfterInitialization=="+beanName);
return BeanPostProcessor.super.postProcessAfterInitialization(bean, beanName);
}
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
System.out.println("postProcessBeforeInitialization=="+beanName);
if(bean instanceof User) {
return new LogUser();
}
if(bean instanceof MyApplicationContextAware) {
MyApplicationContextAware my=(MyApplicationContextAware) bean;
my.setApplicationContext(applicationContext);
}
return BeanPostProcessor.super.postProcessBeforeInitialization(bean, beanName);
}
}
public class App {
public static void main(String[] args) {
AnnotationConfigApplicationContext aa=new AnnotationConfigApplicationContext("com.yjw");
Dog4 dog = aa.getBean(Dog4.class);
System.out.println(dog.getApplicationContext());
User user = aa.getBean(User.class);
System.out.println(user.toString());
aa.close();
}
}
@Component
public class MyBeanPostProcessor implements BeanPostProcessor{
//在每个bean初始化后,初始化方法执行后,都执行
的方法
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
System.out.println("postProcessAfterInitialization=="+beanName);
return BeanPostProcessor.super.postProcessAfterInitialization(bean, beanName);
}
//在每个bean初始化后,在初始化方法执行前,都执行的方法
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
System.out.println("postProcessBeforeInitialization=="+beanName);
return BeanPostProcessor.super.postProcessBeforeInitialization(bean, beanName);
}
}
三种初始化方式
public class Cat {
@PostConstruct//初始化
public void afterPropertiesSet() throws Exception {
System.out.println(" cat init");
}
@PreDestroy//销毁
public void destroy() throws Exception {
System.out.println("cat destroy");
}
}
public class User implements InitializingBean,DisposableBean{
public String toString() {
return "444";
}
@Override//初始化
public void afterPropertiesSet() throws Exception {
System.out.println(" user afterPropertiesSet");
}
@Override//销毁
public void destroy() throws Exception {
System.out.println("user destroy");
}
}
public class Room {
//初始化
public void afterPropertiesSet() throws Exception {
System.out.println(" room afterPropertiesSet");
}
//销毁
public void destroy() throws Exception {
System.out.println("room destroy");
}
}
@Configuration
public class Cfg1 {
@Bean
public Cat getCat() {
return new Cat();
}
@Bean
public User getUser() {
return new User();
}
@Bean(initMethod="afterPropertiesSet",destroyMethod="destroy")
public Room getRoom() {
return new Room();
}
}
@Configuration
public class RedisClusterConfig {
@Value("${spring.redis.cluster.nodes}")
private String clusterNodes;
@Bean
public JedisCluster getJedisCluster() {
// 截取集群节点
String[] cluster = clusterNodes.split(",");
// 创建set集合
Set<HostAndPort> nodes = new HashSet<HostAndPort>();
// 循环数组把集群节点添加到set集合中
for (String node : cluster) {
String[] host = node.split(":");
//添加集群节点
nodes.add(new HostAndPort(host[0], Integer.parseInt(host[1])));
}
JedisCluster jc = new JedisCluster(nodes);
return jc;
}
}
在application.properties文件中,配置spring.redis.cluster.nodes=
在使用的时候直接得到JedisCluster对象使用
一、Redis提供了哪些持久化机制:
1). RDB持久化:
该机制是指在指定的时间间隔内将内存中的数据集快照写入磁盘。
2). AOF持久化:
该机制将以日志的形式记录服务器所处理的每一个写操作,在Redis服务器启动之初会读取该文件来重新构建数据库,以保证启动后数据库中的数据是完整的。
3). 无持久化:
我们可以通过配置的方式禁用Redis服务器的持久化功能,这样我们就可以将Redis视为一个功能加强版的memcached了。
4). 同时应用AOF和RDB。
二、RDB机制的优势和劣势:
RDB存在哪些优势呢?
1). 一旦采用该方式,那么你的整个Redis数据库将只包含一个文件,这对于文件备份而言是非常完美的。比如,你可能打算每个小时归档一次最近24小时的数据,同时还要每天归档一次最近30天的数据。通过这样的备份策略,一旦系统出现灾难性故障,我们可以非常容易的进行恢复。
2). 对于灾难恢复而言,RDB是非常不错的选择。因为我们可以非常轻松的将一个单独的文件压缩后再转移到其它存储介质上。
3). 性能最大化。对于Redis的服务进程而言,在开始持久化时,它唯一需要做的只是fork出子进程,之后再由子进程完成这些持久化的工作,这样就可以极大的避免服务进程执行IO操作了。
4). 相比于AOF机制,如果数据集很大,RDB的启动效率会更高。
RDB又存在哪些劣势呢?
1). 如果你想保证数据的高可用性,即最大限度的避免数据丢失,那么RDB将不是一个很好的选择。因为系统一旦在定时持久化之前出现宕机现象,此前没有来得及写入磁盘的数据都将丢失。
2). 由于RDB是通过fork子进程来协助完成数据持久化工作的,因此,如果当数据集较大时,可能会导致整个服务器停止服务几百毫秒,甚至是1秒钟。
三、AOF机制的优势和劣势:
AOF的优势有哪些呢?
1). 该机制可以带来更高的数据安全性,即数据持久性。Redis中提供了3中同步策略,即每秒同步、每修改同步和不同步。事实上,每秒同步也是异步完成的,其效率也是非常高的,所差的是一旦系统出现宕机现象,那么这一秒钟之内修改的数据将会丢失。而每修改同步,我们可以将其视为同步持久化,即每次发生的数据变化都会被立即记录到磁盘中。可以预见,这种方式在效率上是最低的。至于无同步,无需多言,我想大家都能正确的理解它。
2). 由于该机制对日志文件的写入操作采用的是append模式,因此在写入过程中即使出现宕机现象,也不会破坏日志文件中已经存在的内容。然而如果我们本次操作只是写入了一半数据就出现了系统崩溃问题,不用担心,在Redis下一次启动之前,我们可以通过redis-check-aof工具来帮助我们解决数据一致性的问题。
3). 如果日志过大,Redis可以自动启用rewrite机制。即Redis以append模式不断的将修改数据写入到老的磁盘文件中,同时Redis还会创建一个新的文件用于记录此期间有哪些修改命令被执行。因此在进行rewrite切换时可以更好的保证数据安全性。
4). AOF包含一个格式清晰、易于理解的日志文件用于记录所有的修改操作。事实上,我们也可以通过该文件完成数据的重建。
AOF的劣势有哪些呢?
1). 对于相同数量的数据集而言,AOF文件通常要大于RDB文件。
2). 根据同步策略的不同,AOF在运行效率上往往会慢于RDB。总之,每秒同步策略的效率是比较高的,同步禁用策略的效率和RDB一样高效。
四、其它:
1. Snapshotting:
缺省情况下,Redis会将数据集的快照dump到dump.rdb文件中。此外,我们也可以通过配置文件来修改Redis服务器dump快照的频率,在打开6379.conf文件之后,我们搜索save,可以看到下面的配置信息:
save 900 1 #在900秒(15分钟)之后,如果至少有1个key发生变化,则dump内存快照。
save 300 10 #在300秒(5分钟)之后,如果至少有10个key发生变化,则dump内存快照。
save 60 10000 #在60秒(1分钟)之后,如果至少有10000个key发生变化,则dump内存快照。
2. Dump快照的机制:
1). Redis先fork子进程。
2). 子进程将快照数据写入到临时RDB文件中。
3). 当子进程完成数据写入操作后,再用临时文件替换老的文件。
3. AOF文件:
上面已经多次讲过,RDB的快照定时dump机制无法保证很好的数据持久性。如果我们的应用确实非常关注此点,我们可以考虑使用Redis中的AOF机制。对于Redis服务器而言,其缺省的机制是RDB,如果需要使用AOF,则需要修改配置文件中的以下条目:
将appendonly no改为appendonly yes
从现在起,Redis在每一次接收到数据修改的命令之后,都会将其追加到AOF文件中。在Redis下一次重新启动时,需要加载AOF文件中的信息来构建最新的数据到内存中。
4. AOF的配置:
在Redis的配置文件中存在三种同步方式,它们分别是:
appendfsync always #每次有数据修改发生时都会写入AOF文件。
appendfsync everysec #每秒钟同步一次,该策略为AOF的缺省策略。
appendfsync no #从不同步。高效但是数据不会被持久化。
5. 如何修复坏损的AOF文件:
1). 将现有已经坏损的AOF文件额外拷贝出来一份。
2). 执行"redis-check-aof --fix <filename>"命令来修复坏损的AOF文件。
3). 用修复后的AOF文件重新启动Redis服务器。
6. Redis的数据备份:
在Redis中我们可以通过copy的方式在线备份正在运行的Redis数据文件。这是因为RDB文件一旦被生成之后就不会再被修改。Redis每次都是将最新的数据dump到一个临时文件中,之后在利用rename函数原子性的将临时文件改名为原有的数据文件名。因此我们可以说,在任意时刻copy数据文件都是安全的和一致的。鉴于此,我们就可以通过创建cron job的方式定时备份Redis的数据文件,并将备份文件copy到安全的磁盘介质中。
安装
1/到官网下载最新stable版
2/解压源码并进入目录
3/ make
4/ 可选 make test (可能出现need tcl>8.4,yum install tcl)
5/安装到指定目录,如 /usr/local/redis
make PREFIX=/usr/local/redis install
运行
./bin/redis-server redis-2.8.19/redis.conf
(默认前端运行模式。后台进程模式: 修改conf daemonize yes)
连接
[root@bogon redis]# ./bin/redis-cli
127.0.0.1:6379> set a bb
OK
127.0.0.1:6379> get a
"bb"
127.0.0.1:6379> get aa
(nil)
127.0.0.1:6379>
后来发现了logratate这个工具,Ubuntu
下的mysql,nginx好像也是用的这个工具还定期整理log的。配置文件为/etc/logrotate.conf,和很多其它ubuntu下的工
具一下,也可以把配置文件写在/etc/logrotate.d/下面。如对我们的tomcat的log文件进行整理,sudo vi
/etc/logrotate.d/tomcat,
/opt/tomcat/logs/catalina.out {
rotate 14
daily
copytruncate
compress
notifempty
missingok
}
其中:
rotate 7 表示保留7天的备份文件
daily 表示每天整理一次
copytruncate 表示先复制log文件的内容,然后再清空
compress 表示压缩备分文件
missingok 表示如果找不到log文件也没OK
notifempty 表示如果log文件是空的,就不进行rotate
可以通过/usr/sbin/logrotate -f /etc/logrotate.conf来执行。Ubuntu
有/etc/cron.daily/logrotate文件,内容为:
#!/bin/sh
test -x /usr/sbin/logrotate || exit 0
/usr/sbin/logrotate /etc/logrotate.conf
表示每天会定时执行一次这个命令
通过ntp同步服务器的时间
根据 Ubuntu 的文档 有两种方式可以用来使服务器的时间和ntp server同步。一种是通过ntpdate命令,如
ntpdate ntp.Ubuntu .com
然后在/etc/cron.daily/下新建一个文件来每天执行一次这个命令
另一种是通过ntpd来更新。sudo apt-get install
ntp。配置文件/etc/ntp.conf,可以通过修改配置文件为改变ntp server,
我们用的是210.72.145.44这个server
对于Linux 的系统安全来说,日志文件是极其重要的工具。系统管理员可以使用logrotate
程序用来管理系统中的最新的事件,对于Linux 的系统安全来说,日志文件是极其重要的工具。系统管理员可以使用logrotate
程序用来管理系统中的最新的事件。logrotate 还可以用来备份日志文件,本篇将通过以下几部分来介绍
日志文件的管理:
1、logrotate 配置
2、缺省配置 logrotate
3、使用include 选项读取其他配置文件
4、使用include 选项覆盖缺省配置
5、为指定的文件配置转储参数
一、logrotate 配置
logrotate
程序是一个日志文件管理工具。用来把旧的日志文件删除,并创建新的日志文件,我们把它叫做“转储”。我们可以根据日志文件的大小,也可以根据其天数来转储,这个过程一般通过
cron 程序来执行。
logrotate 程序还可以用于压缩日志文件,以及发送日志到指定的E-mail 。
logrotate 的配置文件是 /etc/logrotate.conf。主要参数如下表:
参数 功能
compress 通过gzip 压缩转储以后的日志
nocompress 不需要压缩时,用这个参数
copytruncate 用于还在打开中的日志文件,把当前日志备份并截断
nocopytruncate 备份日志文件但是不截断
create mode owner group 转储文件,使用指定的文件模式创建新的日志文件
nocreate 不建立新的日志文件
delaycompress 和 compress 一起使用时,转储的日志文件到下一次转储时才压缩
nodelaycompress 覆盖 delaycompress 选项,转储同时压缩。
errors address 专储时的错误信息发送到指定的Email 地址
ifempty 即使是空文件也转储,这个是 logrotate 的缺省选项。
notifempty 如果是空文件的话,不转储
mail address 把转储的日志文件发送到指定的E-mail 地址
nomail 转储时不发送日志文件
olddir directory 转储后的日志文件放入指定的目录,必须和当前日志文件在同一个文件系统
noolddir 转储后的日志文件和当前日志文件放在同一个目录下
prerotate/endscript 在转储以前需要执行的命令可以放入这个对,这两个关键字必须单独成行
postrotate/endscript 在转储以后需要执行的命令可以放入这个对,这两个关键字必须单独成行
daily 指定转储周期为每天
weekly 指定转储周期为每周
monthly 指定转储周期为每月
rotate count 指定日志文件删除之前转储的次数,0 指没有备份,5 指保留5 个备份
tabootext [+] list 让logrotate 不转储指定扩展名的文件,缺省的扩展名是:.rpm-orig,
.rpmsave, v, 和 ~
size size 当日志文件到达指定的大小时才转储,Size 可以指定 bytes (缺省)以及KB
(sizek)或者MB (sizem).cat /dev/null >catalina.out
后来发现了logratate这个工具,Ubuntu
下的mysql,nginx好像也是用的这个工具还定期整理log的。配置文件为/etc/logrotate.conf,和很多其它ubuntu下的工
具一下,也可以把配置文件写在/etc/logrotate.d/下面。如对我们的tomcat的log文件进行整理,sudo vi
/etc/logrotate.d/tomcat,
/opt/tomcat/logs/catalina.out {
rotate 14
daily
copytruncate
compress
notifempty
missingok
}
其中:
rotate 7 表示保留7天的备份文件
daily 表示每天整理一次
copytruncate 表示先复制log文件的内容,然后再清空
compress 表示压缩备分文件
missingok 表示如果找不到log文件也没OK
notifempty 表示如果log文件是空的,就不进行rotate
可以通过/usr/sbin/logrotate -f /etc/logrotate.conf来执行。Ubuntu
有/etc/cron.daily/logrotate文件,内容为:
#!/bin/sh
test -x /usr/sbin/logrotate || exit 0
/usr/sbin/logrotate /etc/logrotate.conf
表示每天会定时执行一次这个命令
通过ntp同步服务器的时间
根据 Ubuntu 的文档 有两种方式可以用来使服务器的时间和ntp server同步。一种是通过ntpdate命令,如
ntpdate ntp.Ubuntu .com
然后在/etc/cron.daily/下新建一个文件来每天执行一次这个命令
另一种是通过ntpd来更新。sudo apt-get install
ntp。配置文件/etc/ntp.conf,可以通过修改配置文件为改变ntp server,
我们用的是210.72.145.44这个server
对于Linux 的系统安全来说,日志文件是极其重要的工具。系统管理员可以使用logrotate
程序用来管理系统中的最新的事件,对于Linux 的系统安全来说,日志文件是极其重要的工具。系统管理员可以使用logrotate
程序用来管理系统中的最新的事件。logrotate 还可以用来备份日志文件,本篇将通过以下几部分来介绍
日志文件的管理:
1、logrotate 配置
2、缺省配置 logrotate
3、使用include 选项读取其他配置文件
4、使用include 选项覆盖缺省配置
5、为指定的文件配置转储参数
一、logrotate 配置
logrotate
程序是一个日志文件管理工具。用来把旧的日志文件删除,并创建新的日志文件,我们把它叫做“转储”。我们可以根据日志文件的大小,也可以根据其天数来转储,这个过程一般通过
cron 程序来执行。
logrotate 程序还可以用于压缩日志文件,以及发送日志到指定的E-mail 。
logrotate 的配置文件是 /etc/logrotate.conf。主要参数如下表:
参数 功能
compress 通过gzip 压缩转储以后的日志
nocompress 不需要压缩时,用这个参数
copytruncate 用于还在打开中的日志文件,把当前日志备份并截断
nocopytruncate 备份日志文件但是不截断
create mode owner group 转储文件,使用指定的文件模式创建新的日志文件
nocreate 不建立新的日志文件
delaycompress 和 compress 一起使用时,转储的日志文件到下一次转储时才压缩
nodelaycompress 覆盖 delaycompress 选项,转储同时压缩。
errors address 专储时的错误信息发送到指定的Email 地址
ifempty 即使是空文件也转储,这个是 logrotate 的缺省选项。
notifempty 如果是空文件的话,不转储
mail address 把转储的日志文件发送到指定的E-mail 地址
nomail 转储时不发送日志文件
olddir directory 转储后的日志文件放入指定的目录,必须和当前日志文件在同一个文件系统
noolddir 转储后的日志文件和当前日志文件放在同一个目录下
prerotate/endscript 在转储以前需要执行的命令可以放入这个对,这两个关键字必须单独成行
postrotate/endscript 在转储以后需要执行的命令可以放入这个对,这两个关键字必须单独成行
daily 指定转储周期为每天
weekly 指定转储周期为每周
monthly 指定转储周期为每月
rotate count 指定日志文件删除之前转储的次数,0 指没有备份,5 指保留5 个备份
tabootext [+] list 让logrotate 不转储指定扩展名的文件,缺省的扩展名是:.rpm-orig,
.rpmsave, v, 和 ~
size size 当日志文件到达指定的大小时才转储,Size 可以指定 bytes (缺省)以及KB
(sizek)或者MB (sizem).
原文来自http://note.youdao.com/share/web/file.html?id=236896997b6ffbaa8e0d92eacd13abbf&type=note
我怕链接会失效,故转载此篇文章
由于linux目前很热门,越来越多的人在学习linux,但是买一台服务放家里来学习,实在是很浪费。那么如何解决这个问题?虚拟机软件是很好的选择,常用的虚拟机软件有vmware workstations和virtual box等。在使用虚拟机软件的时候,很多初学者都会遇到很多问题,而vmware的网络连接问题是大家遇到最多问题之一。在学习交流群里面,几乎每天都会有同学问到这些问题,写这篇详解也是因为群里童鞋网络出故障,然后在帮他解决的过程中,对自己的理解也做一个总结。接下来,我们就一起来探讨一下关于vmware workstations网络连接的三种模式。
vmware为我们提供了三种网络工作模式,它们分别是:Bridged(桥接模式)、NAT(网络地址转换模式)、Host-Only(仅主机模式)。
打开vmware虚拟机,我们可以在选项栏的“编辑”下的“虚拟网络编辑器”中看到VMnet0(桥接模式)、VMnet1(仅主机模式)、VMnet8(NAT模式),那么这些都是有什么作用呢?其实,我们现在看到的VMnet0表示的是用于桥接模式下的虚拟交换机;VMnet1表示的是用于仅主机模式下的虚拟交换机;VMnet8表示的是用于NAT模式下的虚拟交换机。

同时,在主机上对应的有VMware Network Adapter VMnet1和VMware Network Adapter VMnet8两块虚拟网卡,它们分别作用于仅主机模式与NAT模式下。在“网络连接”中我们可以看到这两块虚拟网卡,如果将这两块卸载了,可以在vmware的“编辑”下的“虚拟网络编辑器”中点击“还原默认设置”,可重新将虚拟网卡还原。

小伙伴看到这里,肯定有疑问,为什么在真机上没有VMware Network Adapter VMnet0虚拟网卡呢?那么接下来,我们就一起来看一下这是为什么。
一、Bridged(桥接模式)
什么是桥接模式?桥接模式就是将主机网卡与虚拟机虚拟的网卡利用虚拟网桥进行通信。在桥接的作用下,类似于把物理主机虚拟为一个交换机,所有桥接设置的虚拟机连接到这个交换机的一个接口上,物理主机也同样插在这个交换机当中,所以所有桥接下的网卡与网卡都是交换模式的,相互可以访问而不干扰。在桥接模式下,虚拟机ip地址需要与主机在同一个网段,如果需要联网,则网关与DNS需要与主机网卡一致。其网络结构如下图所示:

接下来,我们就来实际操作,如何设置桥接模式。
首先,安装完系统之后,在开启系统之前,点击“编辑虚拟机设置”来设置网卡模式。

点击“网络适配器”,选择“桥接模式”,然后“确定”

在进入系统之前,我们先确认一下主机的ip地址、网关、DNS等信息。

然后,进入系统编辑网卡配置文件,命令为vi /etc/sysconfig/network-scripts/ifcfg-eth0

添加内容如下:

编辑完成,保存退出,然后重启虚拟机网卡,使用ping命令ping外网ip,测试能否联网。

能ping通外网ip,证明桥接模式设置成功。
那主机与虚拟机之间的通信是否正常呢?我们就用远程工具来测试一下。

主机与虚拟机通信正常。
这就是桥接模式的设置步骤,相信大家应该学会了如何去设置桥接模式了。桥接模式配置简单,但如果你的网络环境是ip资源很缺少或对ip管理比较严格的话,那桥接模式就不太适用了。如果真是这种情况的话,我们该如何解决呢?接下来,我们就来认识vmware的另一种网络模式:NAT模式。
二、NAT(地址转换模式)
刚刚我们说到,如果你的网络ip资源紧缺,但是你又希望你的虚拟机能够联网,这时候NAT模式是最好的选择。NAT模式借助虚拟NAT设备和虚拟DHCP服务器,使得虚拟机可以联网。其网络结构如下图所示:

在NAT模式中,主机网卡直接与虚拟NAT设备相连,然后虚拟NAT设备与虚拟DHCP服务器一起连接在虚拟交换机VMnet8上,这样就实现了虚拟机联网。那么我们会觉得很奇怪,为什么需要虚拟网卡VMware Network Adapter VMnet8呢?原来我们的VMware Network Adapter VMnet8虚拟网卡主要是为了实现主机与虚拟机之间的通信。在之后的设置步骤中,我们可以加以验证。
首先,设置虚拟机中NAT模式的选项,打开vmware,点击“编辑”下的“虚拟网络编辑器”,设置NAT参数及DHCP参数。



将虚拟机的网络连接模式修改成NAT模式,点击“编辑虚拟机设置”。

点击“网络适配器”,选择“NAT模式”

然后开机启动系统,编辑网卡配置文件,命令为vi /etc/sysconfig/network-scripts/ifcfg-eth0

具体配置如下:

编辑完成,保存退出,然后重启虚拟机网卡,动态获取ip地址,使用ping命令ping外网ip,测试能否联网。

之前,我们说过VMware Network Adapter VMnet8虚拟网卡的作用,那我们现在就来测试一下。


如此看来,虚拟机能联通外网,确实不是通过VMware Network Adapter VMnet8虚拟网卡,那么为什么要有这块虚拟网卡呢?
之前我们就说VMware Network Adapter VMnet8的作用是主机与虚拟机之间的通信,接下来,我们就用远程连接工具来测试一下。

然后,将VMware Network Adapter VMnet8启用之后,发现远程工具可以连接上虚拟机了。
那么,这就是NAT模式,利用虚拟的NAT设备以及虚拟DHCP服务器来使虚拟机连接外网,而VMware Network Adapter VMnet8虚拟网卡是用来与虚拟机通信的。
三、Host-Only(仅主机模式)
Host-Only模式其实就是NAT模式去除了虚拟NAT设备,然后使用VMware Network Adapter VMnet1虚拟网卡连接VMnet1虚拟交换机来与虚拟机通信的,Host-Only模式将虚拟机与外网隔开,使得虚拟机成为一个独立的系统,只与主机相互通讯。其网络结构如下图所示:

通过上图,我们可以发现,如果要使得虚拟机能联网,我们可以将主机网卡共享给VMware Network Adapter VMnet1网卡,从而达到虚拟机联网的目的。接下来,我们就来测试一下。
首先设置“虚拟网络编辑器”,可以设置DHCP的起始范围。

设置虚拟机为Host-Only模式。

开机启动系统,然后设置网卡文件。

保存退出,然后重启网卡,利用远程工具测试能否与主机通信。

主机与虚拟机之间可以通信,现在设置虚拟机联通外网。

我们可以看到上图有一个提示,强制将VMware Network Adapter VMnet1的ip设置成192.168.137.1,那么接下来,我们就要将虚拟机的DHCP的子网和起始地址进行修改,点击“虚拟网络编辑器”

重新配置网卡,将VMware Network Adapter VMnet1虚拟网卡作为虚拟机的路由。

重启网卡,然后通过 远程工具测试能否联通外网以及与主机通信。

测试结果证明可以使得虚拟机连接外网。
以上就是关于vmware三种网络模式的工作原理及配置详解。
Map<String,String> map=new HashMap<String,String>();
map.put("1", "222");
List<Map<String,String>> list = new ArrayList<Map<String,String>>();
list.add(map);
map=null;//没有效果,list中还是有数据
map.clear();//map没数据了
Map<String, String> map2 = list.get(0);
System.out.println(map2.size());
System.out.println(map2.get("1"));
背景
通过名字就知道,X-Forwarded-For 是一个 HTTP 扩展头部。HTTP/1.1(RFC 2616)协议并没有对它的定义,它最开始是由 Squid 这个缓存代理软件引入,用来表示 HTTP 请求端真实 IP。如今它已经成为事实上的标准,被各大 HTTP 代理、负载均衡等转发服务广泛使用,并被写入 RFC 7239(Forwarded HTTP Extension)标准之中。
X-Forwarded-For 请求头格式非常简单,就这样:
X-Forwarded-For: client, proxy1, proxy2
可以看到,XFF 的内容由「英文逗号 + 空格」隔开的多个部分组成,最开始的是离服务端最远的设备 IP,然后是每一级代理设备的 IP。
如果一个 HTTP 请求到达服务器之前,经过了三个代理 Proxy1、Proxy2、Proxy3,IP 分别为 IP1、IP2、IP3,用户真实 IP 为 IP0,那么按照 XFF 标准,服务端最终会收到以下信息:
X-Forwarded-For: IP0, IP1, IP2
Proxy3 直连服务器,它会给 XFF 追加 IP2,表示它是在帮 Proxy2 转发请求。列表中并没有 IP3,IP3 可以在服务端通过 Remote Address 字段获得。我们知道 HTTP 连接基于 TCP 连接,HTTP 协议中没有 IP 的概念,Remote Address 来自 TCP 连接,表示与服务端建立 TCP 连接的设备 IP,在这个例子里就是 IP3。
Remote Address 无法伪造,因为建立 TCP 连接需要三次握手,如果伪造了源 IP,无法建立 TCP 连接,更不会有后面的 HTTP 请求。不同语言获取 Remote Address 的方式不一样,例如 php 是 $_SERVER["REMOTE_ADDR"]
,Node.js 是 req.connection.remoteAddress
,但原理都一样。
问题
有了上面的背景知识,开始说问题。我用 Node.js 写了一个最简单的 Web Server 用于测试。HTTP 协议跟语言无关,这里用 Node.js 只是为了方便演示,换成任何其他语言都可以得到相同结论。另外本文用 Nginx 也是一样的道理,如果有兴趣,换成 Apache 或其他 Web Server 也一样。
下面这段代码会监听 9009
端口,并在收到 HTTP 请求后,输出一些信息:
JSvar http = require('http'); http.createServer(function (req, res) { res.writeHead(200, {'Content-Type': 'text/plain'}); res.write('remoteAddress: ' + req.connection.remoteAddress + '\n'); res.write('x-forwarded-for: ' + req.headers['x-forwarded-for'] + '\n'); res.write('x-real-ip: ' + req.headers['x-real-ip'] + '\n'); res.end(); }).listen(9009, '0.0.0.0');
这段代码除了前面介绍过的 Remote Address 和 X-Forwarded-For
,还有一个 X-Real-IP
,这又是一个自定义头部字段。X-Real-IP
通常被 HTTP 代理用来表示与它产生 TCP 连接的设备 IP,这个设备可能是其他代理,也可能是真正的请求端。需要注意的是,X-Real-IP
目前并不属于任何标准,代理和 Web 应用之间可以约定用任何自定义头来传递这个信息。
现在可以用域名 + 端口号直接访问这个 Node.js 服务,再配一个 Nginx 反向代理:
NGINXlocation / { proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header Host $http_host; proxy_set_header X-NginX-Proxy true; proxy_pass http://127.0.0.1:9009/; proxy_redirect off; }
我的 Nginx 监听 80
端口,所以不带端口就可以访问 Nginx 转发过的服务。
测试直接访问 Node 服务:
BASHcurl http://t1.imququ.com:9009/ remoteAddress: 114.248.238.236 x-forwarded-for: undefined x-real-ip: undefined
由于我的电脑直接连接了 Node.js 服务,Remote Address 就是我的 IP。同时我并未指定额外的自定义头,所以后两个字段都是 undefined。
再来访问 Nginx 转发过的服务:
BASHcurl http://t1.imququ.com/ remoteAddress: 127.0.0.1 x-forwarded-for: 114.248.238.236 x-real-ip: 114.248.238.236
这一次,我的电脑是通过 Nginx 访问 Node.js 服务,得到的 Remote Address 实际上是 Nginx 的本地 IP。而前面 Nginx 配置中的这两行起作用了,为请求额外增加了两个自定义头:
proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
实际上,在生产环境中部署 Web 应用,一般都采用上面第二种方式,有很多好处。但这就引入一个隐患:很多 Web 应用为了获取用户真正的 IP,从 HTTP 请求头中获取 IP。
HTTP 请求头可以随意构造,我们通过 curl 的 -H
参数构造 X-Forwarded-For
和 X-Real-IP
,再来测试一把。
直接访问 Node.js 服务:
BASHcurl http://t1.imququ.com:9009/ -H 'X-Forwarded-For: 1.1.1.1' -H 'X-Real-IP: 2.2.2.2' remoteAddress: 114.248.238.236 x-forwarded-for: 1.1.1.1 x-real-ip: 2.2.2.2
对于 Web 应用来说,X-Forwarded-For
和 X-Real-IP
就是两个普通的请求头,自然就不做任何处理原样输出了。这说明,对于直连部署方式,除了从 TCP 连接中得到的 Remote Address 之外,请求头中携带的 IP 信息都不能信。
访问 Nginx 转发过的服务:
BASHcurl http://t1.imququ.com/ -H 'X-Forwarded-For: 1.1.1.1' -H 'X-Real-IP: 2.2.2.2' remoteAddress: 127.0.0.1 x-forwarded-for: 1.1.1.1, 114.248.238.236 x-real-ip: 114.248.238.236
这一次,Nginx 会在 X-Forwarded-For
后追加我的 IP;并用我的 IP 覆盖 X-Real-IP
请求头。这说明,有了 Nginx 的加工,X-Forwarded-For
最后一节以及 X-Real-IP
整个内容无法构造,可以用于获取用户 IP。
用户 IP 往往会被使用与跟 Web 安全有关的场景上,例如检查用户登录地区,基于 IP 做访问频率控制等等。这种场景下,确保 IP 无法构造更重要。经过前面的测试和分析,对于直接面向用户部署的 Web 应用,必须使用从 TCP 连接中得到的 Remote Address;对于部署了 Nginx 这样反向代理的 Web 应用,在正确配置了 Set Header 行为后,可以使用 Nginx 传过来的 X-Real-IP
或 X-Forwarded-For
最后一节(实际上它们一定等价)。
那么,Web 应用自身如何判断请求是直接过来,还是由可控的代理转发来的呢?在代理转发时增加额外的请求头是一个办法,但是不怎么保险,因为请求头太容易构造了。如果一定要这么用,这个自定义头要够长够罕见,还要保管好不能泄露出去。
判断 Remote Address 是不是本地 IP 也是一种办法,不过也不完善,因为在 Nginx 所处服务器上访问,无论直连还是走 Nginx 代理,Remote Address 都是 127.0.0.1。这个问题还好通常可以忽略,更麻烦的是,反向代理服务器和实际的 Web 应用不一定部署在同一台服务器上。所以更合理的做法是收集所有代理服务器 IP 列表,Web 应用拿到 Remote Address 后逐一比对来判断是以何种方式访问。
通常,为了简化逻辑,生产环境会封掉通过带端口直接访问 Web 应用的形式,只允许通过 Nginx 来访问。那是不是这样就没问题了呢?也不见得。
首先,如果用户真的是通过代理访问 Nginx,X-Forwarded-For
最后一节以及 X-Real-IP
得到的是代理的 IP,安全相关的场景只能用这个,但有些场景如根据 IP 显示所在地天气,就需要尽可能获得用户真实 IP,这时候 X-Forwarded-For
中第一个 IP 就可以排上用场了。这时候需要注意一个问题,还是拿之前的例子做测试:
BASHcurl http://t1.imququ.com/ -H 'X-Forwarded-For: unknown, <>"1.1.1.1' remoteAddress: 127.0.0.1 x-forwarded-for: unknown, <>"1.1.1.1, 114.248.238.236 x-real-ip: 114.248.238.236
X-Forwarded-For
最后一节是 Nginx 追加上去的,但之前部分都来自于 Nginx 收到的请求头,这部分用户输入内容完全不可信。使用时需要格外小心,符合 IP 格式才能使用,不然容易引发 SQL 注入或 XSS 等安全漏洞。
结论
- 直接对外提供服务的 Web 应用,在进行与安全有关的操作时,只能通过 Remote Address 获取 IP,不能相信任何请求头;
- 使用 Nginx 等 Web Server 进行反向代理的 Web 应用,在配置正确的前提下,要用
X-Forwarded-For
最后一节 或 X-Real-IP
来获取 IP(因为 Remote Address 得到的是 Nginx 所在服务器的内网 IP);同时还应该禁止 Web 应用直接对外提供服务; - 在与安全无关的场景,例如通过 IP 显示所在地天气,可以从
X-Forwarded-For
靠前的位置获取 IP,但是需要校验 IP 格式合法性;
PS:网上有些文章建议这样配置 Nginx,其实并不合理:
proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $remote_addr;
这样配置之后,安全性确实提高了,但是也导致请求到达 Nginx 之前的所有代理信息都被抹掉,无法为真正使用代理的用户提供更好的服务。还是应该弄明白这中间的原理,具体场景具体分析。
proxy_intercept_errors on; #如果被代理服务器返回的状态码为400或者大于400,设置的error_page配置起作用。默认为off。
error_page 404 https://www.baidu.com; #错误页
如果我们的代理只允许接受get,post请求方法的一种
proxy_method get; #支持客户端的请求方法。post/get;
如果你的nginx服务器给2台web服务器做代理,负载均衡算法采用轮询,那么当你的一台机器web程序iis关闭,也就是说web不能访问,那么nginx服务器分发请求还是会给这台不能访问的web服务器,如果这里的响应连接时间过长,就会导致客户端的页面一直在等待响应,对用户来说体验就打打折扣,这里我们怎么避免这样的情况发生呢。这里我配张图来说明下问题。

如果负载均衡中其中web2发生这样的情况,nginx首先会去web1请求,但是nginx在配置不当的情况下会继续分发请求道web2,然后等待web2响应,直到我们的响应时间超时,才会把请求重新分发给web1,这里的响应时间如果过长,用户等待的时间就会越长。
下面的配置是解决方案之一。
proxy_connect_timeout 1; #nginx服务器与被代理的服务器建立连接的超时时间,默认60秒
proxy_read_timeout 1; #nginx服务器想被代理服务器组发出read请求后,等待响应的超时间,默认为60秒。
proxy_send_timeout 1; #nginx服务器想被代理服务器组发出write请求后,等待响应的超时间,默认为60秒。
proxy_ignore_client_abort on; #客户端断网时,nginx服务器是否终端对被代理服务器的请求。默认为off。
通常系统出于安全考虑,需要进行权限(账号、密码)和IP白名单控制。如何获取访问来源真实的IP,如果公司网络入口设置负载,自己系统设置nginx代理等操作,会使你达到目的不那么简单直接。
通常情况下我们使用request.getRemoteAddr()就可以获取到客户端ip,但是当我们使用了nginx作为反向代理后,由于在客户端和web服务器之间增加了中间层,因此web服务器无法直接拿到客户端的ip,通过$remote_addr变量拿到的将是反向代理服务器的ip地址。如果我们想要在web端获得用户的真实ip,就必须在nginx这里作一个赋值操作,如下:
proxy_set_header X-real-ip $remote_addr;
其中这个X-real-ip是一个自定义的变量名,这样用户的真实ip就被放在X-real-ip这个变量里了,然后,在web端可以这样获取:request.getAttribute("X-real-ip")。但是如果中间经过N次代理过来的请求,X-real-ip就只能获得到前一层代理的IP(10.6.61.14)了,下面是我的解决方案:


红色部分IP是使用X-Forwarded-For(简称XFF头)获取的:,它代表客户端,也就是HTTP的请求端真实的IP,只有在通过了HTTP 代理或者负载均衡服务器时才会添加该项(没有经过的获取为空)标准格式如下:
X-Forwarded-For: client1, proxy1, proxy2
从标准格式可以看出,X-Forwarded-For头信息可以有多个,中间用逗号分隔,第一项为真实的客户端ip,剩下的就是曾经经过的代理或负载均衡的ip地址,经过几个就会出现几个。
我的Nginx具体配置如下:

关于参数含义:
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
意思是增加(不是覆盖)一个$proxy_add_x_forwarded_for到X-Forwarded-For里去。
举个例子,有一个web应用,在它之前通过了两个nginx转发。在第一台nginx中,使用
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
现在的$proxy_add_x_forwarded_for变量的"X-Forwarded-For"部分是空的,所以只有$remote_addr,而$remote_addr的值是用户的ip,于是赋值以后,X-Forwarded-For变量的值就是用户的真实的ip地址了。
到了第二台nginx,使用
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
现在的$proxy_add_x_forwarded_for变量,X-Forwarded-For部分包含的是用户的真实ip,$remote_addr部分的值是上一台nginx的ip地址,于是通过这个赋值以后现在的X-Forwarded-For的值就变成了“用户的真实ip,第一台nginx的ip”。
所以我在程序中使用request.getHeader("x-forwarded-for").toString().split(",")[0]就能获取到访问客户的真实IP,不用担心前面有几层转发啦。
exp qq/1qqq BUFFER=640000 FILE=/oracleq/appq/oracleq/newq.DMP OWNER=qq
upstream tomcat_server { server IP地址:端口; }
upstream authority_server { server IP地址:端口; }
if ( $request_uri ~ "^\/itoo-basic" )
{
proxy_pass http://tomcat_server;
}
if ( $request_uri ~ "^\/itoo-authority" )
{
proxy_pass http://authority_server;
}
在Tomcat的bin目录中执行
chmod u+x *.sh
摘要: 二、安装Nginx1、上传nginx-0.7.63.tar.gz至/usr/local 2、执行如下命令解压nginx:1.#cd /usr/local2.#tar zxvf nginx-0.7.63.tar.gz3、编译安装nginx1.#cd nginx-0.7.632.#./configure --with-http_stub_status_module --with-...
阅读全文
//连接
connect /as sysdba
1.创建表空间和用户并为用户指定表空间
//创建临时表空间
create temporary tablespace user_temp tempfile 'D:oracleoradatauser_temp.dbf' size 50m autoextend on next 50m maxsize 20480m extent management local;
(注:user_temp是临时表空间的名称。)
//创建数据表空间lportal
create tablespace lportal logging datafile 'D:oracleoradatalportal.dbf' size 100m autoextend on next 50m extent management local;
(注:lportal是数据表空间的名称。)
//创建用户lportal并指定表空间
create user lportal identified by lportal default tablespace lportal_db temporary tablespace user_temp;
(注:第一个lportal是用户名,第二个lportal是密码;lportal_db是数据表空间名称,user_temp是临时表空间名称。)
//为lportal用户授权
grant connect,resource,dba to lportal;
2.数据备份(导入导出数据)
//导入数据
imp lportal/lportal@orcl file=d:lportal20121109.dmp full=Y
//导出数据
exp lportal/lportal@orcl file=D:lportal20121109.dmp
(数据的导入与导出,在进入到黑窗口后直接输入上列语句,不需要进入sqlplus)
3.删除用户及表空间
//删除用户以及用户所有的对象
drop user lportal cascade;
//删除表空间与表空间文件(注意:如果在创建表空间的时候带有双引号,则删除的时候也要带上)
DROP TABLESPACE "stu_new" INCLUDING CONTENTS AND DATAFILES;
前提:删除表空间之前要确认该表空间没有被其他用户使用之后再做删除
drop tablespace zfmi including contents and datafiles cascade onstraints;
//including contents 删除表空间中的内容,如果删除表空间之前表空间中有内容,而未加此参数,表空间删不掉,所以习惯性的加此参数
//including datafiles 删除表空间中的数据文件
//cascade constraints 同时删除tablespace中表的外键参照
4.查询表空间和查询用户
//查询所有表空间名称
select tablespace_name from dba_tablespaces;
//查看表空间的名称和状态
select tablespace_name,status from dba_tablespaces;
//查询当前表空间属性
select * from dba_tablespaces where tablespace_name='mtgyd';
//查询所有用户
select username from dba_users;
1、在某一目录下面创建存放表空间的目录,并赋予权限 chmod 777 文件 或者
sudo chmod -R 777 文件2、创建临时表空间 create temporary tablespace USER_TEMP tempfile '/app1/orac1lenamespase/newn1amespase/USER_TEMP1.bdf' size 5120m reuse autoextend on next 20m maxsize unlimited;
3.创建表空间 create tablespace ZHFXBEMS1 datafile '/app1/ora1clenamespase/newnames1pase/ZHFXBEMS1.dbf' size 20480M reuse autoextend on next 40M maxsize unlimited default storage(initial 128k next 128k minextents 2 maxextents unlimited);
4、创建用户和指定使用的表空间 create user qqidentified by 1 default tablespace ZHFXBEMSq temporary tablespace USER_TEMPq;
5.赋予权限
grant dba to qq;
grant connect,resource to qq;
grant select any table to qq;
grant delete any table to qq;
grant update any table to qq;
grant insert any table to qq;
当多线程访问资源时,每条线程的数据变量都是不一样的,线程间的数据需要做到独立,不能相互共享,例如,数据库中常见的转账业务,两次转出和转入操作,不能共享数据,还要注意线程安全。
package com.yjw.thread;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;
public class ThreadScopeShareData {
static class A{
public void get(){
System.out.println(" A="+Thread.currentThread().getName()+",data="+map.get(Thread.currentThread()));
}
}
static class B{
public void get(){
System.out.println(" B="+Thread.currentThread().getName()+",data="+map.get(Thread.currentThread()));
}
}
static Map<Thread, Integer> map = new HashMap<Thread, Integer>();
public static void main(String[] args) {
for (int i = 0; i < 2; i++) {
new Thread(new Runnable() {
public void run() {
int data=new Random().nextInt();
System.out.println(Thread.currentThread().getName()+",data="+data);
map.put(Thread.currentThread(), data);
new A().get();new B().get();
}
}).start();
}
}
}
当使用了mvc:resources标签后,必须使用 <mvc:annotation-driven/>标签,就不会请求controller失败了。
public class Man {
private String id;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public void man() {
System.out.println("man");
}
}
public class TestMan {
//值传递传递的是值的副本
public static int getInt(int i){
i=4;
return i;
}
//引用传递,传递的是对象的引用,指向的还是原来的对象
public static Man getMan(Man man){
man.setId("111");
return man;
}
public static String getS(String s){
return s="111";
}
public static void main(String[] args) {
int i=1;
TestMan.getInt(i);
System.out.println(i);
Man man = new Man();
man.setId("222");
TestMan.getMan(man);
System.out.println(man.getId());
String s="222";
TestMan.getS(s);
System.out.println(s);
}
}
package com.yjw.thread;
public class Test2 {
static class Businis {
boolean f = false;// true sub执行,false main执行
public synchronized void sub(int i) {
if (!f) {
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
for (int j = 1; j <= 10; j++) {
System.out.println("sub=" + j + ",loop=" + i);
}
f = false;
this.notify();
}
public synchronized void main(int i) {
if (f) {
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
for (int j = 1; j <= 100; j++) {
System.out.println("main=" + j + ",loop=" + i);
}
f = true;
this.notify();
}
}
public static void main(String[] args) {
final Businis businis = new Businis();
for (int i = 1; i <= 50; i++) {
businis.main(i);
businis.sub(i);
}
}
}
@org.junit.Test
public void test2(){
new Thread( new Runnable() {
public void run() {
System.out.println(2);
}
}){
public void run() {
System.out.println(1);
};
}.start();
}
线程重写了run方法,又传入了新的线程,此线程只执行重写了run方法的方法,因为根据面向对象的原则,子类重写了父类的方法,只执行子类的方法。
一个页面同时触发ajax请求的次数不能过多,同时触发的次数不要超过6个,不然过多的ajax会被浏览器阻塞,不能实现异步请求。
负载均衡时,如果客户端访问出现404的情况时,有可能是负载均衡映射到了空的服务造成的,需要检查负载均衡对应的后台主机是否存在。
1、
- create user aaaaidentified by 123aaa;
2、
grant connect, resource to aaaa;
3、
grant create session to aaaa;
在DAO文件中,通过sessionFactory.getCurrentSession()来获取会话,报异常:org.hibernate.HibernateException: createQuery is not valid without active transaction。经过实验,发现将Hibernate的配置文件中的<property name="current_session_context_class">thread</property>属性去掉就好了。原来"current_session_context_class"属性的意思是,设置当前会话的上下文环境,如果设置为thread,那么同一线程则共享同一session会话。因此通过getCurrentSession()得到的session,是同一线程上的session,而不是Spring管理的那个能够自动开启事务的session。去除掉该属性就好了
2. 泛型类:泛型只在编译时期有效,编译后的字节码文件中不存在有泛型信息!
1. 泛型方法:
public class GenericDemo {
// 定义泛型方法
public <K,T> T save(T t,K k) {
return null;
}
// 测试方法
@Test
public void testMethod() throws Exception {
// 使用泛型方法: 在使用泛型方法的时候,确定泛型类型
save(1.0f, 1);
}
}
2. 泛型类:
public class GenericDemo<T> {
// 定义泛型方法
public <K> T save(T t,K k) {
return null;
}
public void update(T t) {
}
// 测试方法
@Test
public void testMethod() throws Exception {
// 泛型类: 在创建爱泛型类对象的时候,确定类型
GenericDemo<String> demo = new GenericDemo<String>();
demo.save("test", 1);
}
}
3. 泛型接口:
/**
* 泛型接口
* @author Jie.Yuan
*
* @param <T>
*/
public interface IBaseDao<T> {
void save(T t );
void update(T t );
}
泛型接口类型确定: 实现泛型接口的类也是抽象,那么类型在具体的实现中确定或创建泛型类的时候确定。
泛型的反射
/**
* 所有dao的公用的方法,都在这里实现
* @author Jie.Yuan
*
*/
public class BaseDao<T>{
// 保存当前运行类的参数化类型中的实际的类型
private Class clazz;
// 表名
private String tableName;
// 构造函数: 1. 获取当前运行类的参数化类型; 2. 获取参数化类型中实际类型的定义(class)
public BaseDao(){
// this 表示当前运行类 (AccountDao/AdminDao)
// this.getClass() 当前运行类的字节码(AccountDao.class/AdminDao.class)
// this.getClass().getGenericSuperclass(); 当前运行类的父类,即为BaseDao<Account>
// 其实就是“参数化类型”, ParameterizedType
Type type = this.getClass().getGenericSuperclass();
// 强制转换为“参数化类型” 【BaseDao<Account>】
ParameterizedType pt = (ParameterizedType) type;
// 获取参数化类型中,实际类型的定义 【new Type[]{Account.class}】
Type types[] = pt.getActualTypeArguments();
// 获取数据的第一个元素:Accout.class
clazz = (Class) types[0];
// 表名 (与类名一样,只要获取类名就可以)
tableName = clazz.getSimpleName();
}
/**
* 主键查询
* @param id 主键值
* @return 返回封装后的对象
*/
public T findById(int id){
/*
* 1. 知道封装的对象的类型
* 2. 表名【表名与对象名称一样, 且主键都为id】
*
* 即,
* ---》得到当前运行类继承的父类 BaseDao<Account>
* ----》 得到Account.class
*/
String sql = "select * from " + tableName + " where id=? ";
try {
return JdbcUtils.getQuerrRunner().query(sql, new BeanHandler<T>(clazz), id);
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
/**
* 查询全部
* @return
*/
public List<T> getAll(){
String sql = "select * from " + tableName ;
try {
return JdbcUtils.getQuerrRunner().query(sql, new BeanListHandler<T>(clazz));
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
}
<!-- Log4j配置 -->
<context-param>
<param-name>log4jConfigLocation</param-name>
<param-value>classpath:config/log4j.properties</param-value>
</context-param>
<context-param>
<param-name>log4jRefreshInterval</param-name>
<param-value>60000</param-value>
</context-param>
<listener>
<listener-class>
org.springframework.web.util.Log4jConfigListener
</listener-class>
</listener>
<!-- end -->
<listener>
<listener-class>
org.springframework.web.context.ContextLoaderListener
</listener-class>
</listener>
配置的顺序不能乱!
package com.annotation;
import static java.lang.annotation.ElementType.FIELD;
import static java.lang.annotation.ElementType.METHOD;
import java.lang.annotation.Documented;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(value={ FIELD, METHOD})
public @interface Column {
String ColumnName();
}
package com.annotation;
import static java.lang.annotation.ElementType.FIELD;
import static java.lang.annotation.ElementType.METHOD;
import java.lang.annotation.Documented;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(value={ FIELD, METHOD})
public @interface Id {
}
package com.annotation;
import static java.lang.annotation.ElementType.TYPE;
import java.lang.annotation.Documented;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(value={ TYPE})
public @interface Table {
String tableName();
}
package com;
import java.lang.reflect.Field;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import com.annotation.Column;
import com.annotation.Id;
import com.annotation.Table;
public class BaseDao<T,Pk> {
private Class<T> persistentClass;
@SuppressWarnings("unused")
private Class<Pk> persistentPK;
private String tableName;//表名称
private String id;//主键
public BaseDao() {
ParameterizedType ptype=(ParameterizedType) this.getClass().getGenericSuperclass();
Type[] types = ptype.getActualTypeArguments();
for (Type type : types) {
System.out.println(type.toString());
}
this.persistentPK = (Class<Pk>) types[1];
this.persistentClass = (Class<T>) types[0];
Table table = this.persistentClass.getAnnotation(Table.class);
tableName=table.tableName();
Field[] fields = this.persistentClass.getDeclaredFields();
for (Field field : fields) {
field.setAccessible(true);
Id annotationId = field.getAnnotation(Id.class);
if(annotationId != null){
Column annotationCo = field.getAnnotation(Column.class);
id=annotationCo.ColumnName();
break;
}
}
}
public T getT(T t){
System.out.println(tableName);
System.out.println(id);
return t;
}
}
package com;
import com.annotation.Column;
import com.annotation.Id;
import com.annotation.Table;
@Table(tableName = "t_user")
public class User {
@Id
@Column(ColumnName = "uid")
private String id="1";
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public User(String id) {
super();
this.id = id;
System.out.println("有参数");
}
public User() {
System.out.println("没有参数");
}
}
package com;
public class UserDao extends BaseDao<User, String>{
}
package com;
import java.util.List;
public class App<T> {
/**
* list必须都是Number的子类
* @param list
*/
public void get1(List<? extends Number> list){
System.out.println(list.size());
}
/**
* list必须都是String的父类
* @param list
*/
public void get2(List<? super String> list){
System.out.println(list.size());
}
}
摘要: 一、秒杀业务为什么难做1)im系统,例如qq或者微博,每个人都读自己的数据(好友列表、群列表、个人信息);2)微博系统,每个人读你关注的人的数据,一个人读多个人的数据;3)秒杀系统,库存只有一份,所有人会在集中的时间读和写这些数据,非常多个人同时读一个数据。 例如:小米手机每周二的秒杀,可能手机只有1万部,但瞬时进入的流量可能是几百几千万。又例如:12306抢票,票是有限的,库存一份,瞬...
阅读全文
jdk的动态代理对象和目标对象要实现同一个接口。
public class Classes implements Serializable{
private Long cid;
public Long getCid() {
return cid;
}
public void setCid(Long cid) {
this.cid = cid;
}
public String getCname() {
return cname;
}
public void setCname(String cname) {
this.cname = cname;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
private String cname;
private String description;
}
public interface ClassesDao {
public void saveClasses(Classes classes);
}
public class ClassesDaoImpl implements ClassesDao{
@Override
public void saveClasses(Classes classes) {
System.out.println("保存");
}
}
public class MyTransaction {
public void beginTransaction(){
System.out.println("开始事务");
}
public void commit(){
System.out.println("提交事务");
}
}
public class ClassesDaoInterceptor implements InvocationHandler{
private Object target;
private MyTransaction myTransaction;
public ClassesDaoInterceptor(Object target,MyTransaction myTransaction){
this.target = target;
this.myTransaction = myTransaction;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
System.out.println(proxy.getClass().getName());
if(method.getName().equals("saveClasses")||
method.getName().equals("updateClasses")){
this.myTransaction.beginTransaction();//֪ͨ
method.invoke(this.target, args);//Ŀ�귽��
this.myTransaction.commit();
}else{
method.invoke(this.target, args);
}
return null;
}
}
public class ClassesDaoTest {
public static void testSaveClasses(){
Object target = new ClassesDaoImpl();
MyTransaction myTransaction = new MyTransaction();
ClassesDaoInterceptor interceptor = new ClassesDaoInterceptor(target, myTransaction);
ClassesDao proxyDao = (ClassesDao) Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), interceptor);
Classes classes = new Classes();
classes.setCname("aaaa");
proxyDao.saveClasses(classes);
}
public static void main(String[] args) {
testSaveClasses();
}
}
spring的事务也是动态代理实现的,当一个服务类里的一个实现了服务接口的方法中调用另一个服务方法,第二个服务方法不会加入到事务中,因为这种调用方式不是被代理对象调用,而是实际目标对象调用,不会产生代理对象,所以第二个服务方法不会加入到事务中,如果想实现这种操作,需要先得到aop的代理对象,AopContext.currentProxy();,得到服务接口,进行调用服务方法。spring的事务代理是cglib实现的,只能代理访问接口中的方法。
cglib的动态生成的代理对象是目标类的子类。
public class Classes implements Serializable{
private Long cid;
public Long getCid() {
return cid;
}
public void setCid(Long cid) {
this.cid = cid;
}
public String getCname() {
return cname;
}
public void setCname(String cname) {
this.cname = cname;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
private String cname;
private String description;
}
public interface ClassesDao {
public void saveClasses(Classes classes);
}
public class ClassesDaoImpl implements ClassesDao{
@Override
public void saveClasses(Classes classes) {
System.out.println("保存");
}
}
public class ClassesDaoInterceptor implements MethodInterceptor {
private Object target;
private MyTransaction myTransaction;
public ClassesDaoInterceptor(Object target, MyTransaction myTransaction) {
this.target = target;
this.myTransaction = myTransaction;
}
public Object create() {
Enhancer en = new Enhancer();
en.setSuperclass(target.getClass());
en.setCallback(this);
return en.create();
}
@Override
public Object intercept(Object proxy, Method method, Object[] args,
MethodProxy arg3) throws Throwable {
System.out.println(proxy.getClass().getName());
System.out.println(arg3.getSuperName());
if (method.getName().equals("saveClasses")
|| method.getName().equals("updateClasses")) {
this.myTransaction.beginTransaction();// ֪ͨ
method.invoke(this.target, args);// Ŀ�귽��
this.myTransaction.commit();
} else {
method.invoke(this.target, args);
}
return null;
}
}
public class MyTransaction {
public void beginTransaction(){
System.out.println("开始事务");
}
public void commit(){
System.out.println("提交事务");
}
}
public class ClassesDaoTest {
public static void testSaveClasses(){
Object dao = new ClassesDaoImpl();
MyTransaction myTransaction = new MyTransaction();
ClassesDaoInterceptor interceptor = new ClassesDaoInterceptor(dao, myTransaction);
ClassesDaoImpl proxyDao= (ClassesDaoImpl) interceptor.create();
Classes classes = new Classes();
classes.setCname("aaaa");
proxyDao.saveClasses(classes);
}
public static void main(String[] args) {
testSaveClasses();
}
}
jdk的动态代理模式的目标类和动态生成的代理类都要实现同一个接口。
public interface MoveAble {
void move();
}
public interface InvocationHandler {
public void invoke(Object o, Method m);
}
public class Tank1 implements MoveAble{
@Override
public void move() {
System.out.println("moving");
}
}
public class TimeHandler implements InvocationHandler{
private Object target;
public TimeHandler(Object target) {
super();
this.target = target;
}
@Override
public void invoke(Object o, Method m) {
long start = System.currentTimeMillis();
System.out.println("starttime:" + start);
System.out.println(o.getClass().getName());
try {
m.invoke(target);
} catch (Exception e) {
e.printStackTrace();
}
long end = System.currentTimeMillis();
System.out.println("time:" + (end-start));
}
}
public class Proxy {
public static Object newProxyInstance(Class infce, InvocationHandler invocationHandler) throws Exception { //JDK6 Complier API, CGLib, ASM
String methodStr = "";
String rt = "\r\n";
Method[] methods = infce.getMethods();
for(Method m : methods) {
Class<?> returnType = m.getReturnType();
methodStr += "@Override" + rt +
"public "+returnType+" " + m.getName() + "() {" + rt +
" try {" + rt +
" Method md = " + infce.getName() + ".class.getMethod(\"" + m.getName() + "\");" + rt +
" h.invoke(this, md);" + rt +
" }catch(Exception e) {e.printStackTrace();}" + rt +
"}";
}
String src =
"package proxy.tank;" + rt +
"import java.lang.reflect.Method;" + rt +
"public class $Proxy1 implements " + infce.getName() + "{" + rt +
" public $Proxy1(InvocationHandler h) {" + rt +
" this.h = h;" + rt +
" }" + rt +
" proxy.tank.InvocationHandler h;" + rt +
methodStr +
"}";
String fileName =
"d:/src/proxy/tank/$Proxy1.java";
File f = new File(fileName);
FileWriter fw = new FileWriter(f);
fw.write(src);
fw.flush();
fw.close();
//compile
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
StandardJavaFileManager fileMgr = compiler.getStandardFileManager(null, null, null);
Iterable units = fileMgr.getJavaFileObjects(fileName);
CompilationTask t = compiler.getTask(null, fileMgr, null, null, null, units);
t.call();
fileMgr.close();
//load into memory and create an instance
URL[] urls = new URL[] {new URL("file:/" + "d:/src/")};
URLClassLoader ul = new URLClassLoader(urls);
Class c = ul.loadClass("proxy.tank.$Proxy1");
System.out.println(c);
Constructor ctr = c.getConstructor(InvocationHandler.class);
Object m = ctr.newInstance(invocationHandler);
return m;
}
}
public class Client {
public static void main(String[] args) throws Exception {
Tank1 t = new Tank1();
InvocationHandler h = new TimeHandler(t);
MoveAble m = (MoveAble)Proxy.newProxyInstance(MoveAble.class, h);
m.move();
}
}
public interface MoveAble {
void move();
}
public class Tank1 implements MoveAble{
@Override
public void move() {
System.out.println("moving");
}
}
/**
*
* 聚合
*
*/
public class TankTime3 implements MoveAble{
private MoveAble t;
public TankTime3(){}
public TankTime3(MoveAble t){
this.t=t;
}
@Override
public void move() {
long s = System.currentTimeMillis();
t.move();
long e = System.currentTimeMillis();
System.out.println(e-s);
}
}
public class Test {
public static void main(String[] args) {
Tank1 t =new Tank1();
TankTime3 tt = new TankTime3(t);
tt.move();
}
}
使用策略模式自定义对象排序和比较属性值排序的例子
/**
*
* 实体类的接口
*
*/
public interface DongWu {
public int getAge();
public void setAge(int age) ;
public int getHigh();
public void setHigh(int high) ;
}
/**
*
* 排序接口
*
*/
public interface MyComparator {
int comparatorTo(Object object);
}
/**
*
* 具体的排序接口,和具体的实体类对象无关
*
*/
public interface TypeComparator {
int comparatorTo(Object object1,Object object2);
}
/**
*
* 按照年纪倒叙排序
*
*/
public class AgeDescTypeComparator implements TypeComparator {
@Override
public int comparatorTo(Object object1, Object object2) {
DongWu c1 = (DongWu) object1;
DongWu dw = (DongWu) object2;
if (c1.getAge() > dw.getAge()) {
return -1;
} else if (c1.getAge() < dw.getAge()) {
return 1;
}
return 0;
}
}
/**
*
* 按照年纪正叙排序
*
*/
public class AgeTypeComparator implements TypeComparator {
@Override
public int comparatorTo(Object object1, Object object2) {
DongWu c1 = (DongWu) object1;
DongWu dw = (DongWu) object2;
if (c1.getAge() > dw.getAge()) {
return 1;
} else if (c1.getAge() < dw.getAge()) {
return -1;
}
return 0;
}
}
public class Cat implements MyComparator,DongWu{
private int age;
private int high;
private TypeComparator typeComparator =new AgeDescTypeComparator();
public Cat(){}
public Cat(int age){
this.age=age;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public int getHigh() {
return high;
}
public void setHigh(int high) {
this.high = high;
}
@Override
public int comparatorTo(Object object) {
DongWu cat = (DongWu) object;
return typeComparator.comparatorTo(this, cat);
}
}
public class Dog implements MyComparator,DongWu{
private int age;
private int high;
private TypeComparator typeComparator =new AgeDescTypeComparator();
public Dog(){}
public Dog(int age){
this.age=age;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public int getHigh() {
return high;
}
public void setHigh(int high) {
this.high = high;
}
@Override
public int comparatorTo(Object object) {
DongWu d = (DongWu) object;
return typeComparator.comparatorTo(this, d);
}
}
public class DataSorter {
public static void sort(MyComparator[] arr){
for (int i = arr.length; i >0 ; i--) {
for(int j=0;j<i-1;j++){
MyComparator m1=arr[j];
MyComparator m2= arr[j+1];
if(m1.comparatorTo(m2)==1){
swap(arr,j,j+1);
}
}
}
}
private static void swap(Object[] arr, int j, int i) {
Object temp =arr[j];
arr[j]=arr[j+1];
arr[j+1]=temp;
}
}
public interface Iterator {
Object next();
boolean hasNext();
}
public interface Collection {
void add(Object data);
int size();
Iterator iterator();
}
//集合
public class MyArrayList implements Collection{
private Object[] array = new Object[10];
private int index=0;//数值当前可以放值的下标
public void add( Object obj){
if(index==array.length){
Object[] newArray = new Object[array.length*2];
System.arraycopy(array, 0, newArray, 0, index);
array=newArray;
}
array[index]=obj;
index++;
}
public int size(){
return index;
}
@Override
public Iterator iterator() {
return new Aaa();
}
private class Aaa implements Iterator{
private int c=0;
@Override
public boolean hasNext() {
if(c<index){
return true;
}else{
return false;
}
}
@Override
public Object next() {
Object object = array[c];
c++;
return object;
}
}
public static void main(String[] args) {
MyArrayList arr = new MyArrayList();
for (int i = 0; i < 20; i++) {
arr.add(new Object());
}
System.out.println(arr.size());
Iterator iterator = arr.iterator();
while(iterator.hasNext()){
System.out.println(iterator.next());
}
}
}
//链表
public class MyNode {
private Object data;
private MyNode nextNode;
public MyNode(Object data,MyNode nextNode){
this.data=data;
this.nextNode=nextNode;
}
public Object getData() {
return data;
}
public void setData(Object data) {
this.data = data;
}
public MyNode getNextNode() {
return nextNode;
}
public void setNextNode(MyNode nextNode) {
this.nextNode = nextNode;
}
}
public class MyLinkTable implements Collection{
private MyNode head;
private MyNode tail;
private int size = 0;
public void add(Object data) {
MyNode n = new MyNode(data, null);
if (head == null) {
head = n;
tail = n;
}
tail.setNextNode(n);
tail = n;
size++;
}
public int size() {
return size;
}
public MyNode getHead() {
return head;
}
public void setHead(MyNode head) {
this.head = head;
}
public MyNode getTail() {
return tail;
}
public void setTail(MyNode tail) {
this.tail = tail;
}
@Override
public Iterator iterator() {
return new Aaa();
}
private class Aaa implements Iterator{
private int c=0;
MyNode node=null;
@Override
public boolean hasNext() {
for (int i = 0; i <=c; i++) {
if(i==0){
node = head;
}else{
node = node.getNextNode();
}
}
if(node==null){
return false;
}else{
return true;
}
}
@Override
public Object next() {
for (int i = 0; i <=c; i++) {
if(i==0){
node = head;
}else{
node = node.getNextNode();
}
}
c++;
return node;
}
}
public static void main(String[] args) {
MyLinkTable node = new MyLinkTable();
node.add(1);
node.add(2);
node.add(3);
Iterator iterator = node.iterator();
while(iterator.hasNext()){
MyNode node1= (MyNode) iterator.next();
System.out.println(node1.getData());
}
}
}
装饰模式指的是在不必改变原类文件和使用继承的情况下,动态地扩展一个对象的功能。它是通过创建一个包装对象,也就是装饰来包裹真实的对象。
public interface ICake {
public float cost();
}
public abstract class CakeDecorator implements ICake{
}
public class MilkCake implements ICake{
@Override
public float cost() {
return 100f;
}
}
public class Berry extends CakeDecorator {
private ICake cake;
public Berry(ICake cake) {
this.cake = cake;
}
@Override
public float cost() {
float berryPrice = 5f;
return cake.cost() + berryPrice;
}
}
public class Chocolate extends CakeDecorator{
private ICake cake;
public Chocolate(ICake cake) {
this.cake = cake;
}
@Override
public float cost() {
float chocolatePrice = 25f;
return cake.cost() + chocolatePrice;
}
}
public class Test {
public static void main(String[] args) throws FileNotFoundException {
MilkCake mc = new MilkCake();
Berry b = new Berry(mc);
Chocolate c = new Chocolate(b);
System.out.println("" + c.cost());
}
}
观察者模式(有时又被称为发布(publish )-订阅(Subscribe)模式、模型-视图(View)模式、源-收听者(Listener)模式或从属者模式)是软件设计模式的一种。在此种模式中,一个目标物件管理所有相依于它的观察者物件,并且在它本身的状态改变时主动发出通知。这通常透过呼叫各观察者所提供的方法来实现。此种模式通常被用来实现事件处理系统。
public interface Observer {
public void update(int low,int heigh,String weather);
void removeSubject();
}
public interface Subject {
public void registerObserver(Observer observer);
public void removeObserver(Observer observer);
public void notifyObserver();
}
public class Android implements Observer{
public Android(){}
private Subject subject;
public Android(Subject subject) {
this.subject = subject;
this.subject.registerObserver(this);
}
@Override
public void update(int low, int heigh, String weather) {
System.out.println("Android" + low + "," + heigh + "," + weather);
}
public void removeSubject() {
subject.removeObserver(this);
}
}
public class IPad implements Observer{
private Subject subject;
public IPad(){}
public IPad(Subject subject) {
this.subject = subject;
subject.registerObserver(this);
}
@Override
public void update(int low, int heigh, String weather) {
System.out.println("IPad " + low + "," + heigh + "," + weather);
}
public void removeSubject() {
subject.removeObserver(this);
}
}
public class WeatherData implements Subject{
private int low;
private int heigh;
private String weather;
private List<Observer> observerList = new ArrayList<Observer>();
public void setData(int low,int heigh,String weather) {
this.low = low;
this.heigh = heigh;
this.weather = weather;
notifyObserver();
}
public int getLow() {
return low;
}
public int getHeigh() {
return heigh;
}
public String getWeather() {
return weather;
}
@Override
public void registerObserver(Observer observer) {
if(!observerList.contains(observer)) {
observerList.add(observer);
}
}
@Override
public void removeObserver(Observer observer) {
if(observerList.contains(observer)) {
observerList.remove(observer);
}
}
@Override
public void notifyObserver() {
for(Observer o : observerList) {
o.update(getLow(), getHeigh(), getWeather());
}
}
}
public class Test {
public static void main(String[] args) {
WeatherData wd = new WeatherData();
Android android = new Android(wd);
//android.removeSubject();
IPad ipad = new IPad(wd);
//ipad.removeSubject();
wd.setData(2, 23, "---");
}
}
public interface Filter {
void doFilter(Request request, Response response, FilterChain chain);
}
public class FilterChain implements Filter {
List<Filter> filters = new ArrayList<Filter>();
int index = 0;
public FilterChain addFilter(Filter f) {
this.filters.add(f);
return this;
}
@Override
public void doFilter(Request request, Response response, FilterChain chain) {
if(index == filters.size()) return ;
Filter f = filters.get(index);
index ++;
f.doFilter(request, response, chain);
}
}
public class HTMLFilter implements Filter {
@Override
public void doFilter(Request request, Response response, FilterChain chain) {
//process the html tag <>
request.requestStr = request.requestStr.replace('<', '[')
.replace('>', ']') + "---HTMLFilter()";
chain.doFilter(request, response, chain);
response.responseStr += "---HTMLFilter()";
}
}
public class SesitiveFilter implements Filter {
@Override
public void doFilter(Request request, Response response, FilterChain chain) {
request.requestStr = request.requestStr.replace("", "")
.replace("", "") + "---SesitiveFilter()";
chain.doFilter(request, response, chain);
response.responseStr += "---SesitiveFilter()";
}
}
public class Request {
String requestStr;
public String getRequestStr() {
return requestStr;
}
public void setRequestStr(String requestStr) {
this.requestStr = requestStr;
}
}
public class Response {
String responseStr;
public String getResponseStr() {
return responseStr;
}
public void setResponseStr(String responseStr) {
this.responseStr = responseStr;
}
}
public class Main {
/**
* @param args
*/
public static void main(String[] args) {
String msg = "";
Request request = new Request();
request.setRequestStr(msg);
Response response = new Response();
response.setResponseStr("response");
FilterChain fc = new FilterChain();
fc.addFilter(new HTMLFilter())
.addFilter(new SesitiveFilter())
;
fc.doFilter(request, response, fc);
System.out.println(request.getRequestStr());
System.out.println(response.getResponseStr());
}
}
单例模式分为恶汉式,就是直接在类中new出,直接返回对象,懒汉式是在调用对象时判断对象是否是null,如果null,先new出,再返回,否则直接返回对象,但是这种方式会线程不安全,所以采用双重检查的设计思想,保证线程安全。
package singleton;
public class Teacher3 {
private Teacher3(){}
private static Teacher3 t=null;
public static Teacher3 getTeacher3(){
if(t==null){
synchronized (Teacher3.class) {
if(t==null){
t=new Teacher3();
}
}
}
return t;
}
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
第二种方式,内部类方式
package test;
/**
* 在多线程中使用单例对象的设计模式,内部类
*
*/
public class InnerSingleton {
private static class Singleton{
private static Singleton s=new Singleton();
public void add(){
}
}
public static Singleton getSingleton(){
return Singleton.s;
}
public static void main(String[] args) {
Singleton singleton = InnerSingleton.getSingleton();
singleton.add();
}
}
具体的水果工厂实现类 | 具体的苹果实现类 | 具体的香蕉实现类 | 具体的枣实现类 |
中国水果工厂实现类 | 中国苹果 | 中国香蕉 | 中国枣 |
日本水果工厂实现类 | 日本苹果 | 日本香蕉 | 日本枣 |
以此类推,在工厂的接口中创建所有水果的方法声明。
public interface IFruit {
public void get();
}
public abstract class AbstractApple implements IFruit{
public abstract void get();
}
public abstract class AbstractBanana implements IFruit{
public abstract void get();
}
public interface IFruitFactory {
public IFruit getApple();
public IFruit getBanana();
}
public class NorthApple extends AbstractApple {
public void get() {
System.out.println("北方苹果");
}
}
public class NorthBanana extends AbstractBanana {
public void get() {
System.out.println("北方香蕉");
}
}
public class NorthFruitFactory implements IFruitFactory {
public IFruit getApple() {
return new NorthApple();
}
public IFruit getBanana() {
return new NorthBanana();
}
}
public class SouthApple extends AbstractApple {
public void get() {
System.out.println("南方苹果");
}
}
public class SouthBanana extends AbstractBanana {
public void get() {
System.out.println("南方香蕉");
}
}
public class SouthFruitFactory implements IFruitFactory {
public IFruit getApple() {
return new SouthApple();
}
public IFruit getBanana() {
return new SouthBanana();
}
}
package methodFactory;
public interface People {
void say();
}
package methodFactory;
public class Man implements People{
public void say() {
System.out.println("男人");
}
}
package methodFactory;
public class Woman implements People{
public void say() {
System.out.println("女人");
}
}
package methodFactory;
public interface PeopleFactory {
People create();
}
package methodFactory;
public class ManFactory implements PeopleFactory{
public People create() {
return new Man();
}
}
package methodFactory;
public class WomanFactory implements PeopleFactory{
public People create() {
return new Woman();
}
}
package methodFactory;
public class Test {
public static void main(String[] args) {
PeopleFactory manf= new ManFactory();
People man = manf.create();
man.say();
PeopleFactory wf= new WomanFactory();
People w = wf.create();
w.say();
}
}
好处是新增加的子类不会影响以前的实现,代码的扩展性好。
package simpleFactory;
public interface People {
void say();
}
package simpleFactory;
public class Man implements People{
public void say() {
System.out.println("男人");
}
}
package simpleFactory;
public class Woman implements People{
public void say() {
System.out.println("女人");
}
}
package simpleFactory;
public class SimpleFactory {
public static People create(String className) throws ClassNotFoundException, InstantiationException, IllegalAccessException{
Class class1 = Class.forName(className);
return (People) class1.newInstance();
}
}
package simpleFactory;
public class Test {
public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException {
People man = SimpleFactory.create("simpleFactory.Man");
People woman = SimpleFactory.create("simpleFactory.Woman");
man.say();
woman.say();
}
}
/**
* 处理接收任务
*/
@Test
public void test4(){
String executionId = "2101";
pe.getRuntimeService().signal(executionId );
}
由于接收任务在任务表中没有任务,所有可以传递流程实例的ID或者执行ID处理接收任务。
package com.task.group;
import java.util.List;
import org.activiti.engine.ProcessEngine;
import org.activiti.engine.ProcessEngineConfiguration;
import org.activiti.engine.repository.Deployment;
import org.activiti.engine.repository.DeploymentBuilder;
import org.activiti.engine.task.Task;
import org.activiti.engine.task.TaskQuery;
import org.junit.Test;
/**
* 公共任务测试
*
*
*/
public class GroupTaskTest {
static ProcessEngine pe =null;
static{
ProcessEngineConfiguration conf = ProcessEngineConfiguration.
createStandaloneProcessEngineConfiguration();
conf.setJdbcDriver("com.mysql.jdbc.Driver");
conf.setJdbcUrl("jdbc:mysql://localhost:3306/activiti02?useUnicode=true&characterEncoding=UTF-8");
conf.setJdbcUsername("root");
conf.setJdbcPassword("root");
conf.setDatabaseSchemaUpdate("true");
pe = conf.buildProcessEngine();
}
/**
* 部署流程定义
*/
@Test
public void test1() {
DeploymentBuilder deploymentBuilder = pe.getRepositoryService()
.createDeployment();
deploymentBuilder
.addClasspathResource("com/task/group/groupTask.bpmn");
deploymentBuilder .addClasspathResource("com/task/group/groupTask.png");
Deployment deployment = deploymentBuilder.deploy();
}
/**
* 启动流程实例
*/
@Test
public void test2(){
String processDefinitionId = "grouptTask:1:7404";
pe.getRuntimeService().startProcessInstanceById(processDefinitionId);
}
/**
* 办理个人任务
*/
@Test
public void test3(){
String taskId = "7504";
pe.getTaskService().complete(taskId);
}
/**
* 查询公共任务列表
*/
@Test
public void test4(){
TaskQuery query = pe.getTaskService().createTaskQuery();
String candidateUser = "王五";
//根据候选人过滤
query.taskCandidateUser(candidateUser);
List<Task> list = query.list();
for (Task task : list) {
System.out.println(task.getName());
}
}
/**
* 拾取任务(将公共任务变为个人任务)
*/
@Test
public void test5(){
String taskId = "7602";
String userId = "王五";
pe.getTaskService().claim(taskId , userId);
}
/**
* 退回任务(将个人任务变为公共任务)
*/
@Test
public void test6(){
String taskId = "1602";
pe.getTaskService().setAssignee(taskId , null);
}
}
/**
* RuntimeService得到流程变量
*/
@org.junit.Test
public void testRuntimeServiceGetVar(){
String executionId="5701";
Map<String, Object> variables = processEngine.getRuntimeService().getVariables(executionId);
}
/**
* taskService得到流程变量
*/
@org.junit.Test
public void testTaskServiceGetVar(){
String taskId="5804";
Map<String, Object> variables = processEngine.getTaskService().getVariables(taskId);
}
/**
* 在启动流程实例时设置流程变量
*/
@org.junit.Test
public void testStartProcessInstanceByKey(){
String processDefinitionKey="qjlc";
Map<String,Object> variables = new HashMap<String, Object>();
variables.put("k1", 11);
variables.put("k2", 22);
ProcessInstance query = processEngine.getRuntimeService().startProcessInstanceByKey(processDefinitionKey, variables);
}
/**
* 在办理任务时设置流程变量
*/
@org.junit.Test
public void testTaskComplete(){
String taskId="6002";
Map<String,Object> variables = new HashMap<String, Object>();
variables.put("k3", 11);
variables.put("k4", 22);
processEngine.getTaskService().complete(taskId, variables);
}
/**
* RuntimeService设置流程变量
*/
@org.junit.Test
public void testRuntimeService(){
String executionId="5701";
Map<String,Object> variables = new HashMap<String, Object>();
variables.put("k5", 3);
variables.put("k6", 4);
processEngine.getRuntimeService().setVariables(executionId, variables);
}
/**
* taskService设置流程变量
*/
@org.junit.Test
public void testTaskService(){
String taskId="5804";
Map<String,Object> variables = new HashMap<String, Object>();
variables.put("k5", 31);
variables.put("k6", 41);
processEngine.getTaskService().setVariables(taskId, variables);
}
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
public class CallAbleTest {
public static void main(String[] args) throws InterruptedException, ExecutionException {
ExecutorService service = Executors.newFixedThreadPool(2);
MyCallAbled m1= new MyCallAbled("aa");
MyCallAbled m2= new MyCallAbled("bb");
Future future1 = service.submit(m1);
Future future2 =service.submit(m2);
System.out.println(future1.get().toString());
System.out.println(future2.get().toString());
service.shutdown();
}
static class MyCallAbled implements Callable{
private String name;
public MyCallAbled(String name){
this.name=name;
}
public MyCallAbled(){
}
@Override
public Object call() throws Exception {
return name;
}
}
}
Java的动态代理是为了拦截目标方法,例子:
public interface Person {
String sing(String name);
String dance(String name);
}
public class Liyuchun implements Person {
public String sing(String name){
System.out.println("唱" + name +"歌");
return "唱" + name +"歌";
}
public String dance(String name){
System.out.println("跳"+name+"舞");
return "跳"+name+"舞";
}
}
public class LiyuchunProxy {
private Person person ;
public Person createProxy(Person p){
this.person=p;
return (Person) Proxy.newProxyInstance(LiyuchunProxy.class.getClassLoader(), person.getClass().getInterfaces(), new InvocationHandler(){
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
String methodName = method.getName();
if(methodName.equals("sing")){
return method.invoke(person, args);
}else if(methodName.equals("dance")){
return method.invoke(person, args);
}else{
System.out.println("不支持");
return null;
}
}
});
}
}
public class ProxyTest {
public static void main(String[] args) {
Liyuchun cun = new Liyuchun();
LiyuchunProxy liyuchunProxy = new LiyuchunProxy();
Person person = liyuchunProxy.createProxy(cun);
String result = person.dance("机械");
System.out.println(result);
}
}
public class Bean1 {
private String a;
private String b;
private String time;
public String getA() {
return a;
}
public void setA(String a) {
this.a = a;
}
public String getB() {
return b;
}
public void setB(String b) {
this.b = b;
}
public String getTime() {
return time;
}
public void setTime(String time) {
this.time = time;
}
}
public class Bean2 {
private int a;
private String b;
private Date time;
public int getA() {
return a;
}
public void setA(int a) {
this.a = a;
}
public String getB() {
return b;
}
public void setB(String b) {
this.b = b;
}
public Date getTime() {
return time;
}
public void setTime(Date time) {
this.time = time;
}
}
import java.lang.reflect.InvocationTargetException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.beanutils.ConvertUtils;
import org.apache.commons.beanutils.Converter;
public class Test {
public static void main(String[] args) throws IllegalAccessException, InvocationTargetException {
Bean1 bean1 = new Bean1();
bean1.setA("22");
bean1.setB("fff");
bean1.setTime("2017-01-22 11:11:11");
Bean2 bean2 = new Bean2();
resp();
BeanUtils.copyProperties(bean2, bean1);
System.out.println(bean2.getA());
System.out.println(bean2.getB());
System.out.println(bean2.getTime());
}
private static void resp() {
ConvertUtils.register(new Converter() {
@Override
public Object convert(Class arg0, Object value) {
if(value != null &&!"".equals(value.toString())){
String v=value.toString();
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd hh:MM:ss");
try {
return sdf.parse(v);
} catch (ParseException e) {
e.printStackTrace();
}
}
return null;
}
}, Date.class);
}
}
当一个不在spring容器中的一个类,需要用到事务,这时需要调用spring容器中的其他类来实现事务。比如:
在类中使用context.getBean("aService");得到服务类,此服务类含有事务。
1、配置spring文件:
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">
<!--
读取配置文件
-->
<bean
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<value>classpath:jdbc.properties</value>
</property>
</bean>
<bean id="dataSource" destroy-method="close"
class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName" value="${jdbc.driverClassName}" />
<property name="url" value="${jdbc.url}" />
<property name="username" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
</bean>
<bean id="classesDao" class="cn.itheima03.spring.jdbc.ClassesDaoImpl">
<property name="dataSource">
<ref bean="dataSource"/>
</property>
</bean>
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<constructor-arg index="0" ref="dataSource"></constructor-arg>
</bean>
<bean id="classesDao2" class="cn.itheima03.spring.jdbc.ClassesDaoImpl2">
<property name="jdbcTemplate">
<ref bean="jdbcTemplate"/>
</property>
</bean>
<bean id="itheimaTemplate" class="cn.itheima03.spring.itheima03db.ItHeimaTemplate">
<constructor-arg index="0" ref="dataSource"></constructor-arg>
</bean>
<bean id="classesDao4" class="cn.itheima03.spring.itheima03db.ClassesDaoImpl4">
<constructor-arg index="0" ref="dataSource"></constructor-arg>
</bean>
<bean id="classesDao3" class="cn.itheima03.spring.jdbc.ClassesDaoImpl3">
<constructor-arg index="0" ref="dataSource"></constructor-arg>
</bean>
</beans>
2、第一种方式:
public class ClassesDaoImpl extends JdbcDaoSupport implements ClassesDao{
public void saveClasses() {
this.getJdbcTemplate().execute("insert into classes(cname,description) values('a','a')");
}
@Override
public List<Classes> getClasses() {
// TODO Auto-generated method stub
return this.getJdbcTemplate().query("select * from classes", new ClassesRowMapper());
}
}
3、第二种方式:
public class ClassesDaoImpl2 implements ClassesDao{
private JdbcTemplate jdbcTemplate;
public JdbcTemplate getJdbcTemplate() {
return jdbcTemplate;
}
public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
this.jdbcTemplate = jdbcTemplate;
}
public void saveClasses() {
// TODO Auto-generated method stub
this.jdbcTemplate.execute("insert into classes(cname,description) values('a','a')");
}
@Override
public List<Classes> getClasses() {
// TODO Auto-generated method stub
return null;
}
}
4.第三种方式:
public class ClassesDaoImpl3 extends JdbcTemplate implements ClassesDao{
public ClassesDaoImpl3(DataSource dataSource){
super(dataSource);
}
public void saveClasses() {
this.execute("insert into classes(cname,description) values('a','a')");
}
@Override
public List<Classes> getClasses() {
return null;
}
}
5、自定义数据库操作类:
public class ItHeimaTemplate {
private DataSource dataSource;
public DataSource getDataSource() {
return dataSource;
}
public void setDataSource(DataSource dataSource) {
this.dataSource = dataSource;
}
public ItHeimaTemplate(){}
public ItHeimaTemplate(DataSource dataSource){
this.dataSource = dataSource;
}
public void insert(String sql){
try {
Connection conn = this.dataSource.getConnection();
Statement statement = conn.createStatement();
statement.executeUpdate(sql);
} catch (Exception e) {
}
}
}
public class ClassesDaoImpl4 extends ItHeimaTemplate{
public ClassesDaoImpl4(DataSource dataSource){
super(dataSource);
}
public void insert(){
this.insert("insert into classes(cname,description) values('a','a')");
}
}
$().ready(function(){
for (var i = 0; i < 300; i++) {
$("input[type='button']").unbind("click");
$("input[type='button']").bind("click",function(){
/**
* 触发自定义的事件
*/
$(this).trigger("杨军威",{
a:5,
b:6
});
});
}
$("input[type='button']").unbind("杨军威");
$("input[type='button']").bind("杨军威",function(event,json){
alert(json.a+json.b);
});
});
/**
* 自定义事件
* 1、自定义一个事件,该事件的名称为"云三很牛"
* 2、把该事件绑定在button上
* 3、该事件在点击button的时候触发
*/
1、session有缓存功能,但是当session关闭后,缓存消失。
2.二级缓存是sessionfactory级别的,当hibernate容器启动后,
二级缓存就存在了,当hibernate关闭后,二级缓存消失。
hibernate本身对于二级缓存是关闭的,而且没有实现二级缓存的机制。
在hibernate.cfg.xml文件中配置:
<!-- 启用二级缓存 --><property name="hibernate.cache.use_second_level_cache">true</property><property name="hibernate.cache.use_query_cache">true</property><!-- 配置缓存提供商 --><property name="hibernate.cache.provider_class">org.hibernate.cache.EhCacheProvider</property>
在实体类中配置
<class-cache class="com.nacosoft.pda.user.PdaUser" usage="read-write" />
如果想开启集合的二级缓存,需要开启针对集合类的二级缓存。
如果二级缓存的数据量大,可以在src目录下新建ehcache.xml文件,把数据缓存在磁盘上。
3.查询缓存:在二级缓存的基础上,在代码里写:
Query query = session.createQuery("from Person");
query.setCacheable(true);
List list = query.list();
就可以使用查询缓存了
1、sessionFactory.openSession(),只要调用此方法,就会产生一个新的session。
2、sessionFactory.getCurrentSession()产生session的逻辑是:
先判断当前线程中有无session,如果没有,调用sessionFactory.openSession()产生新的session,
并放入到当前线程中。如果session存在,直接取当前线程中的session,当使用此方法产生的session时,
crud操作必须在事务中进行,并且不用关闭session。
jdbc的缺点:
1.代码太繁琐,2、不是面向对象的数据库操作。
3、资源关闭的代码繁琐,每次都需要打开和关闭。
4、没有数据缓存。5、数据库移植性差。
优点:是最底层的操作,所以效率高。
hibernate优点:
1、代码精简、2、是面向对象的数据库操作
3.只需要关闭一个session对象就可以了
4.数据有缓存,一级缓存和二级缓存用于查询缓存
5.都是面向对象操作,数据库移植性好。
缺点:1、程序无法控制sql的生成,如果系统重视对sql优化,不适合用hibernate。
2、如果单表数据量超过一千万,不适合用hibernate
前端传递json数据,配置第一种方法
<!-- media type -->
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-moxy</artifactId>
<version>${jersey.version}</version>
</dependency>
@ApplicationPath("/webapi/*")
public class AirResourceConfig extends ResourceConfig {
public AirResourceConfig() {
// packages("com.example.resource");
register(BookResource.class);
}
}
前端传递json数据,配置第二种方法
<!-- media type -->
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-json-jackson</artifactId>
<version>${jersey.version}</version>
</dependency>
@ApplicationPath("/api/*")
public class JsonResourceConfig extends ResourceConfig {
public JsonResourceConfig() {
register(BookResource.class);
register(JacksonFeature.class);
register(JsonContextProvider.class);
}
}
@Provider
public class JsonContextProvider implements ContextResolver<ObjectMapper> {
final ObjectMapper d;
final ObjectMapper c;
public JsonContextProvider() {
d = createDefaultMapper();
c = createCombinedMapper();
}
private static ObjectMapper createCombinedMapper() {
Pair ps = createIntrospector();
ObjectMapper result = new ObjectMapper();
//result.configure(Feature.WRAP_ROOT_VALUE, true);
//result.configure(DeserializationConfig.Feature.UNWRAP_ROOT_VALUE, true);
result.setDeserializationConfig(result.getDeserializationConfig().withAnnotationIntrospector(ps));
result.setSerializationConfig(result.getSerializationConfig().withAnnotationIntrospector(ps));
return result;
}
private static ObjectMapper createDefaultMapper() {
ObjectMapper result = new ObjectMapper();
result.configure(Feature.INDENT_OUTPUT, true);
return result;
}
private static Pair createIntrospector() {
AnnotationIntrospector p = new JacksonAnnotationIntrospector();
AnnotationIntrospector s = new JaxbAnnotationIntrospector();
return new Pair(p, s);
}
@Override
public ObjectMapper getContext(Class<?> type) {
if (type == JsonHybridBook.class) {
return c;
} else {
return d;
}
}
}
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
public class Test {
private static Iterator<String> iterator;
public static void main(String[] args) {
List<String> list = new ArrayList<String>();
list.add("1");
list.add("2");
iterator = list.iterator();
while (iterator.hasNext()) {
String next = iterator.next();
if("1".equals(next)){
list.remove(next);
}
}
for(String s : list){
System.out.println(s);
}
}
}
jersey容器发布web应用不需要web.xml的开发。
1.新建容器扫描类
package com.example;
import javax.servlet.annotation.WebInitParam;
import javax.servlet.annotation.WebServlet;
import org.glassfish.jersey.servlet.ServletContainer;
@WebServlet(
initParams = @WebInitParam(name = "jersey.config.server.provider.packages", value = "com.example"),
urlPatterns = "/webapi/*",
loadOnStartup = 1)
public class AirServlet extends ServletContainer {
private static final long serialVersionUID = 1L;
}
在com.example包中的资源服务类都可以访问到
jersey不用添加扫描包,自动扫描资源服务类。
在web.xml文件中添加
<servlet>
<servlet-name>javax.ws.rs.core.Application</servlet-name>
</servlet>
<servlet-mapping>
<servlet-name>javax.ws.rs.core.Application</servlet-name>
<url-pattern>/webapi/*</url-pattern>
</servlet-mapping>
这样可以自动扫描所有的资源服务类
在使用jersey中,web.xml文件也可以不用。
1、新建jersey容器类
package com.example;
import javax.ws.rs.ApplicationPath;
import org.glassfish.jersey.server.ResourceConfig;
@ApplicationPath("/webapi/*")
public class AirResourceConfig extends ResourceConfig {
public AirResourceConfig() {
packages("com.example");
}
}
或者
package com.example;
import java.util.HashSet;
import java.util.Set;
import javax.ws.rs.ApplicationPath;
import javax.ws.rs.core.Application;
@ApplicationPath("/webapi/*")
public class AirApplication extends Application {
@Override
public Set<Class<?>> getClasses() {
final Set<Class<?>> classes = new HashSet<Class<?>>();
classes.add(MyResource.class);
return classes;
}
}
把所有的资源服务类加入到set中
@ApplicationPath定义了访问的地址,packages("com.example");定义了扫描的资源服务类的包
1、先在pom.xml文件中添加依赖:
<dependency>
<groupId>org.glassfish.jersey.containers</groupId>
<artifactId>jersey-container-servlet-core</artifactId>
</dependency>
</dependencies>
2、在web.xml中添加jersey类
<servlet>
<servlet-name>Jersey Web Application</servlet-name>
<servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
<init-param>
<param-name>javax.ws.rs.Application</param-name>
<param-value>com.example.AirApplication</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>Jersey Web Application</servlet-name>
<url-pattern>/webapi/*</url-pattern>
</servlet-mapping>
其中com.example.AirApplication类扫描所有的对外服务类
3、新建对外服务类
package com.example;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
/**
* Root resource (exposed at "myresource" path)
*/
@Path("myresource1")
public class MyResource1 {
@GET
@Produces(MediaType.TEXT_PLAIN)
public String getIt() {
return "Got it222!";
}
}
package com.example;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
/**
* Root resource (exposed at "myresource1" path)
*/
@Path("myresource1")
public class MyResource1 {
@GET
@Produces(MediaType.TEXT_PLAIN)
public String getIt() {
return "Got it222!";
}
}
4、在AirApplication类中扫描服务类
package com.example;
import java.util.HashSet;
import java.util.Set;
import javax.ws.rs.core.Application;
public class AirApplication extends Application {
@Override
public Set<Class<?>> getClasses() {
final Set<Class<?>> classes = new HashSet<Class<?>>();
classes.add(MyResource.class);
classes.add(MyResource1.class);
return classes;
}
}
这样在tomcat中启动就可以访问资源类中的方法。
1.新建一个实体类
package com.example.domain;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlRootElement;
@XmlRootElement(name = "device")
public class Device {
private String deviceIp;
private int deviceStatus;
public Device() {
}
public Device(String deviceIp) {
super();
this.deviceIp = deviceIp;
}
@XmlAttribute
public String getIp() {
return deviceIp;
}
public void setIp(String deviceIp) {
this.deviceIp = deviceIp;
}
@XmlAttribute
public int getStatus() {
return deviceStatus;
}
public void setStatus(int deviceStatus) {
this.deviceStatus = deviceStatus;
}
}
其中@XmlRootElement(name = "device")代表xml文件的根节点
@XmlAttribute代表xml文件的属性节点
在pom.xml文件中依赖下面2包
<dependencies>
<dependency>
<groupId>org.glassfish.jersey.containers</groupId>
<artifactId>jersey-container-grizzly2-http</artifactId>
</dependency>
<!-- get JSON support: -->
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-moxy</artifactId>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.9</version>
<scope>test</scope>
</dependency>
</dependencies>
在服务类中编写
package com.example;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import com.example.domain.Device;
@Path("myresource")
public class MyResource {
@GET
@Produces({ MediaType.APPLICATION_JSON })
public Device getIt() {
Device d=new Device("1.1.1.1");
d.setStatus(2);
return d;
}
}
建立测试类:
package com.example;
import java.io.IOException;
import java.net.URI;
import org.glassfish.grizzly.http.server.HttpServer;
import org.glassfish.jersey.grizzly2.httpserver.GrizzlyHttpServerFactory;
import org.glassfish.jersey.server.ResourceConfig;
public class Main {
public static final String BASE_URI = "http://localhost:8080/myapp/";
public static HttpServer startServer() {
final ResourceConfig rc = new ResourceConfig().packages("com.example");
return GrizzlyHttpServerFactory.createHttpServer(URI.create(Main.BASE_URI), rc);
}
public static void main(String[] args) throws IOException {
final HttpServer server = Main.startServer();
}
}
启动后在浏览器中输入http://localhost:8080/myapp/myresource,页面返回
{"ip":"1.1.1.1","status":2}
返回json格式的数据。
根据流程定义中的pdkey-->查询出所有的流程定义--》根据流程定义中的DeploymentId删除流程部署
String url="http://localhost:8984/axis/HelloWs.jws";//服务地址
Service s = new Service();
Call call = s.createCall();
call.setTargetEndpointAddress(url);
call.setOperationName(new QName(url, "getH"));//调用的服务端方法名称
Object invoke = call.invoke(new Object[]{"a"});//传递的参数
System.out.println(invoke);
1、创建自己的handler类实现SOAPHandler接口,实现里面的方法。
2、新增handler-chain.xml文件,
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<javaee:handler-chains
xmlns:javaee="http://java.sun.com/xml/ns/javaee"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<javaee:handler-chain>
<javaee:handler>
<javaee:handler-class>com.ws.MsgHandler</javaee:handler-class>
</javaee:handler>
</javaee:handler-chain>
</javaee:handler-chains>
3、在webservice实现类中添加文件的地址 @HandlerChain(file="handler-chain.xml")
4、
wsimport -d [目录] -keep -verbose [wsdl地址]
session是在服务端开辟的一块内存,有唯一的sessionid,如果客户端没有禁用cookie,sessionid就保存在客户端的cookie中;如果客户端禁用了cookie,客户端的url后面就跟上;jsessionid=111。来想服务器传递sessionid,可以保证sessionid不变。
/**
* Created by Administrator on 2017/3/24.
*/
var extend=function (c,f) {
c.prototype=f.prototype;
}
var f=function () {
this.a='aa';
}
f.prototype={
say:function () {
alert('f');
}
}
var c=function () {
this.b='aa';
}
extend(c,f);//只能继承prototype实现的方法
var c1=new c();
c1.say();
Ext.namespace('com.ext');
com.ext.First=function () {
var kiss='中国';
}
com.ext.First.prototype={
init:function () {
alert('init');
alert('kiss');
},
method:function () {
alert('method');
}
}
//var f=new com.ext.First();
//f.method();
com.ext.Second=function () {
}
Ext.extend(com.ext.Second,com.ext.First,{
method:function () {
alert('method2');
},
fun:function () {
alert('fun');
}
});
var s=new com.ext.Second();
s.method();
s.fun();
Student=function (config) {
this.a='3';
Ext.apply(this,config);
}
var st=new Student({a:'1',b:'2'});
alert(st.a);
Student1=function (config) {
this.a='3';
Ext.applyIf(this,config);
}
var st=new Student1({a:'1',b:'2'});
alert(st.a);
/**apply方法覆盖所有的属性
* applyIf不覆盖属性
*
*/
1.准备jar包将ik的jar包、pinyin4j-2.5.0.jar、solr-4.9.0\contrib\analysis-extras\lucene-libs\lucene-analyzers-smartcn-4.9.0.jar拷贝到%TOMCAT_HOME%\webapps\solr\WEB-INF\lib下
2.修改schema.xml<fieldType name="text_pinyin" class="solr.TextField" positionIncrementGap="0">
<analyzer type="index">
<tokenizer class="org.apache.lucene.analysis.cn.smart.SmartChineseSentenceTokenizerFactory"/>
<filter class="org.apache.lucene.analysis.cn.smart.SmartChineseWordTokenFilterFactory"/>
</analyzer>
<analyzer type="query">
<tokenizer class="org.apache.lucene.analysis.cn.smart.SmartChineseSentenceTokenizerFactory"/>
<filter class="org.apache.lucene.analysis.cn.smart.SmartChineseWordTokenFilterFactory"/>
</analyzer>
</fieldType>
<fieldType name="text_smartcn" class="solr.TextField" positionIncrementGap="0">
<analyzer type="index">
<tokenizer class="org.apache.lucene.analysis.cn.smart.SmartChineseSentenceTokenizerFactory"/>
<filter class="org.apache.lucene.analysis.cn.smart.SmartChineseWordTokenFilterFactory"/>
</analyzer>
<analyzer type="query">
<tokenizer class="org.apache.lucene.analysis.cn.smart.SmartChineseSentenceTokenizerFactory"/>
<filter class="org.apache.lucene.analysis.cn.smart.SmartChineseWordTokenFilterFactory"/>
</analyzer>
</fieldType>
3.需要拼音分词的字段使用这些fieldType
4.在搜索字段时配上这些拼音字段
参与权重的查询字段最好是可以进行分词配置过的,
例子程序:
//权重
query.set("defType","dismax");
query.set("qf","username^10000 zgxltext^10000 usernameSpell^10000 id^10000 email^10000 jgtext^10000 xueweitext^10000 zhiweitext^10000 sextext^10000 zhijitext^10000 companytext^10000 zuzhitext^10000 companysubtext^10000 sbfamily^1 sbharvest^1 sbproject^1 sbteach^1 sbwaiyu^1 sbwork^1 sbzhiCheng^1 ");
//高亮
query.setHighlight(true);
query.setParam("hl", "true"); //highlighting
query.setParam("hl.fl", "username id email jgtext xueweitext zhiweitext sextext zhijitext companytext zuzhitext companysubtext zgxltext");
query.setHighlightSimplePre("<font color=\'red\'>");
query.setHighlightSimplePost("</font>");
query.setHighlightFragsize(200);
query.setHighlightSnippets(3);
List<SPEntity> lpojo = response.getBeans(SPEntity.class);
Map<String, Map<String, List<String>>> highlighting = response.getHighlighting();
List<String> list2 =null;
//
if (lpojo != null && lpojo.size()>0 && highlighting != null){
for(SPEntity sp : lpojo){
Map<String, List<String>> map = highlighting.get(sp.getId());
list2 = map.get("username");
if (list2 != null && list2.size()>0){
sp.setUsername(list2.get(0));
}
list2 = map.get("id");
if (list2 != null && list2.size()>0){
sp.setId(list2.get(0));
}
list2 = map.get("email");
if (list2 != null && list2.size()>0){
sp.setEmail(list2.get(0));
}
list2 = map.get("jgtext");
if (list2 != null && list2.size()>0){
sp.setJgtext(list2.get(0));
}
list2 = map.get("xueweitext");
if (list2 != null && list2.size()>0){
sp.setXueweitext(list2.get(0));
}
list2 = map.get("zhiweitext");
if (list2 != null && list2.size()>0){
sp.setZhiweitext(list2.get(0));
}
list2 = map.get("sextext");
if (list2 != null && list2.size()>0){
sp.setSextext(list2.get(0));
}
list2 = map.get("zhijitext");
if (list2 != null && list2.size()>0){
sp.setZhijitext(list2.get(0));
}
list2 = map.get("companytext");
if (list2 != null && list2.size()>0){
sp.setCompanytext(list2.get(0));
}
list2 = map.get("zuzhitext");
if (list2 != null && list2.size()>0){
sp.setZuzhitext(list2.get(0));
}
list2 = map.get("companysubtext");
if (list2 != null && list2.size()>0){
sp.setCompanysubtext(list2.get(0));
}
list2 = map.get("zgxltext");//
if (list2 != null && list2.size()>0){
sp.setZgxltext(list2.get(0));
}
}
}
客户端系统js代码:
<script type="text/javascript">
function test(a){
alert(a.name);
return a;
}
$.ajax({
url:'http://ip:8090/mobile/test.json?method=test',
type:'POST', //GET
async:true, //或false,是否异步
data:{
// name:'yang',age:25
},
timeout:5000, //超时时间
dataType:'jsonp', //返回的数据格式:json/xml/html/script/jsonp/text
beforeSend:function(xhr){
},
success:function(data,textStatus,jqXHR){
},
error:function(xhr,textStatus){
},
complete:function(){
}
})
</script>
服务端系统代码:
test({name:'yang',age:25});
客户端访问跨域系统时,传递客户端需要执行的方法名,服务端在查询出数据后,使用传递的方法名封装成js方法的执行返回,客户端程序就直接执行此方法。
springmvc后台例子,返回jsonp数据代码
//第一种字符串返回jsonp格式数据
@RequestMapping(value="/get/{method}",produces=MediaType.APPLICATION_JSON_VALUE+";charset=utf-8")
@ResponseBody
public String getUser(@PathVariable String method) {
User user = userService.selectByPrimaryKey(1);
Gson gson = new Gson();
String userJson = gson.toJson(user);
return method+"("+userJson+")";
}
//第二种对象返回jsonp格式数据
spring版本4.1以上
@RequestMapping("/gett/{method}")
@ResponseBody
public Object gett(@PathVariable String method) {
User user = userService.selectByPrimaryKey(1);
MappingJacksonValue mjv = new MappingJacksonValue(user);
mjv.setJsonpFunction(method);
return mjv;
}
spring容器是父容器,包含的对象有dao,service等
springmvc容器是子容器,包括controller
子容器可以访问父容器的 对象,但是子容器不可以访问父容器的属性。
父容器不能访问子容器的对象。
例如,controller可以访问service,但是service不能访问controller。
upstream project
{
server 127.0.0.1:8080 weight=3; tomcat地址
server 127.0.0.1:8082; tomcat地址
}
server {
listen 80; 发布的访问地址的端口
server_name test.tt.com; 发布的访问地址
location / {
proxy_pass http://project;
index index.html index.htm;
}
}
1、mvn compile 编译源代码
2、mvn test 执行所有的测试类方法
3、mvn clean 清除class
4、mvn package 打包
5、mvn install 安装到本地仓库中
6、 mvn archetype:generate -DgroupId=com.aaa.bbb -DartifactId=ccc-bbb -Dversion=0.0.1-SNAPSHOT 新建项目
7、<dependency>
<groupId></groupId>
<artifactId></artifactId>
<version></version>
<scope>compile</scope>编译和打包的时候会依赖(这个属性是默认的)
<scope>provided</scope>编译和测试的时候依赖,打包的时候不依赖,例如servlet-api,打包的时候tomcat中有,会冲突,所有不打包,但是编译和测试的时候需要这个jar。
<scope>test</scope> 在测试范围有效,在编译和打包的时候不会使用这个依赖。并且不会传递依赖,例如,其他项目依赖此包时,此jar不会被传递依赖。
<scope>runtime</scope> 在运行的时候依赖,在编译的时候不依赖。
</dependency>
8、a-->直接依赖jar1.1 , b-->直接依赖jar1.2 , c-->直接依赖a,b ,c先依赖a,后依赖b,所以a依赖jar1.1版本
9、当依赖级别相同的时候,先依赖谁,就用它,当依赖级别不同的时候,用依赖级别短的依赖。
10、<exclusions>
<exclusion>
</exclusion>
</exclusions>
的意思是说不使用此jar依赖的某个jar包,可以解决jar冲突的问题。
11、继承的绝对路径是pom文件,聚合的是模块的位置。
1.下载oracle jar包,放在计算机用户目录下,例如C:\Users\Administrator目录下。
2.在cmd下执行
mvn install:install-file -DgroupId=com.Oracle -DartifactId=ojdbc14 -Dversion=10.2.0.2.0 -Dpackaging=jar -Dfile=ojdbc14.jar -DgeneratePom=true
这样加把jar加载到本地库了。
/**
* 通过数据库类型处理翻页查询语句
* 注释:如果框架当前不支持此种数据库分页查询,则返回一个空值字符串。
* * @param strSql 待执行SQL语句
* @param start 开始行数
* @param pageCount 每页行数
* */
private static String dealSqlByDBType(String dbType,String strSql,int start,int pageCount)
{
if(dbType==null)return "";
String retSql = "";
if(dbType.equals("mysql"))
{
//MYSQL数据库采用limit关键字进行分页
int startItem = start -1;if(startItem<0)startItem = 0;
retSql = strSql + " limit " + startItem + "," + pageCount;
}
else if(dbType.equals("oracle"))
{
//ORACLE数据库采用ROWNUM控制分页
int startItem = start;
if(startItem<=0){startItem = 0;}
int endItem = startItem + pageCount;
retSql = "SELECT * FROM ("
+ "SELECT A.*,ROWNUM RN FROM("
+ strSql
+ ") A WHERE ROWNUM<="+ endItem +") WHERE RN >"+startItem;
}
else if(dbType.equals("db2"))
{
//DB2数据库采用ROWNUMBER() OVER()函数进行分页
//其中OVER()函数中必须包含排序字段,此处用“1”代替
int startItem = start -1;if(startItem<0)startItem = 0;
int endItem = startItem + pageCount;
retSql = "SELECT * FROM ("
+ "SELECT B.*, ROWNUMBER() OVER(1) AS RN FROM ("
+ strSql
+ ") AS B )AS A WHERE A.RN <= "+ endItem +" AND A.RN >= "+ startItem;
}
else if(dbType.equals("sqlserver2005"))
{
//SQLSERVER2005采用ROW_NUMBER()函数进行分页
//其中OVER()函数中必须包含排序字段,此处用“1”代替
int startItem = start -1;if(startItem<0)startItem = 0;
int endItem = startItem + pageCount;
retSql = "SELECT * FROM ("
+ "SELECT B.*, ROW_NUMBER() OVER(1) RN FROM ("
+ strSql
+ ") B )A WHERE A.RN <= "+ endItem +" AND A.RN >= "+ startItem;
}
else if(dbType.equals("derby"))
{
//通过OFFSET等关键字进行翻页(尚未经过测试)
int startItem = start -1;if(startItem<0)startItem = 0;
//int endItem = startItem + pageCount;
retSql = strSql
+ " OFFSET "+ startItem +" ROWS"
+ " FETCH NEXT "+ pageCount +" ROWS ONLY";
}
return retSql;
}
String objParam = "{name:\"c\",configType:1,list:[{label:\"c\",tableName:\"c\",vfiled:\"c\",category:\"c\"},{label:\"c\",tableName:\"c\",vfiled:\"c\",category:\"c\"}]}";//request.getParameter("objParam");
JSONObject jsonObject = JSONObject.fromObject(objParam);
Map
classMap = new HashMap();
classMap.put("list", DtoSearch.class);
ResultData resultData = (ResultData) net.sf.json.JSONObject.toBean(
jsonObject, ResultData.class, classMap);
在window上安装solr步骤
1.在tomcat的目录中放入solr的索引库
2.在webapps中放入solr的应用程序
3.在tomcat_file/solr/目录中新建collection1目录, 放入搜索库文件,新建data文件夹,存放索引文件。
新建core.properties文件,写name=collection1。在/app/tomcat_file/solr/collection1/conf目录中,
修改scripts.conf文件。写上 <dataDir>${solr.data.dir:D:/app/tomcat_file/solr/collection1/data}</dataDir>。
5,在/app/tomcat_file/webapps/solr/WEB-INF中的web.xml文件中,配置:
<env-entry>
<env-entry-name>solr/home</env-entry-name>
<env-entry-value>D:/tomcat_file/solr</env-entry-value>
<env-entry-type>java.lang.String</env-entry-type>
</env-entry>
6.启动tomcat,配置solr成功
在Linux上安装solr步骤
1.在tomcat的目录中放入solr的索引库
2.在webapps中放入solr的应用程序
3.在/app/tomcat_file/conf/Catalina/localhost中新建solr.xml文件,内容是:
<?xml version="1.0" encoding="UTF-8"?>
<Context docBase="/app/tomcat_file/webapps/solr" debug="0" crossContext="true" >
<Environment name="solr/home" type="java.lang.String" value="/app/tomcat_file/solr" override="true" />
</Context>
4.在/app/tomcat_file/solr/目录中新建collection1目录, 放入搜索库文件,新建data文件夹,存放索引文件。
新建core.properties文件,写name=collection1。在/app/tomcat_file/solr/collection1/conf目录中,
修改scripts.conf文件。写上 <dataDir>${solr.data.dir:/app/tomcat_file/solr/collection1/data}</dataDir>。
5,在/app/tomcat_file/webapps/solr/WEB-INF中的web.xml文件中,配置:
<env-entry>
<env-entry-name>solr/home</env-entry-name>
<env-entry-value>/app/tomcat_file/solr</env-entry-value>
<env-entry-type>java.lang.String</env-entry-type>
</env-entry>
6.启动tomcat,配置solr成功
1.
@ExceptionHandler(ArithmeticException.class)
public ModelAndView getArithmeticException(Exception ex){
ModelAndView mv = new ModelAndView("error");
mv.addObject("ex", ex);
return mv;
}
@RequestMapping("/zero")
public void ac(@RequestParam("i") int i){
System.out.println(10/i);
}
当发生ArithmeticException异常的时候,在error.jsp页面输出异常 。
2.
@ControllerAdvice
public class Exceptions {
@ExceptionHandler(ArithmeticException.class)
public ModelAndView getArithmeticException(Exception ex){
ModelAndView mv = new ModelAndView("error");
mv.addObject("ex", ex);
return mv;
}
}
如果在本类中找不到异常处理的方法,就去@ControllerAdvice注解的类中查找异常处理的类的方法。
3.
@ResponseStatus(value=HttpStatus.BAD_REQUEST,reason="请求不对")
public class UserExceptions extends RuntimeException{
/**
*
*/
private static final long serialVersionUID = 1L;
}
在controller的方法里抛出UserExceptions 异常,在页面上显示
HTTP Status 400 - 请求不对
java不同版本加载jar的顺序不一样,window和Linux中,java不同版本加载jar的顺序不一样,所有不要以为在一个java版本和一个操作系统上成功运行成功,就认为程序没问题。只有在不同java版本和不同操作系统上都运行成功,才说明程序没问题。在java8一样的情况下,window和Linux加载spring的jar文件顺序不一样!!!!!!
一、在oracle11G以前卸载oracle会存在卸载不干净,导致再次安装失败的情况,在运行services.msc打开服务,停止Oracle的所有服务。
二、 oracle11G自带一个卸载批处理\app\Administrator\product\11.2.0\dbhome_1\deinstall\deinstall.bat运行该批处理程序将自动完成oracle卸载工作,最后手动删除\app文件夹(可能需要重启才能删除)
运行过程中可能需要填写如下项:
- 指定要取消配置的所有单实例监听程序[LISTENER]:LISTENER
- 指定在此 Oracle 主目录中配置的数据库名的列表 [MYDATA,ORCL]: MYDATA,ORCL
- 是否仍要修改 MYDATA,ORCL 数据库的详细资料? [n]: n
- CCR check is finished
- 是否继续 (y - 是, n - 否)? [n]: y
三、运行regedit命令,打开注册表。删除注册表中与Oracle相关内容,具体下:
- 删除HKEY_LOCAL_MACHINE/SOFTWARE/ORACLE目录。
- 删除HKEY_LOCAL_MACHINE/SYSTEM/CurrentControlSet/Services中所有以oracle或OraWeb为开头的键。
- 删除HKEY_LOCAL_MACHINE/SYSETM/CurrentControlSet/Services/Eventlog/application中所有以oracle开头的键。
- 删除HKEY_CLASSES_ROOT目录下所有以Ora、Oracle、Orcl或EnumOra为前缀的键。
- 删除HKEY_CURRENT_USER/SOFTWARE/Microsoft/windows/CurrentVersion/Explorer/MenuOrder/Start Menu/Programs中所有以oracle 开头的键。
- 删除HKDY_LOCAL_MACHINE/SOFTWARE/ODBC/ODBCINST.INI中除Microsoft ODBC for Oracle注册表键以外的所有含有Oracle的键。
- 删除环境变量中的PATHT CLASSPATH中包含Oracle的值。
- 删除“开始”/“程序”中所有Oracle的组和图标。
- 删除所有与Oracle相关的目录,包括: (1)、c:\Program file\Oracle目录。 (2)、ORACLE_BASE目录。(3)、c:\Documents and Settings\系统用户名、LocalSettings\Temp目录下的临时文件。
(function (){
function Person(){
this.getAge=function (age){
alert(age);
}
}
//让此类的所有对象有name属性,showName方法
Person.prototype.name="yjw";
Person.prototype.showName=function(){
alert(this.name);
}
// new Person().showName();
var v={};
//让空对象v继承Person,含有Person的所有属性和方法
v.__proto__=new Person();
v.__proto__.constructor=v;
v.getAge(1);
v.showName();
})()
(function (){
//创建一个人员类
function Person(n){
this.name=n;
this.getAge=function (age){
alert(age);
}
}
//创建教师类
function Teacher(name,books){
//call方法可以将一个函数的对象上下文,从初始化变成由this来决定
//调用Person的构造函数,
Person.call(this, name);//this就是person的this,name属性就是person的属性
this.books=books;
}
//让教师类继承人员类
Teacher.prototype=new Person();
Teacher.prototype.constructor=Teacher;//教师的构造方法还是使用教师自己的构造方法
Teacher.prototype.getBook = function(){//给教师类的原型添加方法
return this.name+" "+this.books;
}
var jim = new Teacher("jim","extjs");
// alert(jim.getBook());
//jim.getAge(2);
function extend(subClass,superClass){
//1.让子类原型类属性等于父类的原型属性,初始化一个中间空对象,为了转换主父类关系
var f = function(){};
f.prototype=superClass.prototype;
//2.让子类继承f
subClass.prototype=new f();
subClass.prototype.constructor=subClass;
//3.为子类增加属性,继承父类的原型对象
subClass.fuLei=superClass.prototype;
//4.增加一个保险,就算父类的原型类是超类object,也要把父类的构造函数的级别降下来
if(superClass.prototype.constructor==Object.prototype.constructor){
superClass.prototype.constructor=superClass;
}
}
function Student(name,books){
Student.fuLei.constructor.call(this,name);
this.books=books;
this.getBooks=function(){
return this.name+" "+this.books;
}
}
extend(Student, Person);
var s = new Student("s","a");
alert(s.getBooks());
s.getAge(2);
})()
1.如果两个网站域名的一级域名相同,可以使用cookie和filter实现单点登录,因为网站有可能(具体看cookie的设置)可以共享cookie。例如:www.bbs.aa.cn www.news.aa.cn。
第一个网站在登录后,把用户信息写到cookie中,当访问第二个网站时,第二个网站先经过自己的filter,检查session,如果没有,查询cookie,取出用户信息,放在session中登录。
public void doFilter(ServletRequest req, ServletResponse resp,
FilterChain chain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) req;
if(request.getSession().getAttribute("user")== null){
Cookie[] cs = request.getCookies();
if (cs != null && cs.length > 0) {
for (Cookie c : cs) {
String cName = c.getName();
if (cName.equals("sso")) {
String userName = c.getValue();
request.getSession().setAttribute("user", userName);
}
}
}
}
chain.doFilter(request, resp);
}
2.如果两个网站域名的一级域名不同,不可以使用cookie和filter实现单点登录,因为网站不可以共享cookie。例如:www.bbs.cn www.news.cn。
使用cas框架服务实现单点登录。1.部署cas服务端。2.在服务器端的ticketGrantingTicketCookieGenerator.xml中修改文件。<bean id="ticketGrantingTicketCookieGenerator" class="org.jasig.cas.web.support.CookieRetrievingCookieGenerator"
p:cookieSecure="false"//使用http协议
p:cookieMaxAge="-1"//cookie有效时间
p:cookieName="yjwname"//cookie名称
p:cookiePath="/" />//项目名称
3.部署www.bbs.cn www.news.cn服务,在每个客户端项目中加入casjar包,在web.xml中配置<?xml version="1.0" encoding="UTF-8"?>
<!--
Copyright (c) 2008, Martin W. Kirst
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of the Martin W. Kirst nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-->
<web-app id="mywebapp" version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
<display-name>mywebapp</display-name>
<description>
Simple sample, how to use CAS Java Client 3.x.
In this sample exists a public area (/)
and a private area (/protected/*).
</description>
<!-- Sign out not yet implemented -->
<!--
<filter>
<filter-name>CAS Single Sign Out Filter</filter-name>
<filter-class>org.jasig.cas.client.session.SingleSignOutFilter</filter-class>
</filter>
-->
<filter>
<filter-name>CAS Authentication Filter</filter-name>
<filter-class>org.jasig.cas.client.authentication.AuthenticationFilter</filter-class>
<init-param>
<!--cas服务器地址-->
<param-name>casServerLoginUrl</param-name>
<param-value>http://www.service.com:8081/login</param-value>
</init-param>
<init-param>
<!--自己的地址-->
<param-name>serverName</param-name>
<param-value>http://www.bbs.com:8081</param-value>
</init-param>
<init-param>
<param-name>renew</param-name>
<param-value>false</param-value>
</init-param>
<init-param>
<param-name>gateway</param-name>
<param-value>false</param-value>
</init-param>
</filter>
<filter>
<filter-name>CAS Validation Filter</filter-name>
<filter-class>org.jasig.cas.client.validation.Cas20ProxyReceivingTicketValidationFilter</filter-class>
<init-param>
<param-name>casServerUrlPrefix</param-name>
<param-value>http://www.service.com:8081</param-value>
</init-param>
<init-param>
<param-name>serverName</param-name>
<param-value>http://www.bbs.com:8081</param-value>
</init-param>
</filter>
<filter>
<filter-name>CAS HttpServletRequest Wrapper Filter</filter-name>
<filter-class>org.jasig.cas.client.util.HttpServletRequestWrapperFilter</filter-class>
</filter>
<filter>
<filter-name>CAS Assertion Thread Local Filter</filter-name>
<filter-class>org.jasig.cas.client.util.AssertionThreadLocalFilter</filter-class>
</filter>
<!-- ************************* -->
<!-- Sign out not yet implemented -->
<!--
<filter-mapping>
<filter-name>CAS Single Sign Out Filter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
-->
<filter-mapping>
<filter-name>CAS Authentication Filter</filter-name>
<!--此URL下的资源都需要验证登录-->
<url-pattern>/protected/*</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>CAS Validation Filter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>CAS HttpServletRequest Wrapper Filter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>CAS Assertion Thread Local Filter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>CAS Validation Filter</filter-name>
<url-pattern>/proxyCallback</url-pattern>
</filter-mapping>
<!-- *********************** -->
<!-- Sign out not yet implemented -->
<!--
<listener>
<listener-class>org.jasig.cas.client.session.SingleSignOutHttpSessionListener</listener-class>
</listener>
-->
</web-app>
4.启动服务,这样就可以实现单点登录
在web.xml中配置
<filter>
<filter-name>CharacterEncodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>utf-8</param-value>
</init-param>
<init-param>
<param-name>forceEncoding</param-name>
<param-value>true</param-value><!-- 强制进行转码 -->
</init-param>
</filter>
<filter-mapping>
<filter-name>CharacterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
</head>
<body>
<div id="mydiv">aaaaa</div>
<div id="mydiv1" onclick="test();">bbbbb</div>
<div id="mydiv2" onclick="test2(this);">bbbbb</div>
</body>
<script type="text/javascript" >
document.getElementById('mydiv').onclick=test1;
//相当于 对象.属性=test1,相当于对象拥有了test1属性,this指向当前对象
function test1(){
this.style.color='red';
}
function test(){
this.style.color='red';
}
function test2(t){
t.style.color='red';
}
//1.我们在js定义的所有的全局变量 和方法,都是需要附属在window上的,当成window的属性,所以在test方法中的
//this指向window,不是当前元素,所以test方法执行报错。在js中,规定,函数被哪个元素调用,this指向这个元素。
//当方法被动态绑定时,是当前元素调用方法,当行内绑定时,如果不在方法中传入当前对象,方法中的this指向window。
</script>
</html>
1.查看文件命令
命令格式:ls -la (查看所有文件,包括隐藏文件)
ls -l 或者ll (显示文件详细信息)
ls -d (查看目录属性)
2.文件类型和权限标示
- rw- rw- r--
-表示文件 d表示目录 l表示软链接文件
rw- 表示所有者的权限
rw-表示所有组的权限
r--表示其他人的权限
r读权限w写权限x执行权限
3.命令mkdir 创建目录 mkdir -p 递归创建目录
4.cd 进入目录 cd .. 返回上层目录
5.pwd 显示当前所在目录
6.rmdir 删除空目录
7.cp -r 复制目录 目的目录 cp -p 复制目录 目的目录,保留文件属性
8.mv 剪切文件或者目录或者 修改文件名
9.rm -r 删除目录 rm -f 强制执行 rm -rf 强制删除文件或者目录
10.touch 创建文件
11. cat 查看文件全文 cat -n 显示行号
12.more 查看大文件,f或者空格 向下翻页,enter 向下每行显示,
13.less 向上翻页查看大文件
14.head 文件名 head -n 10查看文件头10行
15.tail -n 10 文件名 ,查看文件尾部10行
16.tail -f 文件夹 实时查看文件变化
设置时间伟2008年8月8号12:00# date -s "2008-08-08 12:00:00"修改完后,记得执行clock -w,把系统时间写入CMOS
<script type="text/javascript" >
(function(){
i=10;
function aa(){
i=2;
}
aa();
alert(i);
})();
(function(){
i=10;
function aa(){
var i=2;
}
aa();
alert(i);
})();
</script>
在同一个js文件中,使用匿名函数,可以定义方法名相同的方法。
在函数里面没有var声明的变量会直接影响全局的变量,是因为在js中,如果某个变量没有var声明,
会自动到上一层作用域中去找这个变量的声明语句,如果找到,就使用,如果没有找到,继续向上查找,
一直查找到全局作用域为止。如果全局中仍然没有这个变量的声明语句,那么会自动在全局作用域进行声明,
这个就是js的作用域链 。
外部访问函数内部的变量是闭包实现的,函数内部的变量访问外部的变量是作用域链实现的
<html>
<script type="text/javascript">
/*作为普通函数来调用时,this的值指向window,
准确的说,this为null,但被解释成window
alert(window.xx);
function t(){
this.xx = 2;
}
t();
alert(window.xx);
*/
/*作为对象的方法来调用
this指向方法的调用者,就是该对象
var obj = {xx:11,yy:22,t:function(){alert(this.xx);}};
obj.t();
var dog = {xx:33};
dog.t = obj.t;
dog.t();
*/
/*this作为方法调用时,this指向其调用者,即母体对象,
不管被调用函数声明时属于方法还是属于函数
var dog = {xx:33};
show = function(){
alert('show=' +this.xx);
}
dog.t = show;
dog.t();
*/
/*函数作为构造函数调用时
js中没有类的概念,创建对象是用构造函数完成
或者直接用json格式来创建对象
new对象发生的步骤
a:系统创建空对象{},空对象的constructor属性指向构造感受
b:把函数的this指向该空对象
c:执行该函数
d:返回该对象
*/
function Pig(){
this.age = 2;
return 'a';
}
var pig = new Pig();
//返回Pig对象,因为函数作为构造函数运行时,
//return的值是忽略的,还是返回对象
</script>
</html>
<html>
<script type="text/javascript">
/*arguments是一个对象,一个长得很像数组的对象*/
/*arguments内容是函数运行时期的实参列表*/
/*arguments.callee 属性代表当前运行的函数*/
/*题目:不用函数名,使用匿名函数,完成递归*/
alert((function(n){
if (n<=1){
return n;
}else{
return n+arguments.callee(n-1);
}
})(100));
/*
函数运行期内,关键的三个函数
1:ao 如果本函数ao上没有属性,则继续去外层函数的ao
上找,直到全局对象,叫做作用域链
2:arguments 每个函数有自己的callee属性,但不向外层
接着找arguments相关属性,不形成链
*/
</script>
</html>
<html>
<script type="text/javascript">
function t1(){}
//t2=function(){}
/*这2种方式效果是不同的
t1是函数声明,全局内得到一个t1变量,值是function
t2只是一个赋值过程,值是右侧的表达式的返回结果,即函数
function(){}在js看来,就和3*3一样,是个表达式,返回一个结果
因此t1,t2两种方式在词法分析时,有着本质区别
前者在词法分析阶段就发挥作用
后者在运行阶段才发挥作用
*/
(function(window,undefined){alert(window);})(window);
</script>
</html>
<html>
<script type="text/javascript">
function a(b){
alert(b);
function b(){
alert(b);
}
b();
}
//a(1);
/*ao{b=fun}*/
function aa(b){
alert(b);
b=function (){
alert(b);
}
b();
}
aa(1);
/*
0:ao={}
1:分析参数 ao={b=undefined},马上变成ao={b=1}
2:分析var声明,没有
3:分析函数声明,没有
(注:b=function(){}是一个赋值过程,在执行期才有用)
*/
/*词法分析
分析3样东西
第一步:先分析参数
第二步:再分析变量声明
第三步:分析函数声明
一个函数能使用的局部变量,就从3步而来
具体步骤:
0:函数运行前的一瞬间,生成active object
1:a.把声明的参数作为ao对象的属性,值都是undefined
b.接收实参,形成ao对应属性的值
2:分析变量声明,如var
如果ao上还没有此变量声明,则把此变量作为ao属性,
值是undefined
如果ao上已经有了此属性,则不做任何影响
3:分析函数声明,如function t(){}
则把此函数作为ao的属性
注:如果此前ao已经有了t属性,则以前的t被覆盖
*/
function t1(age){
alert(age);
}
//t1(1);
function t2(age){
var age = 99;
alert(age);
}
//t2(1);
function t3(g){
var g = 'hello';
alert(g);
function g(){
}
alert(g);
}
//t3();
</script>
</html>
<html>
<script type="text/javascript">
function a(b){
alert(b);
function b(){
alert(b);
}
b();
}
//a(1);
/*ao{b=fun}*/
function aa(b){
alert(b);
b=function (){
alert(b);
}
b();
}
aa(1);
/*
0:ao={}
1:分析参数 ao={b=undefined},马上变成ao={b=1}
2:分析var声明,没有
3:分析函数声明,没有
(注:b=function(){}是一个赋值过程,在执行期才有用)
*/
/*词法分析
分析3样东西
第一步:先分析参数
第二步:再分析变量声明
第三步:分析函数声明
一个函数能使用的局部变量,就从3步而来
具体步骤:
0:函数运行前的一瞬间,生成active object
1:a.把声明的参数作为ao对象的属性,值都是undefined
b.接收实参,形成ao对应属性的值
2:分析变量声明,如var
如果ao上还没有此变量声明,则把此变量作为ao属性,
值是undefined
如果ao上已经有了此属性,则不做任何影响
3:分析函数声明,如function t(){}
则把此函数作为ao的属性
注:如果此前ao已经有了t属性,则以前的t被覆盖
*/
function t1(age){
alert(age);
}
//t1(1);
function t2(age){
var age = 99;
alert(age);
}
//t2(1);
function t3(g){
var g = 'hello';
alert(g);
function g(){
}
alert(g);
}
//t3();
</script>
</html>
<html>
<script type="text/javascript">
/*作用域
在js中,函数嵌套是非常普遍的,在函数嵌套中,
对变量是如何寻找的?
答:首先在函数内部寻找,如果需找不到,则在外层寻找。
直到……全局(window)区域.从里往外寻找
*/
var c=5;
function t1(){
var d=6;
function t2(){
var e =7;
alert(c+d+e);
}
t2();
}
//t1();//18
function t3(){
var d=6;
function t2(){
var e =7;
d =3;
alert(c+d+e);
}
t2();
}
//t3();//15
/*声明变量,var的作用
var 是在函数运行的上下文中,声明一个变量,
如果不加var,则是一个赋值操作,
但是不要狭隘的理解为声明了一个全局变量
*/
//alert(window.d);
//alert(window.e);
function t(){
d=5;//d没有加var,仅仅是一个赋值操作,寻找
//t域内的函数,如果没找到,继续向外寻找……到window
//如果window中还没有d,创建d变量并赋值
var e=6;
}
//t();
//alert(window.d);
//alert(window.e);
function t4 (){
var d;
function t2(){
d=5;
e=6;
}
t2();
}
//t4();
//alert(window.d);//undefined
//alert(d);// d is not defined
//alert(e);
/*
注意:以window.xxx引用全局变量,寻找不到,
作为window的属性不存在,返回undefined。
直接以xxx引用,寻找不到,则报xxx is not defined
*/
var s1='g';
function t5(){
alert(s1);//g
alert(s2);//is not defined
s2 = 'lo';
}
// t5();
/*
在t5中寻找s2,没有找到s2的变量声明,到window上寻找s2的变量声明,
还是没有找到,报is not defined
*/
function t6(){
alert(s1);//g
alert(s2);//undefined
var s2 = 'lo';
}
t6();
/*
解释:
js代码自上而下执行,但是js代码的整体运行分为:
词法分析期和运行期
自上而下执行之前,先有一个词法分析过程。
词法分析t6函数:
声明了s2变量,但是没有对s2赋值,只有在运行期才赋值
因此s2=undefined。
执行t6函数:
alert(s1);//g
alert(s2);//undefined
s2 = 'lo';
*/
</script>
</html>
/**
* 任务实体类
*/
@Entity
@Table(name = "t_task")
public class Task implements Serializable {
/**
*
*/
private static final long serialVersionUID = 1L;
private Long id;
private String name;
//计划开始时间
private Date plan_startTime;
private Project project;
//父任务
private Task parent;
// 子任务
private Set<Task> children = new HashSet<Task>();
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "id")
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Temporal(TemporalType.TIMESTAMP)
public Date getPlan_startTime() {
return plan_startTime;
}
public void setPlan_startTime(Date plan_startTime) {
this.plan_startTime = plan_startTime;
}
@ManyToOne(optional = false, cascade = {CascadeType.REFRESH, CascadeType.MERGE})
@JoinColumn(name = "projectId")
public Project getProject() {
return project;
}
public void setProject(Project project) {
this.project = project;
}
@ManyToOne(cascade = {CascadeType.REFRESH, CascadeType.MERGE})
@JoinColumn(name = "parentId")
public Task getParent() {
return parent;
}
public void setParent(Task parent) {
this.parent = parent;
}
@OrderBy("id ASC")
@OneToMany(mappedBy = "parent", fetch = FetchType.LAZY, cascade = {CascadeType.ALL})
public Set<Task> getChildren() {
return children;
}
public void setChildren(Set<Task> children) {
this.children = children;
}
}
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation {
public String key();
public String value();
}
@MyAnnotation(key = "k", value = "v")
public class UserAnnotation {
@MyAnnotation(key = "km", value = "vm")
public void sayHello() {
System.out.println("111");
}
public static void main(String[] args) throws Exception {
Class<?> cla = Class
.forName("com.kaishengit.annotation.UserAnnotation");
Method[] methods = cla.getMethods();
boolean flag = cla.isAnnotationPresent(MyAnnotation.class);
System.out.println(flag);
if (flag) {
MyAnnotation mya = (MyAnnotation) cla
.getAnnotation(MyAnnotation.class);
System.out.println(mya.key() + "====" + mya.value());
}
Set<Method> set = new HashSet<Method>();
for (int i = 0; i < methods.length; i++) {
boolean otherflag = methods[i]
.isAnnotationPresent(MyAnnotation.class);
if (otherflag) {
set.add(methods[i]);
System.out.println(methods[i].getName());
}
}
for (Method method : set) {
MyAnnotation name = method.getAnnotation(MyAnnotation.class);
System.out.println(name.key());
System.out.println("value===:" + name.value());
}
}
}
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package com.kaishengit.util.desfile;
import com.google.gson.Gson;
import javax.crypto.KeyGenerator;
import javax.crypto.CipherInputStream;
import javax.crypto.Cipher;
import javax.crypto.CipherOutputStream;
import java.security.SecureRandom;
import java.security.Key;
import java.io.*;
import java.security.*;
import java.util.ArrayList;
import java.util.List;
import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;
/**
*
* @author Y-T测试成功
*/
public class DesFile3 {
// private static final String k = "24234";
Key key;
public DesFile3() {
getKey("24234");//生成密匙
}
/**
* 根据参数生成KEY
*/
public void getKey(String strKey) {
try {
KeyGenerator _generator = KeyGenerator.getInstance("DES");
_generator.init(new SecureRandom(strKey.getBytes()));
this.key = _generator.generateKey();
_generator = null;
} catch (Exception e) {
throw new RuntimeException("Error initializing SqlMap class. Cause: " + e);
}
}
//加密以byte[]明文输入,byte[]密文输出
private byte[] getEncCode(byte[] byteS) {
byte[] byteFina = null;
Cipher cipher;
try {
cipher = Cipher.getInstance("DES");
cipher.init(Cipher.ENCRYPT_MODE, key);
byteFina = cipher.doFinal(byteS);
} catch (Exception e) {
e.printStackTrace();
} finally {
cipher = null;
}
return byteFina;
}
// 加密String明文输入,String密文输出
public String setEncString(String strMing) {
BASE64Encoder base64en = new BASE64Encoder();
String s = null;
try {
s = base64en.encode(getEncCode(strMing.getBytes("UTF8")));
} catch (Exception e) {
e.printStackTrace();
}
return s;
}
public String setEncString(String strMing, int count) {
BASE64Encoder base64en = new BASE64Encoder();
String s = strMing;
if (s != null) {
for (int i = 0; i < count; i++) {
try {
s = base64en.encode(getEncCode(s.getBytes("UTF8")));
} catch (Exception e) {
e.printStackTrace();
}
}
} else {
return s;
}
return s;
}
// 解密以byte[]密文输入,以byte[]明文输出
public byte[] getDesCode(byte[] byteD) {
Cipher cipher;
byte[] byteFina = null;
try {
cipher = Cipher.getInstance("DES");
cipher.init(Cipher.DECRYPT_MODE, key);
byteFina = cipher.doFinal(byteD);
} catch (Exception e) {
e.printStackTrace();
} finally {
cipher = null;
}
return byteFina;
}
// 解密:以String密文输入,String明文输出
public String setDesString(String strMi) {
BASE64Decoder base64De = new BASE64Decoder();
String s = null;
try {
s = new String(getDesCode(base64De.decodeBuffer(strMi)), "UTF8");
} catch (Exception e) {
e.printStackTrace();
}
return s;
}
public String setDesString(String strMi, int count) {
BASE64Decoder base64De = new BASE64Decoder();
String s = strMi;
if (s != null) {
for (int i = 0; i < count; i++) {
try {
s = new String(getDesCode(base64De.decodeBuffer(s)), "UTF8");
} catch (Exception e) {
e.printStackTrace();
}
}
} else {
return s;
}
return s;
}
/**
* 文件file进行加密并保存目标文件destFile中
*
* @param file 要加密的文件 如c:/test/srcFile.txt
* @param destFile 加密后存放的文件名 如c:/加密后文件.txt
*/
public void fileEncrypt(String file, String destFile) throws Exception {
Cipher cipher = Cipher.getInstance("DES");
// cipher.init(Cipher.ENCRYPT_MODE, getKey());
cipher.init(Cipher.ENCRYPT_MODE, this.key);
InputStream is = new FileInputStream(file);
OutputStream out = new FileOutputStream(destFile);
CipherInputStream cis = new CipherInputStream(is, cipher);
byte[] buffer = new byte[1024];
int r;
while ((r = cis.read(buffer)) > 0) {
out.write(buffer, 0, r);
}
cis.close();
is.close();
out.close();
}
public void fileEncrypt(String file, String destFile, int count) throws Exception {
if(file!=null&&!"".equals(file)&&destFile!=null&&!"".equals(destFile)){
if(count==1){
fileEncrypt( file, destFile);
}else {
String temp="";
String st=file;
for(int i=0;i<count;i++){
if(i!=(count-1)){
temp="src/jia"+System.currentTimeMillis();
fileEncrypt( st, temp);
File f = new File(st);
f.delete();
st=temp;
}else {
fileEncrypt( st, destFile);
File f = new File(st);
f.delete();
}
}
}
}
}
/**
* 文件采用DES算法解密文件
*
* @param file 已加密的文件 如c:/加密后文件.txt
* * @param destFile 解密后存放的文件名 如c:/ test/解密后文件.txt
*/
public void fileDecrypt(String file, String dest) throws Exception {
Cipher cipher = Cipher.getInstance("DES");
cipher.init(Cipher.DECRYPT_MODE, this.key);
InputStream is = new FileInputStream(file);
OutputStream out = new FileOutputStream(dest);
CipherOutputStream cos = new CipherOutputStream(out, cipher);
byte[] buffer = new byte[1024];
int r;
while ((r = is.read(buffer)) >= 0) {
cos.write(buffer, 0, r);
}
cos.close();
out.close();
is.close();
}
public void fileDecrypt(String file, String destFile, int count) throws Exception {
if(file!=null&&!"".equals(file)&&destFile!=null&&!"".equals(destFile)){
if(count==1){
fileDecrypt( file, destFile);
}else {
String temp="";
String st=file;
for(int i=0;i<count;i++){
if(i!=(count-1)){
temp="src/jie"+System.currentTimeMillis();
fileDecrypt( st, temp);
File f = new File(st);
f.delete();
st=temp;
}else {
fileDecrypt( st, destFile);
File f = new File(st);
f.delete();
}
}
}
}
}
public static void main(String[] args) throws Exception {
DesFile3 td = new DesFile3();
long begin = System.currentTimeMillis();
td.fileEncrypt("F:\\webservice\\webservice第一部分视频\\02_wsimport的使用.avi", "F:\\webservice\\webservice第一部分视频\\04",2); //加密
long jia = System.currentTimeMillis();
System.out.println((jia-begin)/1000);
long begin1 = System.currentTimeMillis();
// td.fileDecrypt("F:\\webservice\\webservice第一部分视频\\04", "F:\\webservice\\webservice第一部分视频\\04.a"); //解密
td.fileDecrypt("F:\\webservice\\webservice第一部分视频\\04", "F:\\webservice\\webservice第一部分视频\\04.avi",2); //解密
long jie = System.currentTimeMillis();
System.out.println((jie-begin1)/1000);
// List<User> list = new ArrayList<User>();
// User user = new User();
// user.setId(1);
// user.setAge(21);
// user.setName("杨军威");
// User user1 = new User();
// user1.setId(2);
// user1.setAge(23);
// user1.setName("北京");
// list.add(user);
// list.add(user1);
// Gson gson = new Gson();
// String res = gson.toJson(list);
// System.out.println(res);
// System.out.println("加密==" + td.setEncString(res,2));
// // td.setEncString(res);
// System.out.println("解密==" + td.setDesString(td.setEncString(res,2),2));
}
}
package com.kaishengit.util.jackson;
import java.io.IOException;
import java.io.StringWriter;
import java.io.Writer;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.codehaus.jackson.JsonEncoding;
import org.codehaus.jackson.JsonGenerationException;
import org.codehaus.jackson.JsonGenerator;
import org.codehaus.jackson.JsonParseException;
import org.codehaus.jackson.map.JsonMappingException;
import org.codehaus.jackson.map.ObjectMapper;
import org.codehaus.jackson.node.JsonNodeFactory;
public class JacksonTest {
private static JsonGenerator jsonGenerator = null;
private static ObjectMapper objectMapper = null;
private static AccountBean bean = null;
static {
bean = new AccountBean();
bean.setAddress("china-Guangzhou");
bean.setEmail("hoojo_@126.com");
bean.setId(1);
bean.setName("hoojo");
objectMapper = new ObjectMapper();
try {
jsonGenerator = objectMapper.getJsonFactory().createJsonGenerator(
System.out, JsonEncoding.UTF8);
} catch (IOException e) {
e.printStackTrace();
}
}
// public void init() {}
/*
* public void destory() { try { if (jsonGenerator != null) {
* jsonGenerator.flush(); } if (!jsonGenerator.isClosed()) {
* jsonGenerator.close(); } jsonGenerator = null; objectMapper = null; bean
* = null; System.gc(); } catch (IOException e) { e.printStackTrace(); } }
*/
// JavaBean(Entity/Model)转换成JSON
public static void writeEntityJSON() {
try {
System.out.println("jsonGenerator"); // writeObject可以转换java对象,eg:JavaBean/Map/List/Array等
jsonGenerator.writeObject(bean);
System.out.println();
System.out.println("ObjectMapper"); // writeValue具有和writeObject相同的功能
StringWriter strWriter = new StringWriter();
objectMapper.writeValue(strWriter, bean);
String s = strWriter.toString();
System.out.println("-----------------------");
System.out.println(s);
} catch (IOException e) {
e.printStackTrace();
}
}
// 将Map集合转换成Json字符串
public static void writeMapJSON() {
try {
Map<String, Object> map = new HashMap<String, Object>();
map.put("name", bean.getName());
map.put("account", bean);
bean = new AccountBean();
bean.setAddress("china-Beijin");
bean.setEmail("hoojo@qq.com");
map.put("account2", bean);
System.out.println("jsonGenerator");
jsonGenerator.writeObject(map);
System.out.println("");
System.out.println("objectMapper");
Writer strWriter = new StringWriter();
objectMapper.writeValue(strWriter, map);
System.out.println(strWriter.toString());
} catch (IOException e) {
e.printStackTrace();
}
}
// 将List集合转换成json
public static void writeListJSON() {
try {
List<AccountBean> list = new ArrayList<AccountBean>();
list.add(bean);
bean = new AccountBean();
bean.setId(2);
bean.setAddress("address2");
bean.setEmail("email2");
bean.setName("haha2");
list.add(bean);
System.out.println("jsonGenerator"); // list转换成JSON字符串
jsonGenerator.writeObject(list);
System.out.println();
System.out.println("ObjectMapper"); // 用objectMapper直接返回list转换成的JSON字符串
System.out.println("1###" + objectMapper.writeValueAsString(list));
System.out.print("2###"); // objectMapper list转换成JSON字符串
Writer strWriter = new StringWriter();
objectMapper.writeValue(strWriter, list);
System.out.println(strWriter.toString());
} catch (IOException e) {
e.printStackTrace();
}
}
public static void writeOthersJSON() {
try {
String[] arr = { "a", "b", "c" };
System.out.println("jsonGenerator");
String str = "hello world jackson!"; // byte
jsonGenerator.writeBinary(str.getBytes()); // boolean
jsonGenerator.writeBoolean(true); // null
jsonGenerator.writeNull(); // float
jsonGenerator.writeNumber(2.2f); // char
jsonGenerator.writeRaw("c"); // String
jsonGenerator.writeRaw(str, 5, 10); // String
jsonGenerator.writeRawValue(str, 5, 5); // String
jsonGenerator.writeString(str);
jsonGenerator.writeTree(JsonNodeFactory.instance.POJONode(str));
System.out.println(); // Object
jsonGenerator.writeStartObject();// {
jsonGenerator.writeObjectFieldStart("user");// user:{
jsonGenerator.writeStringField("name", "jackson");// name:jackson
jsonGenerator.writeBooleanField("sex", true);// sex:true
jsonGenerator.writeNumberField("age", 22);// age:22
jsonGenerator.writeEndObject();// }
jsonGenerator.writeArrayFieldStart("infos");// infos:[
jsonGenerator.writeNumber(22);// 22
jsonGenerator.writeString("this is array");// this is array
jsonGenerator.writeEndArray();// ]
jsonGenerator.writeEndObject();// }
AccountBean bean = new AccountBean();
bean.setAddress("address");
bean.setEmail("email");
bean.setId(1);
bean.setName("haha");
// complex Object
jsonGenerator.writeStartObject();// {
jsonGenerator.writeObjectField("user", bean);// user:{bean}
jsonGenerator.writeObjectField("infos", arr);// infos:[array]
jsonGenerator.writeEndObject();// }
} catch (Exception e) {
e.printStackTrace();
}
}
// 将json字符串转换成JavaBean对象
public static void readJson2Entity() {
String json = "{\"address\":\"address\",\"name\":\"haha\",\"id\":1,\"email\":\"email\"}";
try {
AccountBean acc = objectMapper.readValue(json, AccountBean.class);
System.out.println(acc.getName());
System.out.println(acc);
} catch (JsonParseException e) {
e.printStackTrace();
} catch (JsonMappingException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
// 将json字符串转换成List<Map>集合
public static void readJson2List() {
String json = "[{\"address\": \"address2\",\"name\":\"haha2\",\"id\":2,\"email\":\"email2\"},"
+ "{\"address\":\"address\",\"name\":\"haha\",\"id\":1,\"email\":\"email\"}]";
try {
List<LinkedHashMap<String, Object>> list = objectMapper.readValue(
json, List.class);
System.out.println(list.size());
for (int i = 0; i < list.size(); i++) {
Map<String, Object> map = list.get(i);
Set<String> set = map.keySet();
for (Iterator<String> it = set.iterator(); it.hasNext();) {
String key = it.next();
System.out.println(key + ":" + map.get(key));
}
}
} catch (JsonParseException e) {
e.printStackTrace();
} catch (JsonMappingException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
// Json字符串转换成Array数组
public static void readJson2Array() {
String json = "[{\"address\": \"address2\",\"name\":\"haha2\",\"id\":2,\"email\":\"email2\"},"
+ "{\"address\":\"address\",\"name\":\"haha\",\"id\":1,\"email\":\"email\"}]";
try {
AccountBean[] arr = objectMapper.readValue(json,
AccountBean[].class);
System.out.println(arr.length);
for (int i = 0; i < arr.length; i++) {
System.out.println(arr[i]);
}
} catch (JsonParseException e) {
e.printStackTrace();
} catch (JsonMappingException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
// Json字符串转换成Map集合
public static void readJson2Map() {
String json = "{\"success\":true,\"A\":{\"address\": \"address2\",\"name\":\"haha2\",\"id\":2,\"email\":\"email2\"},"
+ "\"B\":{\"address\":\"address\",\"name\":\"haha\",\"id\":1,\"email\":\"email\"}}";
try {
Map<String, Map<String, Object>> maps = objectMapper.readValue(
json, Map.class);
System.out.println(maps.size());
Set<String> key = maps.keySet();
Iterator<String> iter = key.iterator();
while (iter.hasNext()) {
String field = iter.next();
System.out.println(field + ":" + maps.get(field));
}
} catch (JsonParseException e) {
e.printStackTrace();
} catch (JsonMappingException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
/*
* public void writeObject2Xml() { //stax2-api-3.0.2.jar
* System.out.println("XmlMapper"); XmlMapper xml = new XmlMapper(); try {
* //javaBean转换成xml //xml.writeValue(System.out, bean); StringWriter sw =
* new StringWriter(); xml.writeValue(sw, bean);
* System.out.println(sw.toString()); //List转换成xml List<AccountBean> list =
* new ArrayList<AccountBean>(); list.add(bean); list.add(bean);
* System.out.println(xml.writeValueAsString(list)); //Map转换xml文档
* Map<String, AccountBean> map = new HashMap<String, AccountBean>();
* map.put("A", bean); map.put("B", bean);
* System.out.println(xml.writeValueAsString(map)); } catch
* (JsonGenerationException e) { e.printStackTrace(); } catch
* (JsonMappingException e) { e.printStackTrace(); } catch (IOException e) {
* e.printStackTrace(); }}
*/
public static void main(String[] args) {
JacksonTest.writeEntityJSON();
// JacksonTest.writeMapJSON();
// JacksonTest.writeListJSON();
// JacksonTest.writeOthersJSON();
// JacksonTest.readJson2Entity();
// JacksonTest.readJson2List();
// JacksonTest.readJson2Array();
//JacksonTest.readJson2Map();
}
}
1.公司和雇员的实体类
@XmlRootElement(name="company")
public class Company {
// @XmlElement(name="cname")
private String cname;
@XmlElement(name="employee")
private List<Employee> employees;
public Company(String cname,List<Employee> employees){
this.cname=cname;
this.employees=employees;
}
public Company(){}
@XmlTransient
public List<Employee> getEmployees() {
return this.employees;
}
public void setEmployees(List<Employee> employees) {
this.employees = employees;
}
// public void addEmployee(Employee employee){
// if(employees==null){
// this.employees=new ArrayList<Employee>();
// }
// this.employees.add(employee);
// }
public String getCname() {
return this.cname;
}
public void setCname(String cname) {
this.cname = cname;
}
}
@XmlType
public class Employee {
@XmlElement(name="name")
private String name;
@XmlElement(name="id")
private String id;
public Employee(String name,String id){
this.id=id;
this.name=name;
}
public Employee(){}
@XmlTransient
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@XmlTransient
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
}
测试类:
public class Test {
public static void main(String[] args){
Test.test01();
}
public static void test01() {
long l=System.currentTimeMillis();
try {
JAXBContext ctx = JAXBContext.newInstance(Company.class);
Marshaller marshaller = ctx.createMarshaller();
List<Employee> list=new ArrayList<Employee>();
list.add(new Employee("1","1e"));
list.add(new Employee("2", "2e"));
Company c = new Company("cc",list);
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
// marshaller.marshal( c,new FileOutputStream("src/"+l+".xml"));
StringWriter sw = new StringWriter();
marshaller.marshal(c,sw);
System.out.println(sw.toString());
test02(sw.toString());
// Unmarshaller unmarshaller = ctx.createUnmarshaller();
// File file = new File("src/"+l+".xml");
// Company cc = (Company)unmarshaller.unmarshal(file);
// // System.out.println(cc.getCname());
// System.out.println(cc.getEmployees().get(0).getName());
// System.out.println(file.exists());
} catch (JAXBException e) {
e.printStackTrace();
}
}
public static void test02(String xml) {
try {
// String xml = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?><company><employee><name>1</name><id>1e</id></employee><employee><name>2</name><id>2e</id></employee><cname>cc</cname></company>";
JAXBContext ctx = JAXBContext.newInstance(Company.class);
Unmarshaller um = ctx.createUnmarshaller();
Company stu = (Company)um.unmarshal(new StringReader(xml));
System.out.println(stu.getEmployees().get(0).getName() +","+stu.getCname());
} catch (JAXBException e) {
e.printStackTrace();
}
}
public static void test03() {
try{
JAXBContext context = JAXBContext.newInstance(Company.class);
Unmarshaller unmarshaller = context.createUnmarshaller();
File file = new File("src/test.xml");
Company c = (Company)unmarshaller.unmarshal(file);
System.out.println(c.getCname());
System.out.println(c.getEmployees().get(0).getName());
}catch (Exception e){
}
// System.out.println(people.age);
}
}
select * from table_name
是查询出table_name 里所有的记录
select * from table_name where column_name like '%%'
是查询出table_name表里column_name 类似于'%%'的记录
由于%是代替所有,‘%%’代替所有,但并不表示代替空值,所以后一条记录和前一条的区别是,前一条是查询所有记录,后一条是查询column_name 值 不为空的所有记录。
%是字符通配付,必须是字符。
select * from table_name 是查询整个表
select * from table_name where column_name like '%%' 查询这个字段 NOT IS NULL
加载Spring配置文件时,如果Spring配置文件中所定义的Bean类实现了ApplicationContextAware 接口,那么在加载Spring配置文件时,会自动调用ApplicationContextAware 接口中的
public void setApplicationContext(ApplicationContext context) throws BeansException
方法,获得ApplicationContext对象。
前提必须在Spring配置文件中指定该类
public class ApplicationContextRegister implements ApplicationContextAware {
private Log log = LogFactory.getLog(getClass());
public void setApplicationContext(ApplicationContext applicationContext)
throws BeansException {
ContextUtils.setApplicationContext(applicationContext);
log.debug("ApplicationContext registed");
}
}
public class ContextUtils {
private static ApplicationContext applicationContext;
private static Log log = LogFactory.getLog(ContextUtils.class);
public static void setApplicationContext(ApplicationContext applicationContext) {
synchronized (ContextUtils.class) {
log.debug("setApplicationContext, notifyAll");
ContextUtils.applicationContext = applicationContext;
ContextUtils.class.notifyAll();
}
}
public static ApplicationContext getApplicationContext() {
synchronized (ContextUtils.class) {
while (applicationContext == null) {
try {
log.debug("getApplicationContext, wait...");
ContextUtils.class.wait(60000);
if (applicationContext == null) {
log.warn("Have been waiting for ApplicationContext to be set for 1 minute", new Exception());
}
} catch (InterruptedException ex) {
log.debug("getApplicationContext, wait interrupted");
}
}
return applicationContext;
}
}
public static Object getBean(String name) {
return getApplicationContext().getBean(name);
}
}
配置文件:<bean class="com.sinotrans.framework.core.support.ApplicationContextRegister" />
正常情况:
- public class AppManager extends ContextLoaderListener implements ServletContextListener {
-
- private ServletContext context;
- private WebApplicationContext webApplicationContext;
-
- public void contextInitialized(ServletContextEvent sce) {
- this.context = sce.getServletContext();
- this.webApplicationContext = WebApplicationContextUtils.getRequiredWebApplicationContext(context);
- this.context.setAttribute("WEBAPPLICATIONCONTEXT", webApplicationContext); }
- HttpSession session = request.getSession();
- WebApplicationContext webApplicationContext = (WebApplicationContext)session.getServletContext().getAttribute("WEBAPPLICATIONCONTEXT");
- UnsubscribeEmailFacade unsubscribeEmailFacade = (UnsubscribeEmailFacade)webApplicationContext.getBean("unsubscribeEmailFacade");
<html>
<head>
<script src="jquery.js" type="text/javascript"></script>
</head>
<body>
<form class="cmxform" id="commentForm" method="get" action="#" style="float:left;position:absolute ;background-color: yellow;width:100%;height:100% " >
<fieldset style="width:100%;height:100%">
<p>
<label for="cusername">姓名</label>
<em>*</em><input id="cusername" name="username" size="25" />
</p>
<p>
<label for="cemail">电子邮件</label>
<em>*</em><input id="cemail" name="email" size="25" />
</p>
<p>
<label for="curl">网址</label>
<em> </em><input id="curl" name="url" size="25" value="" />
</p>
<p>
<label >价格</label>
<em> </em><input id="cprice" name="price" size="25" value="" />
</p>
<p>
<label for="ccomment">你的评论</label>
<em>*</em><textarea id="ccomment" name="comment" cols="22" ></textarea>
</p>
<p>
<input class="submit" type="button" value="提交"/>
<input class="quxiao" type="button" value="取消"/>
</p>
</fieldset>
</form>
<div>
<form>
<input type="text" id="chaxun" /><input type="button" value="查询" />
</form>
<div>
<input type="button" value="全选/全不选" id="CheckedAll"/>
<input type="button" value="反选" id='CheckedRev' />
<input id="add" type="button" value="新增"/>
<input type="button" value="删除" class="deleteall" />
</div>
</div>
<table cellpadding="0" cellspacing="0" border="1" width="100%">
<thead><tr><td>姓名</td><td>电子邮件</td><td>网址</td><td>你的评论</td><td>价格</td><td>编辑</td><td>删除</td></tr></thead>
<tbody>
<tr></tr>
</tbody>
<tfoot>
<tr><td>总价</td><td colspan="6">0</td></tr>
</tfoot>
</table>
</body>
<script type="text/javascript">
$(document).ready(function(){
// $("#commentForm").validate({meta: "validate"});
$("#commentForm").hide();
$("#add").bind("click",function(){
if($("#commentForm").is(":visible")){
$("#commentForm").hide();
}else{
$("#commentForm").show();
}
})
var num = 1;
$(".submit").click(function(){
$("#commentForm").hide();
var name = $('#cusername').val();
var email = $('#cemail').val();
var url = $('#curl').val();
var price = $('#cprice').val();
var comment = $('#ccomment').val();
var tr = $('<tr class="'+num+'"><td class="jsname"><input type="checkbox" value="'+num+'"/>'+name+'</td><td class="jsemail">'+email+'</td><td class="jsurl">'+url+'</td><td class="jscomment">'+comment+'</td><td class="jsprice" id="'+num+'">'+price+'</td><td><a href="#" class="edit">编辑</a></td><td><a href="#" class="delete">删除</a></td></tr>');
$('tbody tr:eq(0)').after(tr);
num++;
});
$(".quxiao").click(function(){
$("#commentForm").hide();
});
$('.delete').live('click',function(){
$(this).parent().parent().remove();
});
$('.edit').live('click',function(){
var tr=$(this).parent().parent();
var name = tr.children('.jsname').text();
var email = tr.children('.jsemail').text();
var url = tr.children('.jsurl').text();
var comment = tr.children('.jscomment').text();
var price = tr.children('.jsprice').text();
$('#cusername').attr('value',name);
$('#cemail').attr('value',email);
$('#curl').attr('value',url);
$('#cprice').attr('value',price);
$('#ccomment').attr('value',comment);
$("#commentForm").show();
$(this).parent().parent().remove();
});
$('.deleteall').click(function(){
$('input[type="checkbox"]:checked').each(function(){
$(this).parent().parent().remove();
});
});
var a = true;
$("#CheckedAll").click(function(){
//所有checkbox跟着全选的checkbox走。
if(a){
$('input[type="checkbox"]:checkbox').attr("checked", true);
a = false;
}else {
$('input[type="checkbox"]:checkbox').attr("checked", false);
a=true;
}
});
$("#CheckedRev").click(function(){
$('input[type="checkbox"]:checkbox').each(function(){
this.checked=!this.checked;
});
});
});
</script>
</html>
myschema文件如下:<?xml version="1.0" encoding="UTF-8"?>
<schema xmlns="
http://www.w3.org/2001/XMLSchema"
targetNamespace="
http://www.example.org/myschema"
xmlns:tns="
http://www.example.org/myschema"
elementFormDefault="qualified">
<element name="user">
<complexType>
<sequence>
<element name="id" type="int"/>
<element name="username" type="string"/>
<element name="time" type="date"/>
</sequence>
</complexType>
</element>
</schema>
xml文件如下1:
<?xml version="1.0" encoding="UTF-8"?>
<user xmlns="
http://www.example.org/01"
xmlns:xsi="
http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.example.org/01">
<id>1</id>
<username>zhangsan</username>
<born>1989-12-22</born>
</user>
xml文件2如下:
<?xml version="1.0" encoding="UTF-8"?>
<user xmlns="
http://www.example.org/01"
xmlns:xsi="
http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="01.xsd">
<id>11</id>
<username>lisi</username>
<born>1988-11-11</born>
</user>
摘要: --
开发流程:
一、先写schema或者wsdl文件
(1)新建一个项目作为服务端,在src目录下简历文件夹META-INF/wsdl/mywsdl.wsdl文件。(2)在mywsdl.wsdl文件中编写自己的内容,如下:
<?xml version="1.0"
encoding="UTF-8" standalone="no"?>
<wsdl:d...
阅读全文
@WebService
public interface IMyService {
@WebResult(name="addResult")
public int add(@WebParam(name="a")int a,@WebParam(name="b")int b);
@WebResult(name="user")
public User addUser(@WebParam(name="user")User user);
@WebResult(name="user")
public User login(@WebParam(name="username")String username,
@WebParam(name="password")String password)throws UserException;
@WebResult(name="user")
public List<User> list(@WebParam(header=true,name="authInfo")String authInfo);
}
@XmlRootElement
public class User {
private int id;
private String username;
private String nickname;
private String password;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getNickname() {
return nickname;
}
public void setNickname(String nickname) {
this.nickname = nickname;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public User(int id, String username, String nickname, String password) {
super();
this.id = id;
this.username = username;
this.nickname = nickname;
this.password = password;
}
public User() {
super();
}
}
public class MyServer {
public static void main(String[] args) {
Endpoint.publish("http://localhost:8989/ms", new MyServiceImpl());
}
}
@WebService(endpointInterface="org.soap.service.IMyService")
@HandlerChain(file="handler-chain.xml")
public class MyServiceImpl implements IMyService {
private static List<User> users = new ArrayList<User>();
public MyServiceImpl() {
users.add(new User(1,"admin","","111111"));
}
@Override
public int add(int a, int b) {
System.out.println("a+b="+(a+b));
return a+b;
}
@Override
public User addUser(User user) {
users.add(user);
return user;
}
@Override
public User login(String username, String password) throws UserException{
for(User user:users) {
if(username.equals(user.getUsername())&&password.equals(user.getPassword()))
return user;
}
throw new UserException("");
}
@Override
public List<User> list(String authInfo) {
System.out.println(authInfo);
return users;
}
}
public class TestSoap {
private static String ns = "http://service.soap.org/";
private static String wsdlUrl = "http://localhost:8989/ms?wsdl";
public static void main(String[] args){
TestSoap.test03();
}
@Test
public static void test01() {
try {
//1�������创建消息工厂���
MessageFactory factory = MessageFactory.newInstance();
//2����根据消息工厂创建SoapMessage
SOAPMessage message = factory.createMessage();
//3�����创建SOAPPart
SOAPPart part = message.getSOAPPart();
//4��获取SOAPENvelope
SOAPEnvelope envelope = part.getEnvelope();
//5��可以通过SoapEnvelope有效的获取相应的Body和Header等信息
SOAPBody body = envelope.getBody();
//6���根据Qname创建相应的节点(QName就是一个带有命名空间的节点)���������ռ��)
QName qname = new QName("http://java.zttc.edu.cn/webservice",
"add","ns");//<ns:add xmlns="http://java.zttc.edu.cn/webservice"/>
//�如果使用以下方式进行设置,会见<>转换为<和>
//body.addBodyElement(qname).setValue("<a>1</a><b>2</b>");
SOAPBodyElement ele = body.addBodyElement(qname);
ele.addChildElement("a").setValue("22");
ele.addChildElement("b").setValue("33");
//打印消息信息
message.writeTo(System.out);
} catch (SOAPException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
@Test//基于soap的消息传递
public static void test02() {
try {
//1���创建服务(Service)
URL url = new URL(wsdlUrl);
QName sname = new QName(ns,"MyServiceImplService");
Service service = Service.create(url,sname);
//2����创建Dispatch
Dispatch<SOAPMessage> dispatch = service.createDispatch(new QName(ns,"MyServiceImplPort"),
SOAPMessage.class, Service.Mode.MESSAGE);
//3����创建SOAPMessage
SOAPMessage msg = MessageFactory.newInstance().createMessage();
SOAPEnvelope envelope = msg.getSOAPPart().getEnvelope();
SOAPBody body = envelope.getBody();
//4���创建QName来指定消息中传递数据����
QName ename = new QName(ns,"add","nn");//<nn:add xmlns="xx"/>
SOAPBodyElement ele = body.addBodyElement(ename);
ele.addChildElement("a").setValue("22");
ele.addChildElement("b").setValue("33");
msg.writeTo(System.out);
System.out.println("\n invoking.....");
//5�通过Dispatch传递消息,会返回响应消息
SOAPMessage response = dispatch.invoke(msg);
response.writeTo(System.out);
System.out.println("\n----------------------------------------");
//��将响应的消息转换为dom对象��
Document doc = response.getSOAPPart().getEnvelope().getBody().extractContentAsDocument();
String str = doc.getElementsByTagName("addResult").item(0).getTextContent();
System.out.println(str);
} catch (SOAPException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
@Test
public static void test03() {
try {
//1�����创建服务(Service)
URL url = new URL(wsdlUrl);
QName sname = new QName(ns,"MyServiceImplService");
Service service = Service.create(url,sname);
//2���创建Dispatch(通过源数据的方式传递)
Dispatch<Source> dispatch = service.createDispatch(new QName(ns,"MyServiceImplPort"),
Source.class, Service.Mode.PAYLOAD);
//3���根据用户对象创建相应的xml
User user = new User(3,"zs","张三","11111");
//编排user对象
JAXBContext ctx = JAXBContext.newInstance(User.class);
Marshaller mar = ctx.createMarshaller();
//不会再创建xml的头信息
mar.setProperty(Marshaller.JAXB_FRAGMENT, true);
StringWriter writer= new StringWriter();
mar.marshal(user, writer);
System.out.println("writer====="+writer);
//4、封装相应的part addUser
String payload = "<xs:addUser xmlns:xs=\""+ns+"\">"+writer.toString()+"</xs:addUser>";
System.out.println("payload====="+payload);
StreamSource rs = new StreamSource(new StringReader(payload));
//5�通过dispatch传递payload
Source response = (Source)dispatch.invoke(rs);
//6�将Source转化为DOM进行操作,使用Transform对象转换
Transformer tran = TransformerFactory.newInstance().newTransformer();
DOMResult result = new DOMResult();
tran.transform(response, result);
//7���处理相应信息(通过xpath处理)
XPath xpath = XPathFactory.newInstance().newXPath();
NodeList nl = (NodeList)xpath.evaluate("//user", result.getNode(),XPathConstants.NODESET);
User ru = (User)ctx.createUnmarshaller().unmarshal(nl.item(0));
System.out.println(ru.getNickname());
} catch (IOException e) {
e.printStackTrace();
} catch (JAXBException e) {
e.printStackTrace();
} catch (TransformerConfigurationException e) {
e.printStackTrace();
} catch (TransformerFactoryConfigurationError e) {
e.printStackTrace();
} catch (TransformerException e) {
e.printStackTrace();
} catch (XPathExpressionException e) {
e.printStackTrace();
}
}
schema文件:
<?xml version="1.0" encoding="UTF-8"?>
<schema xmlns="
http://www.w3.org/2001/XMLSchema"
targetNamespace="
http://www.example.org/01"
xmlns:tns="
http://www.example.org/01"
elementFormDefault="qualified">
<element name="user">
<complexType>
<sequence>
<element name="id" type="int"/>
<element name="username" type="string"/>
<element name="born" type="date"/>
</sequence>
</complexType>
</element>
</schema>
xml文件1:
<?xml version="1.0" encoding="UTF-8"?>
<user xmlns="
http://www.example.org/01"
xmlns:xsi="
http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.example.org/01">
<id>1</id>
<username>zhangsan</username>
<born>1989-12-22</born>
</user>
xml文件2:
<?xml version="1.0" encoding="UTF-8"?>
<user xmlns="
http://www.example.org/01"
xmlns:xsi="
http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="01.xsd">
<id>11</id>
<username>lisi</username>
<born>1988-11-11</born>
</user>
schema文件2:
<?xml version="1.0" encoding="UTF-8"?>
<schema xmlns="http://www.w3.org/2001/XMLSchema" targetNamespace="http://www.example.org/02"
xmlns:tns="http://www.example.org/02" elementFormDefault="qualified">
<element name="books">
<complexType>
<!-- maxOccurs表示最大出现次数 -->
<sequence maxOccurs="unbounded">
<element name="book">
<complexType>
<sequence minOccurs="1" maxOccurs="unbounded">
<element name="title" type="string" />
<element name="content" type="string" />
<choice>
<element name="author" type="string" />
<element name="authors">
<complexType>
<all><!-- 每个元素只能出现一次 -->
<element name="author" type="string"/>
</all>
</complexType>
</element>
</choice>
</sequence>
<attribute name="id" type="int" use="required"/>
</complexType>
</element>
</sequence>
</complexType>
</element>
</schema>
xml文件:
<?xml version="1.0" encoding="UTF-8"?>
<book:books xmlns:book="
http://www.example.org/02"
xmlns:xsi="
http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="02.xsd">
<book:book id="1">
<book:title>Java in action</book:title>
<book:content>Java is good</book:content>
<book:author>Bruce</book:author>
</book:book>
<book:book id="2">
<book:title>SOA in action</book:title>
<book:content>soa is difficult</book:content>
<book:authors>
<book:author>Jike</book:author>
</book:authors>
</book:book>
</book:books>
schema文件3:
<?xml version="1.0" encoding="UTF-8"?>
<schema xmlns="
http://www.w3.org/2001/XMLSchema"
targetNamespace="
http://www.example.org/04"
xmlns:tns="
http://www.example.org/04"
elementFormDefault="qualified">
<element name="person" type="tns:personType"/>
<complexType name="personType">
<sequence>
<element name="name" type="string"/>
<element name="age" type="tns:ageType"/>
<element name="email" type="tns:emailType"/>
</sequence>
<attribute name="sex" type="tns:sexType"/>
</complexType>
<simpleType name="emailType">
<restriction base="string">
<pattern value="(\w+\.*)*\w+@\w+\.[A-Za-z]{2,6}"/>
<minLength value="6"/>
<maxLength value="255"/>
</restriction>
</simpleType>
<simpleType name="ageType">
<restriction base="int">
<minInclusive value="1"/>
<maxExclusive value="150"/>
</restriction>
</simpleType>
<simpleType name="sexType">
<restriction base="string">
<enumeration value="男"/>
<enumeration value="女"/>
</restriction>
</simpleType>
</schema>
xml文件:
<?xml version="1.0" encoding="UTF-8"?>
<person xmlns="
http://www.example.org/04"
xmlns:xsi="
http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.example.org/04" sex="男">
<name>搜索</name>
<age>149</age>
<email>sadf@sdf.css</email>
</person>
schema文件4:
classroom.dtd文件:<?xml version="1.0" encoding="UTF-8"?>
<!ELEMENT classroom (claName,grade,students)>
<!ATTLIST classroom id ID #REQUIRED>
<!ELEMENT claName (#PCDATA)>
<!ELEMENT grade (#PCDATA)>
<!ELEMENT students (student+)>
<!ELEMENT student (id,stuName,age)>
<!ELEMENT id (#PCDATA)>
<!ELEMENT stuName (#PCDATA)>
<!ELEMENT age (#PCDATA)>
classroom.xml文件:<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE classroom SYSTEM "classroom.dtd">
<classroom id="c1">
<claName>10计算机应用技术</claName>
<grade>2010</grade>
<students>
<student>
<id>1</id>
<stuName>zhangsan</stuName>
<age>12</age>
</student>
<student>
<id>2</id>
<stuName>lisi</stuName>
<age>122</age>
</student>
</students>
</classroom>
private static String ns = "
http://service.soap.org/";
private static String wsdlUrl = "
http://localhost:8989/ms?wsdl";public static void test02() {
try {
//1���创建服务(Service)
URL url = new URL(wsdlUrl);
QName sname = new QName(ns,"MyServiceImplService");
Service service = Service.create(url,sname);
//2����创建Dispatch
Dispatch<SOAPMessage> dispatch = service.createDispatch(new QName(ns,"MyServiceImplPort"),
SOAPMessage.class, Service.Mode.MESSAGE);
//3����创建SOAPMessage
SOAPMessage msg = MessageFactory.newInstance().createMessage();
SOAPEnvelope envelope = msg.getSOAPPart().getEnvelope();
SOAPBody body = envelope.getBody();
//4���创建QName来指定消息中传递数据����
QName ename = new QName(ns,"add","nn");//<nn:add xmlns="xx"/>
SOAPBodyElement ele = body.addBodyElement(ename);
ele.addChildElement("a").setValue("22");
ele.addChildElement("b").setValue("33");
msg.writeTo(System.out);
System.out.println("\n invoking.....");
//5�通过Dispatch传递消息,会返回响应消息
SOAPMessage response = dispatch.invoke(msg);
response.writeTo(System.out);
System.out.println("\n----------------------------------------");
//��将响应的消息转换为dom对象��
Document doc = response.getSOAPPart().getEnvelope().getBody().extractContentAsDocument();
String str = doc.getElementsByTagName("addResult").item(0).getTextContent();
System.out.println(str);
} catch (SOAPException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
public static void test06() {
InputStream is = null;
try {
is = TestStax.class.getClassLoader().getResourceAsStream("books.xml");
//创建文档处理对象
DocumentBuilder db = DocumentBuilderFactory.newInstance().newDocumentBuilder();
//通过DocumentBuilder创建doc的文档对象
Document doc = db.parse(is);
//创建XPath
XPath xpath = XPathFactory.newInstance().newXPath();
//第一个参数就是xpath,第二参数就是文档
NodeList list = (NodeList)xpath.evaluate("//book[@category='WEB']", doc,XPathConstants.NODESET);
for(int i=0;i<list.getLength();i++) {
//遍历输出相应的结果
Element e = (Element)list.item(i);
System.out.println(e.getElementsByTagName("title").item(0).getTextContent());
}
} catch (ParserConfigurationException e) {
e.printStackTrace();
} catch (SAXException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (XPathExpressionException e) {
e.printStackTrace();
} finally {
try {
if(is!=null) is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
@Test
public static void test07() {
try {
XMLStreamWriter xsw = XMLOutputFactory.newInstance().createXMLStreamWriter(System.out);
xsw.writeStartDocument("UTF-8","1.0");
xsw.writeEndDocument();
String ns = "
http://11:dd";
xsw.writeStartElement("nsadfsadf","person",ns);
xsw.writeStartElement(ns,"id");
xsw.writeCharacters("1");
xsw.writeEndElement();
xsw.writeEndElement();
xsw.flush();
xsw.close();
} catch (XMLStreamException e) {
e.printStackTrace();
} catch (FactoryConfigurationError e) {
e.printStackTrace();
}
}
@Test
public static void test08() {
InputStream is = null;
try {
is = TestStax.class.getClassLoader().getResourceAsStream("books.xml");
//创建文档处理对象
DocumentBuilder db = DocumentBuilderFactory.newInstance().newDocumentBuilder();
//通过DocumentBuilder创建doc的文档对象
Document doc = db.parse(is);
//创建XPath
XPath xpath = XPathFactory.newInstance().newXPath();
Transformer tran = TransformerFactory.newInstance().newTransformer();
tran.setOutputProperty(OutputKeys.ENCODING,"UTF-8");
tran.setOutputProperty(OutputKeys.INDENT, "yes");
//第一个参数就是xpath,第二参数就是文档
NodeList list = (NodeList)xpath.evaluate("//book[title='Learning XML']", doc,XPathConstants.NODESET);
//获取price节点
Element be = (Element)list.item(0);
Element e = (Element)(be.getElementsByTagName("price").item(0));
e.setTextContent("333.9");
Result result = new StreamResult(System.out);
//通过tranformer修改节点
tran.transform(new DOMSource(doc), result);
} catch (ParserConfigurationException e) {
e.printStackTrace();
} catch (SAXException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (XPathExpressionException e) {
e.printStackTrace();
} catch (TransformerConfigurationException e) {
e.printStackTrace();
} catch (TransformerFactoryConfigurationError e) {
e.printStackTrace();
} catch (TransformerException e) {
e.printStackTrace();
} finally {
try {
if(is!=null) is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
public static void test05() {
XMLInputFactory factory = XMLInputFactory.newInstance();
InputStream is = null;
try {
is = TestStax.class.getClassLoader().getResourceAsStream("books.xml");
//基于Filter的过滤方式,可以有效的过滤掉不用进行操作的节点,效率会高一些
XMLEventReader reader = factory.createFilteredReader(factory.createXMLEventReader(is),
new EventFilter() {
@Override
public boolean accept(XMLEvent event) {
//返回true表示会显示,返回false表示不显示
if(event.isStartElement()) {
String name = event.asStartElement().getName().toString();
if(name.equals("title")||name.equals("price"))
return true;
}
return false;
}
});
int num = 0;
while(reader.hasNext()) {
//通过XMLEvent来获取是否是某种节点类型
XMLEvent event = reader.nextEvent();
if(event.isStartElement()) {
//通过event.asxxx转换节点
String name = event.asStartElement().getName().toString();
if(name.equals("title")) {
System.out.print(reader.getElementText()+":");
}
if(name.equals("price")) {
System.out.print(reader.getElementText()+"\n");
}
}
num++;
}
System.out.println(num);
} catch (XMLStreamException e) {
e.printStackTrace();
} finally {
try {
if(is!=null) is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
public static void test04() {
XMLInputFactory factory = XMLInputFactory.newInstance();
InputStream is = null;
try {
is = TestStax.class.getClassLoader().getResourceAsStream("books.xml");
//基于迭代模型的操作方式
XMLEventReader reader = factory.createXMLEventReader(is);
int num = 0;
while(reader.hasNext()) {
//通过XMLEvent来获取是否是某种节点类型
XMLEvent event = reader.nextEvent();
if(event.isStartElement()) {
//通过event.asxxx转换节点
String name = event.asStartElement().getName().toString();
if(name.equals("title")) {
System.out.print(reader.getElementText()+":");
}
if(name.equals("price")) {
System.out.print(reader.getElementText()+"\n");
}
}
num++;
}
System.out.println(num);
} catch (XMLStreamException e) {
e.printStackTrace();
} finally {
try {
if(is!=null) is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
public static void test01() {
XMLInputFactory factory = XMLInputFactory.newInstance();
InputStream is = null;
try {
is = TestStax.class.getClassLoader().getResourceAsStream("books.xml");
XMLStreamReader reader = factory.createXMLStreamReader(is);
while(reader.hasNext()) {
// System.out.println("------------------------------------------------");
int type = reader.next();
System.out.println("type---"+type);
//判断节点类型是否是开始或者结束或者文本节点,之后根据情况及进行处理
if(type==XMLStreamConstants.START_ELEMENT) {//==1,指示事件是一个开始元素
System.out.println(reader.getName());
String name = reader.getName().toString();
if("book".equals(name)){
System.out.println(reader.getAttributeName(0)+":"+reader.getAttributeValue(0));
}else if("title".equals(name)){
System.out.println(reader.getAttributeName(0)+":"+reader.getAttributeValue(0));
}
// System.out.println("==1,指示事件是一个开始元素");
} else if(type==XMLStreamConstants.CHARACTERS) {//==4指示事件是一些字符
System.out.println(reader.getText().trim());
// System.out.println("==4指示事件是一些字符");
} else if(type==XMLStreamConstants.END_ELEMENT) {//==2,指示事件是一个结束元素
System.out.println("/"+reader.getName());
// System.out.println("==2,指示事件是一个结束元素");
}
//else if(type==XMLStreamConstants.ATTRIBUTE){
// int count = reader.getAttributeCount();
// System.out.println("count========"+count);
// if(count>0){
// int i=0;
// int[] arr = new int[count];
// while(i<count){
// arr[i]=i;
// i++;
// }
// for(int a : arr){
// System.out.println(reader.getAttributeValue(a));
// }
// }
// }
}
} catch (XMLStreamException e) {
e.printStackTrace();
} finally {
try {
if(is!=null) is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
学生类
import javax.xml.bind.annotation.XmlRootElement;
@XmlRootElement
public class Student {
private int id;
private String name;
private int age;
private Classroom classroom;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public Classroom getClassroom() {
return classroom;
}
public void setClassroom(Classroom classroom) {
this.classroom = classroom;
}
public Student(int id, String name, int age, Classroom classroom) {
super();
this.id = id;
this.name = name;
this.age = age;
this.classroom = classroom;
}
public Student() {
super();
}
}
教室类
public class Classroom {
private int id;
private String name;
private int grade;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getGrade() {
return grade;
}
public void setGrade(int grade) {
this.grade = grade;
}
public Classroom(int id, String name, int grade) {
super();
this.id = id;
this.name = name;
this.grade = grade;
}
public Classroom() {
super();
// TODO Auto-generated constructor stub
}
}
测试类:
public class TestJaxb {
public static void main(String[] args){
TestJaxb.test02();
}
@Test
public static void test01() {//测试对象转换xml字符串
try {
JAXBContext ctx = JAXBContext.newInstance(Student.class);
Marshaller marshaller = ctx.createMarshaller();
Student stu = new Student(1,"张三",21,new Classroom(1,"10计算机应用技术",2010));
marshaller.marshal(stu, System.out);
} catch (JAXBException e) {
e.printStackTrace();
}
}
@Test
public static void test02() {//测试xml字符串转换对象
try {
String xml = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?><student><age>21</age><classroom><grade>2010</grade><id>1</id><name>10计算机应用技术</name></classroom><id>1</id><name>张三</name></student>";
JAXBContext ctx = JAXBContext.newInstance(Student.class);
Unmarshaller um = ctx.createUnmarshaller();
Student stu = (Student)um.unmarshal(new StringReader(xml));
System.out.println(stu.getName()+","+stu.getClassroom().getName());
} catch (JAXBException e) {
e.printStackTrace();
}
}
}
1简历webservice服务的步骤:
(1)服务器的建立:1:创建接口SEI(Service Endpoint Interface)
@WebService()
public interface IMyService
{
@WebResult(name="addResult")
public int add(@WebParam(name="a")int
a,@WebParam(name="b")int b);
@WebResult(name="minusResult")
public int minus(@WebParam(name="a")int
a,@WebParam(name="b")int b);
@WebResult(name="loginUser")
public User login(@WebParam(name="username")String
username,@WebParam(name="password")String password);
}
2:创建实现类SIB(Service inplemention Bean)
@WebService(endpointInterface="org.zttc.service.IMyService")
public class MyServiceImpl
implements IMyService {
@Override
public int add(int a, int b) {
System.out.println(a+"+"+b+"="+(a+b));
return a+b;
}
@Override
public int minus(int a, int b) {
System.out.println(a+"-"+b+"="+(a-b));
return a-b;
}
@Override
public User login(String username, String password) {
System.out.println(username+" is logining");
User user = new User();
user.setId(1);
user.setUsername(username);
user.setPassword(password);
return user;
}
}
3:开启服务
public class MyServer {
public
static void main(String[] args) {
String
address = "http://localhost:8888/ns";
Endpoint.publish(address,
new MyServiceImpl());
}
}
在浏览器地址栏中输入; http://localhost:8888/ns?wsdl,看到页面上出现xml文件。
(2)客户端的建立:
public class TestClient {
public
static void main(String[] args) {
try
{
创建访问wsdl服务地址的url
URL
url = new URL("http://localhost:8888/ns?wsdl");
通过qname指明服务的具体信息
QName
sname = new QName("http://service.zttc.org/",
"MyServiceImplService");
创建服务
Service
service = Service.create(url,sname);
实现接口
IMyService
ms = service.getPort(IMyService.class);
System.out.println(ms.add(12,33));
}
catch (MalformedURLException e) {
e.printStackTrace();
}
}
}
3.wsdl的有关参数:
types:用来定义访问的类型
message:SOAP
portType:指明服务器的接口,并且通过operation绑定相应的in和out的消息:其中in表示参数,out表示返回值
binding:指定传递消息所使用的格式
service:指定服务所发布的名称
4:dtd的例子:
classroom.dtd
<?xml version="1.0"
encoding="UTF-8"?>
<!ELEMENT classroom
(claName,grade,students)>
<!ATTLIST classroom id ID #REQUIRED>
<!ELEMENT claName (#PCDATA)>
<!ELEMENT grade (#PCDATA)>
<!ELEMENT students (student+)>
<!ELEMENT student (id,stuName,age)>
<!ELEMENT id (#PCDATA)>
<!ELEMENT stuName (#PCDATA)>
<!ELEMENT age (#PCDATA)>
classroom.xml
<?xml version="1.0"
encoding="UTF-8"?>
<!DOCTYPE classroom SYSTEM
"classroom.dtd">
<classroom id="c1">
<claName>10计算机应用技术</claName>
<grade>2010</grade>
<students>
<student>
<id>1</id>
<stuName>zhangsan</stuName>
<age>12</age>
</student>
<student>
<id>2</id>
<stuName>lisi</stuName>
<age>122</age>
</student>
</students>
</classroom>
1.得到访问的文件地址
<script type="text/javascript">
with(location){
var qs = search.substring(1);
var hostName = hostname; //unavailable when viewing from a local file
var url = href;
}
alert(qs);
alert(hostName);
alert(url);
</script>
<script type="text/javascript">
// == 表示两个对象的toString相等
//===表示两个对象的类型相等且值相等。
alert(null == undefined); //true
alert(null === undefined); //false
alert("NaN" == NaN); //false
alert("NaN" === NaN); //false
alert(NaN == NaN); //false
alert(NaN === NaN); //false
alert(NaN != NaN); //true
alert(NaN !== NaN); //true
alert(false == 0); //true
alert(false === 0); //false
alert(true == 1); //true
alert(true === 1); //false
alert(null == 0); //false
alert(undefined == 0); //false
alert(5 == "5"); //true
alert(5 === "5"); //false
</script>
<script type="text/javascript">
alert(null == undefined); //true
alert(null === undefined); //false
alert("NaN" == NaN); //false
alert("NaN" === NaN); //false
alert(NaN == NaN); //false
alert(NaN === NaN); //false
alert(NaN != NaN); //true
alert(NaN !== NaN); //true
alert(false == 0); //true
alert(false === 0); //false
alert(true == 1); //true
alert(true === 1); //false
alert(null == 0); //false
alert(undefined == 0); //false
alert(5 == "5"); //true
alert(5 === "5"); //false
</script>
<script type="text/javascript">
var result1 = ("55" != 55); //false ?equal because of conversion
var result2 = ("55" !== 55); //true ?not equal because different data types
alert(result1);
alert(result2);
var result1 = ("55" == 55); //true ?equal because of conversion
var result2 = ("55" === 55); //false ?not equal because different data types
</script>
得到window中所有的事件
<script type="text/javascript">
for (var propName in window) {
document.write(propName);
document.write("<br />");
}
</script>
<script type="text/javascript">
for (var propName in window) {
document.write(propName);
document.write("<br />");
}
</script>
方法参数数组
<script type="text/javascript">
function sayHi() {
alert("Hello " + arguments[0] + ", " + arguments[1]);
}
sayHi("Nicholas", "how are you today?");
function howManyArgs() {
alert(arguments.length);
}
howManyArgs("string", 45); //2
howManyArgs(); //0
howManyArgs(12); //1 </script>
<script type="text/javascript">
function sayHi() {
alert("Hello " + arguments[0] + ", " + arguments[1]);
}
sayHi("Nicholas", "how are you today?");
</script>
null的类型
<script type="text/javascript">
var car = null;
alert(typeof car); //"object"
alert(null == undefined); //true </script>
<script type="text/javascript">
var car = null;
alert(typeof car); //"object"
</script>
1 Javascript数组转换为CSV格式
首先考虑如下的应用场景,有一个Javscript的字符型(或者数值型)数组,现在需要转换为以逗号分割的CSV格式文件。则我们可以使用如下的小技巧,代码如下:
- var fruits = ['apple', 'peaches', 'oranges', 'mangoes'];
- var str = fruits.valueOf();
输出:apple,peaches,oranges,mangoes
其中,valueOf()方法会将Javascript数组转变为逗号隔开的字符串。要注意的是,如果想不使用逗号分割,比如用|号分割,则请使用join方法,如下:
- var fruits = ['apple', 'peaches', 'oranges', 'mangoes'];
- var str = fruits.join("|");
输出: apple|peaches|oranges|mangoes
2 将CSV格式重新转换回Javscript数组
那么如何将一个CSV格式的字符串转变回Javascript数组呢?可以使用split()方法,就可以使用任何指定的字符去分隔,代码如下:
- var str = "apple, peaches, oranges, mangoes";
- var fruitsArray = str.split(",");
输出 fruitsArray[0]: apple
3 根据索引移除数组中的某个元素
假如需要从Javascript数组中移除某个元素,可以使用splice方法,该方法将根据传入参数n,移除数组中移除第n个元素(Javascript数组中从第0位开始计算)。
- function removeByIndex(arr, index) {
- arr.splice(index, 1);
- }
- test = new Array();
- test[0] = 'Apple';
- test[1] = 'Ball';
- test[2] = 'Cat';
- test[3] = 'Dog';
- alert("Array before removing elements: "+test);
- removeByIndex(test, 2);
- alert("Array after removing elements: "+test);
则最后输出的为Apple,Ball,Dog
4 根据元素的值移除数组元素中的值
下面这个技巧是很实用的,是根据给定的值去删除数组中的元素,代码如下:
- function removeByValue(arr, val) {
- for(var i=0; i<arr.length; i++) {
- if(arr[i] == val) {
- arr.splice(i, 1);
- break;
- }
- }
- }
-
- var somearray = ["mon", "tue", "wed", "thur"]
-
- removeByValue(somearray, "tue");
-
-
当然,更好的方式是使用prototype的方法去实现,如下代码:
- Array.prototype.removeByValue = function(val) {
- for(var i=0; i<this.length; i++) {
- if(this[i] == val) {
- this.splice(i, 1);
- break;
- }
- }
- }
-
- var somearray = ["mon", "tue", "wed", "thur"]
- somearray.removeByValue("tue");
5 通过字符串指定的方式动态调用某个方法
有的时候,需要在运行时,动态调用某个已经存在的方法,并为其传入参数。这个如何实现呢?下面的代码可以:
- var strFun = "someFunction";
- var strParam = "this is the parameter";
- var fn = window[strFun];
-
-
- fn(strParam);
6 产生1到N的随机数
- var random = Math.floor(Math.random() * N + 1);
-
-
- var random = Math.floor(Math.random() * 10 + 1);
-
-
- var random = Math.floor(Math.random() * 100 + 1);
7 捕捉浏览器关闭的事件
我们经常希望在用户关闭浏览器的时候,提示用户要保存尚未保存的东西,则下面的这个Javascript技巧是十分有用的,代码如下:
- <script language="javascript">
- function fnUnloadHandler() {
-
- alert("Unload event.. Do something to invalidate users session..");
- }
- </script>
- <body onbeforeunload="fnUnloadHandler()">
- ………
- </body>
就是编写onbeforeunload()事件的代码即可
8 检查是否按了回退键
同样,可以检查用户是否按了回退键,代码如下:
- window.onbeforeunload = function() {
- return "You work will be lost.";
- };
9 检查表单数据是否改变
有的时候,需要检查用户是否修改了一个表单中的内容,则可以使用下面的技巧,其中如果修改了表单的内容则返回true,没修改表单的内容则返回false。代码如下:
- function formIsDirty(form) {
- for (var i = 0; i < form.elements.length; i++) {
- var element = form.elements[i];
- var type = element.type;
- if (type == "checkbox" || type == "radio") {
- if (element.checked != element.defaultChecked) {
- return true;
- }
- }
- else if (type == "hidden" || type == "password" ||
- type == "text" || type == "textarea") {
- if (element.value != element.defaultValue) {
- return true;
- }
- }
- else if (type == "select-one" || type == "select-multiple") {
- for (var j = 0; j < element.options.length; j++) {
- if (element.options[j].selected !=
- element.options[j].defaultSelected) {
- return true;
- }
- }
- }
- }
- return false;
- }
- window.onbeforeunload = function(e) {
- e = e || window.event;
- if (formIsDirty(document.forms["someForm"])) {
-
- if (e) {
- e.returnValue = "You have unsaved changes.";
- }
-
- return "You have unsaved changes.";
- }
- };
10 完全禁止使用后退键
下面的技巧放在页面中,则可以防止用户点后退键,这在一些情况下是需要的。代码如下:
- <SCRIPT type="text/javascript">
- window.history.forward();
- function noBack() { window.history.forward(); }
- </SCRIPT>
- </HEAD>
- <BODY onload="noBack();"
- onpageshow="if (event.persisted) noBack();" onunload="">
11 删除用户多选框中选择的项目
下面提供的技巧,是当用户在下拉框多选项目的时候,当点删除的时候,可以一次删除它们,代码如下:
- function selectBoxRemove(sourceID) {
-
- var src = document.getElementById(sourceID);
-
- for(var count= src.options.length-1; count >= 0; count--) {
-
- if(src.options[count].selected == true) {
- try {
- src.remove(count, null);
-
- } catch(error) {
-
- src.remove(count);
- }
- }
- }
- }
12 Listbox中的全选和非全选
如果对于指定的listbox,下面的方法可以根据用户的需要,传入true或false,分别代表是全选listbox中的所有项目还是非全选所有项目,代码如下:
- function listboxSelectDeselect(listID, isSelect) {
- var listbox = document.getElementById(listID);
- for(var count=0; count < listbox.options.length; count++) {
- listbox.options[count].selected = isSelect;
- }
- }
13 在Listbox中项目的上下移动
下面的代码,给出了在一个listbox中如何上下移动项目
- unction listbox_move(listID, direction) {
-
- var listbox = document.getElementById(listID);
- var selIndex = listbox.selectedIndex;
-
- if(-1 == selIndex) {
- alert("Please select an option to move.");
- return;
- }
-
- var increment = -1;
- if(direction == 'up')
- increment = -1;
- else
- increment = 1;
-
- if((selIndex + increment) < 0 ||
- (selIndex + increment) > (listbox.options.length-1)) {
- return;
- }
-
- var selValue = listbox.options[selIndex].value;
- var selText = listbox.options[selIndex].text;
- listbox.options[selIndex].value = listbox.options[selIndex + increment].value
- listbox.options[selIndex].text = listbox.options[selIndex + increment].text
-
- listbox.options[selIndex + increment].value = selValue;
- listbox.options[selIndex + increment].text = selText;
-
- listbox.selectedIndex = selIndex + increment;
- }
-
-
-
- listbox_move('countryList', 'up');
- listbox_move('countryList', 'down');
14 在两个不同的Listbox中移动项目
如果在两个不同的Listbox中,经常需要在左边的一个Listbox中移动项目到另外一个Listbox中去,下面是相关代码:
- function listbox_moveacross(sourceID, destID) {
- var src = document.getElementById(sourceID);
- var dest = document.getElementById(destID);
-
- for(var count=0; count < src.options.length; count++) {
-
- if(src.options[count].selected == true) {
- var option = src.options[count];
-
- var newOption = document.createElement("option");
- newOption.value = option.value;
- newOption.text = option.text;
- newOption.selected = true;
- try {
- dest.add(newOption, null);
- src.remove(count, null);
- }catch(error) {
- dest.add(newOption);
- src.remove(count);
- }
- count--;
- }
- }
- }
-
-
-
- listbox_moveacross('countryList', 'selectedCountryList');
15 快速初始化Javscript数组
下面的方法,给出了一种快速初始化Javscript数组的方法,代码如下:
- var numbers = [];
- for(var i=1; numbers.push(i++)<100;);
-
- 使用的是数组的push方法
16 截取指定位数的小数
如果要截取小数后的指定位数,可以使用toFixed方法,比如:
- var num = 2.443242342;
- alert(num.toFixed(2));
- 而使用toPrecision(x)则提供指定位数的精度,这里的x是全部的位数,如:
- num = 500.2349;
- result = num.toPrecision(4);
17 检查字符串中是否包含其他字符串
下面的代码中,可以实现检查某个字符串中是否包含其他字符串。代码如下:
- if (!Array.prototype.indexOf) {
- Array.prototype.indexOf = function(obj, start) {
- for (var i = (start || 0), j = this.length; i < j; i++) {
- if (this[i] === obj) { return i; }
- }
- return -1;
- }
- }
-
- if (!String.prototype.contains) {
- String.prototype.contains = function (arg) {
- return !!~this.indexOf(arg);
- };
- }
在上面的代码中重写了indexOf方法并定义了contains方法,使用的方法如下:
- var hay = "a quick brown fox jumps over lazy dog";
- var needle = "jumps";
- alert(hay.contains(needle));
18 去掉Javscript数组中的重复元素
下面的代码可以去掉Javascript数组中的重复元素,如下:
- function removeDuplicates(arr) {
- var temp = {};
- for (var i = 0; i < arr.length; i++)
- temp[arr[i]] = true;
-
- var r = [];
- for (var k in temp)
- r.push(k);
- return r;
- }
-
-
- var fruits = ['apple', 'orange', 'peach', 'apple', 'strawberry', 'orange'];
- var uniquefruits = removeDuplicates(fruits);
-
19 去掉String中的多余空格
下面的代码会为String增加一个trim()方法,代码如下:
- if (!String.prototype.trim) {
- String.prototype.trim=function() {
- return this.replace(/^\s+|\s+$/g, '');
- };
- }
-
-
- var str = " some string ";
- str.trim();
-
20 Javascript中的重定向
在Javascript中,可以实现重定向,方法如下:
- window.location.href = "http://viralpatel.net";
21 对URL进行编码
有的时候,需要对URL中的传递的进行编码,方法如下:
- var myOtherUrl =
- "http://example.com/index.html?url=" + encodeURIComponent(myUrl);
<html>
<head>
<script src="jquery.js" type="text/javascript"></script>
</head>
<body>
<input type="radio" name="riskLib" value="yjw1">杨军威1<br/>
<input type="radio" name="riskLib" value="yjw2">杨军威2<br/>
<input type="button" id="Btn_riskLib" />
<script type="text/javascript">
$(document).ready(function(){
$("#Btn_riskLib").bind("click",function(){
var id =$(":radio:checked").val();
if(id==null){
alert("请选择一个!");
}else {
alert(id);
}
})
});
</script>
</body>
</html>
任务和联系人是多对多关系,现在由联系人id查询出所有相关的任务
"SELECT t from Task t join t.contacters c where c.id = ?1"
比如:
一个老师教许多学生,一个学生被许多老师教,一个学生有好多书,同一种书被许多同学拥有.
要查询教拥有书"a"的学生的老师!
Hql语句:
SELECT t FROM Teacher t join t.students s join s.books b where b.name = 'a'
解释:t.students s中s并不是集合的意思,而是t的students对象的表别名,join t.students s这个hql,hibernate会翻译成两个表的内连接关系
错误写法:
SELECT t FROM teacher t where t.students.books.name = 'a'
其实道理是很显然的,t.students是一个Set,那么这个Set怎么可能有books这样的属性呢?同理books.name也不对,所以 使用表间连接并给出别名t.students s,此时的对象s才有books属性,所以可以写s.books b,最后使用b.name限制查询b.name = 'a'.
另外一种写法:
SELECT t FROM Teacher t,Student s,Book b where s.id in elements(t.students) and b.id in elements(s.books)
这种方法没有出错!不过这种方式要用子查询!
public Map readXml() {
try {
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = dbf.newDocumentBuilder();
Document doc;
InputStream stream = this.getClass().getResourceAsStream("/dictionaries.xml");
doc = builder.parse(stream);
Element root = doc.getDocumentElement();
NodeList list = root.getElementsByTagName("dictionary");
Map map = new LinkedHashMap();
ArrayList<String> types = new ArrayList<String>();
for (int i = 0; i < list.getLength(); i++) {
String key = list.item(i).getAttributes().getNamedItem("name").getNodeValue();
String value = list.item(i).getAttributes().getNamedItem("value").getNodeValue();
map.put(key, value);
}
return map;
} catch (Exception ex) {
return null;
}
}
dictionaries.xml文件如下:
<?xml version="1.0" encoding="UTF-8"?>
<dictionaries>
<dictionary name="项目类型" value="project.types" />
<dictionary name="项目状态" value="project.statuses" />
<dictionary name="任务阶段" value="task.stages" />
<dictionary name="任务状态" value="task.statuses" />
<dictionary name="发生几率" value="risk.probability" />
<dictionary name="危险程度" value="risk.harm" />
<dictionary name="风险状态" value="risk.status" />
<dictionary name="预案类别" value="risk.type" />
<dictionary name="合同类型" value="contract.type" />
<dictionary name="合同状态" value="contract.status" />
</dictionaries>
<html>
<body>
<input type="button" value="add row" id="addrow"/>
<table>
<tr>
<td width="20"><input type="checkbox" /><td>
<td>dddddddd</td>
</tr>
</table>
</body>
<script type="text/javascript" src="jquery-1.5.1.min.js"></script>
<script type="text/javascript" >
$(document).ready(function(){
$('input[type="checkbox"]').live('click',function(){//live给新添加的节点添加事件
$(this).parent().parent().remove();
});
$('addrow').mouseover(function(){
$(this).css('color','red');
});
$('addrow').mouseout(function(){
$(this).css('color','red');
});
$('#addrow').click(function(){
var tr = $('<tr>');
var td1 = $('<td>');
td1.attr('width','20');
var input = $('<input>');
input.attr('type','checkbox');
var td2 = $('<td>');
td2.text('aaaa');
td1.append(input);
tr.append(td1);
tr.append(td2);
//$('table').append(tr);
$('tbody tr:first').before(tr);
});
});
</script>
</html>
<html>
<body>
<input type="button" value="add row" id="addrow"/>
<table>
<tr>
<td width="20"><input type="checkbox" /><td>
<td>dddddddd</td>
</tr>
</table>
</body>
<script type="text/javascript" src="jquery-1.5.1.min.js"></script>
<script type="text/javascript" >
$(document).ready(function(){
$('input[type="checkbox"]').click(function(){
$(this).parent().parent().remove();
});
$('#addrow').click(function(){
var tr = $('<tr>');
var td1 = $('<td>');
td1.attr('width','20');
var input = $('<input>');
input.attr('type','checkbox');
var td2 = $('<td>');
td2.text('aaaa');
td1.append(input);
tr.append(td1);
tr.append(td2);
$('table').append(tr);
});
});
</script>
</html>
<html>
<head></head>
<body>
<form name="fm1" id="fm1">
name:<input type="text" name="name" id="name1" />
<input type="submit" id="s1"/>
</form>
<form name="fm2" id="fm2">
name:<input type="text" name="name" id="name2" />
<input type="submit" id="s2" />
</form>
<script type="text/javascript">
//var form = document.getElementById('fm2');
//var formarray = document.forms[1];//得到页面中所以表单的数组
//var form = document.forms['fm1'];//根据表单name属性得到数组
var form = document.fm1;//根据表单name属性得到数组
alert(form);
</script>
</body>
</html>
<html>
<head></head>
<body>
<input type="text" id="mytext" />
<span id="myspan"></span>
<script type="text/javascript">
var mytext=document.getElementById('mytext');
var myspan=document.getElementById('myspan');
mytext.onfocus = function(){
myspan.innerHTML = '得到焦点';
}
mytext.onblur = function(){
myspan.innerHTML = '失去焦点';
}
window.onbeforeunload=function(){
var v = mytext.value;
alert(v);
if(v){
return '444';
}
}
</script>
</body>
</html>


<html>
<head></head>
<body>
<div id="div1">1111111111
<div id="div2">2222222222</div>
</div>
<input type="button" id="btn" />
<a href="http://www.baidu.com" id="mya">163</a>
<a href="javascript:;" >普通按钮,不跳转</a>
<script type="text/javascript">
var eventUtil = {
addHandler:function(element,type,handler){
if(element.addEventListener){
element.addEventListener(type,handler,false);
}else if(element.attachEvent){
element.attachEvent('on'+type,handler);
}else {
element['on'+type]=handler;
}
},
getEvent:function(event){
return event ? event : window.event;
},
getElement: function(e){
if(e.target){
return e.target;
}else {
return e.srcElement;
}
},
preventDefault:function(e){
if(e.preventDefault){
e.preventDefault();
}else {
e.returnValue=false;
}
},
stopPropagation : function(e){
if(e.stopPropagation){
e.stopPropagation();
}else {
e.cancelBubble=true;
}
}
};
function test(event){
var e = eventUtil.getEvent(event);
alert("1="+e);
var element = eventUtil.getElement(e);
element.value = '33333333';
alert("2="+element);
}
var btn = document.getElementById('btn');
eventUtil.addHandler(btn,'click',test);
</script>
</body>
</html>
在非ie中
<html>
<head></head>
<body>
<div id="div1">1111111111
<div id="div2">2222222222</div>
</div>
<input type="button" id="btn" />
<a href="
http://www.baidu.com" id="mya">163</a>
<a href="javascript:;" >普通按钮,不跳转</a>
<script type="text/javascript">
document.getElementById('btn').onclick = function(event){
//在非ie中
alert(event.type);
alert(event.target);
}
document.getElementById('mya').onclick = function(event){
alert(event.cancelable);
if(event.cancelable){
event.preventDefault();//阻止事件的发生
}
}
document.getElementById('btn').onclick = function(event){
//alert(1);
event.stopPropagation();//阻止事件的传播
}
document.body.onclick=function(){
//alert(2);
}
</script>
</body>
</html>
在ie中
<html>
<head></head>
<body>
<div id="div1">1111111111
<div id="div2">2222222222</div>
</div>
<input type="button" id="btn" />
<a href="
http://www.baidu.com" id="mya">163</a>
<a href="javascript:;" >普通按钮,不跳转</a>
<script type="text/javascript">
var event;
function getEvent(){
event=window.event;
}
document.getElementById('btn').onclick = function(event){
getEvent();
alert(event.type);
alert(event.srcElement);//得到目标元素
event.cancelBubble = true;//取消事件冒泡
event.returnValue = false;//取消默认行为
}
//使用下面的方法可以在参数中得到event
document.getElementById('btn').attachEvent('onclick',function(event){
});
</script>
</body>
</html>
<html>
<head></head>
<body>
<div id="div1">1111111111
<div id="div2">2222222222</div>
</div>
<script type="text/javascript">
var EventUtil = {
addHandler:function(element,type,handler){
if(element.addEventListener){
element.addEventListener(type,handler,false);
}else if(element.attachEvent){
element.attachEvent('on'+type,handler);
}else {
element['on'+type]=handler;
}
},
removeHandler:function(element,type,handler){
if(element.addEventListener){
element.removeEventListener(type,handler,false);
}else if(element.attachEvent){
element.detachEvent('on'+type,handler);
}else {
element['on'+type]=null;
}
}
}
function alertid(){
alert(this.id);
}
var div1 = document.getElementById('div1');
var div2 = document.getElementById('div2');
EventUtil.addHandler(div2,'click',alertid);
//EventUtil.removeHandler(div2,'click',alertid);
//ie
//div1.attachEvent('onclick',alertid);
//div2.attachEvent('onclick',alertid);
//非ie
//div1.addEventListener('click',alertid,true);
//div2.addEventListener('click',alertid,true);
</script>
</body>
</html>
JavaScript 的事件是以一种流的形式存在的,一个事件会有多个元素同时响应。有时候这不是我们想要的,我们只需要某个特定的元素响应我们的绑定事件就可以了。
事件分类
捕获型事件(非IE)、冒泡型事件(所有浏览器都支持)
捕获型事件是自上而下的,而冒泡型事件是自下而上的。下面我用一个图来直观表示:

冒泡型事件我们在工作中可能会比较多遇到,但捕获型事件怎样才会执行到呢,如果我们想要在非 IE 浏览器中要创建捕获型事件,只需将 addEventListener 的第三个参数设为true就好了。

第三个参数false代表在冒泡时运行,true代表在捕获时运行。
ID为div1和div2的两个元素都被绑定了捕捉阶段的事件处理函数,这样:
当点击#div1(蓝色区域)时,应该会alert出”div1″ 当点击#div2(黄色区域)时,应该会先alert出”div1″,再alert出”div2″,因为在事件捕捉阶段,事件是从根元素向下传播的,#div1是#div2的父元素,自然绑定在#div1上的click事件也会先于#div2上的click事件被执行。
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>冒泡事件</title> <script type="text/javascript"> var i = 1; function Add(sText,objText) { document.getElementById("Console").innerHTML +=sText + "执行顺序:" + i + "<br />" + "<hr />"; i = i + 1; //window.event.cancelBubble = true; } </script> </head> <body onclick="Add('body事件触发<br />','body')"> <div onclick="Add('div事件触发<br />','div')"> <p onclick="Add('p事件触发<br />','p')" style="background:#c00;">点击</p> </div> <div id="Console" style="border:solid 1px #ee0; background:#ffc;"></div> </body>
从这个例子我们可以很清楚的看到事件冒泡是从目标元素 P 一直上升到 body 元素。
例子:
<html>
<head></head>
<body>
<div id="div1">1111111111
<div id="div2">2222222222</div>
</div>
<script type="text/javascript">
function alertid(){
alert(0);
}
var div1 = document.getElementById('div1');
var div2 = document.getElementById('div2');
//ie
div1.attachEvent('onclick',alertid);
div2.attachEvent('onclick',alertid);
//非ie
//div1.addEventListener('click',alertid,true);
//div2.addEventListener('click',alertid,true);
</script>
</body>
</html>
在javascript操作css中,如果css的属性是比如background-color中间有横线的,在javascript操作是要遵守驼峰命名法,如mydiv.style.backgroundColor='blue';
在点击让图片显示和隐藏时css中style.visibility=’hidden’,让图片隐藏但是不释放空间,style.display=’none’,图片隐藏并且释放空间,style.display=’block’,图片显示,style.visibility=’visible’,图片显示。
一个定时不断改变颜色的例子:
<html>
<head>
<style type="text/css" >
#mydiv{
width:100px;
height:100px;
}
</style>
</head>
<body>
<div id="mydiv" ></div>
<input id="start" type="button" value="start" onclick="start()"/>
<input id="end" type="button" value="end" onclick="end()"/>
<script type="text/javascript">
var count = 4;
var now = 1;
function changea(){
var mydiv = document.getElementById('mydiv');
if(now==1){
mydiv.style.backgroundColor='blue';
}
if(now==2){
mydiv.style.backgroundColor='red';
}
if(now==3){
mydiv.style.backgroundColor='black';
}
if(now==4){
mydiv.style.backgroundColor='yellow';
}
now++;
// alert(now);
if(now>=5){
now=1;
}
var a =setTimeout(changea,1000);
}
changea();
</script>
</body>
</html>
package com.test.yjw;
public class Sort {
//冒泡
/**
*
*/
public static void bubbleSort(int a[]) {
int len = a.length;
for (int i = 0; i < len - 1; i++) {
for (int j = 0; j < len - 1 - i; j++) {
if (a[j] > a[j + 1]) {
int temp = a[j];
a[j] = a[j + 1];
a[j + 1] = temp;
}
}
}
for(int t : a){
System.out.println(t);
}
}
//选择排序
public static void selectSort(int a[]) {
int temp = 0;
int len = a.length;
for (int i = 0; i < len - 1; i++) {
int min = a[i];
int index = i;
for (int j = i + 1; j < len; j++) {
if (min > a[j]) {
min = a[j];
index = j;
}
}
temp = a[i];
a[i] = a[index];
a[index] = temp;
}
for(int t : a){
System.out.println(t);
}
}
// 插入排序{9,5,1,3,7,8,6,2,0,4}
public static void insertSort(int a[]) {
int len = a.length;
for (int i = 1; i < len; i++) {
int temp = a[i];// 待插入的值
int index = i;// 待插入的位置
while (index > 0 && a[index - 1] > temp) {
a[index] = a[index - 1];// 待插入的位置重新赋更大的值
index--;// 位置往前移
}
a[index] = temp;
}
for(int t : a){
System.out.println(t);
}
}
//快速排序
public static void quickSort(int a[], int low, int height) {
if (low < height) {
int result = partition(a, low, height);
quickSort(a, low, result - 1);
quickSort(a, result + 1, height);
}
}
public static int partition(int a[], int low, int height) {
int key = a[low];
while (low < height) {
while (low < height && a[height] >= key)
height--;
a[low] = a[height];
while (low < height && a[low] <= key)
low++;
a[height] = a[low];
}
a[low] = key;
return low;
}
public static void swap(int a[], int i, int j) { // 通过临时变量,交换数据
int tmp = a[i];
a[i] = a[j];
a[j] = tmp;
} // 第一次交换分析
public static void quicksort(int a[], int low, int high) { // 假设传入low=0; high=a.length-1;
if (low < high) { // 条件判断
int pivot, p_pos, i; // 声明变量
p_pos = low; // p_pos指向low,即位索引为0位置 ;
pivot = a[p_pos]; // 将0位置上的数值赋给pivot;
for (i = low + 1; i <= high; i++) { // 循环次数, i=1;
if (a[i]>pivot) { // 1位置的数与0位置数作比较: a[1]>a[0]
p_pos++; // 2位与1位比较,3位与2位比较......
swap(a, p_pos, i); // 传参并调用swap
}
}
swap(a, low, p_pos); // 将p_pos设为high再次调用swap
quicksort(a, low, p_pos - 1); // 递归调用,排序左半区
quicksort(a, p_pos + 1, high); // 递归调用,排序右半区
}
}
public static void main(String[] args) {
int[] a =new int[]{9,5,1,3,7,8,6,2,0,4};
//Sort.bubbleSort(a);
//Sort.selectSort(a);
//Sort.insertSort(a);
Sort.quickSort(a, 0, a.length-1);
for(int t : a){
System.out.println(t);
}
}
}
在java语言 I/O库的设计中,使用了两个结构模式,即装饰模式和适配器模式。
在任何一种计算机语言中,输入/输出都是一个很重要的部分。与一般的计算机语言相比,java将输入/输出的功能和使用范畴做了很大的扩充。因此输入输出在java语言中占有极为重要的位置。
java语言采用流的机制来实现输入/输出。所谓流,就是数据的有序排列,流可以是从某个源(称为流源,或者 Source of Stream)出来,到某个目的(Sink of Stream)地去。根据流的方向可以将流分成输出流和输入流。程序通过输入流读取数据,想输出流写出数据。
例如:一个java程序可以使用FileInputStream类从一个磁盘文件读取数据,如下图:

像FileInputStream这样的处理器叫流处理器。一个流处理器就像一个流的管道一样,从一个流源吸入某种类型的数据,并输出某种类型的数据。上面的示意图叫流的管道图。
类似地,也可以用FileOutputStream类向一个磁盘文件写数据,如下图:

在实际的应用当中,这样简单的机制并没有太大的用处。程序需要写出的往往是非常结构话的信息,因此这些Byte类型的数据实际上是一些数字、文字、源代码等。java的I/O库提供了一个称作链接(Chaining)的机制,可以将一个流处理器与另一个流处理器首尾相接,以其中之一的输出为输入,形成一个流管道的链接。
例如,DateInputStream流处理器可以把FileInputStream流对象的输出当做输入,将Byte类型的数据转换成java的原始数据类型和String数据类型,如下图:

类似地,向一个文件中写入Byte类型的数据也不是一个简单的过程。一个程序需要向一个文件里写入的数据往往是结构化的,而Byte类型则是原始的类型,因此,在写入的时候必须首先经过转换。DateOutputStream流处理器提供了接受原始数据类型和String数据类型的方法,而这个流处理器的输出数据则是Byte类型。换而言之,DateOutputStream可以将源数据转换成Byte类型的数据,在输出出来。
这样一来,就可以将DateOutputStream与FileOutputStream链接起来。这样做的结果就是,程序可以将原始数据类型和String数据类型的源数据写到这个链接好的双重管道里面,达到将结构话数据写到磁盘文件里的目的,如下图所示:

这是链接的威力。
流处理器所处理的流必定都有流源,如果将流类所处理的流源分类的话,那么基本可以分成两大类:
(1)数组、String、File等,这一种叫原始流源。
(2)同样类型的流用做链接流类的流源,就叫做链接流源。
java I/O库的设计原则
java语言的I/O库是对各种常见的流源、流汇以及处理过程的抽象化。客户端的java 程序不必知道最终的的流源、流汇是磁盘上的文件还是一个数组,或者是一个线程;也不比插手到诸如数据是否缓存、可否按照行号读取等处理的细节中去。
要理解java I/O 这个庞大而复杂的库,关键是掌握两个对称性和两个设计模式。
java I/O库的两个对称性
java I/O库具有两个对称性,它们分别是:
(1)输入-输出对称:比如InputStream 和OutputStream 各自占据Byte流的输入和输出的两个平行的等级结构的根部;而Reader和Writer各自占据Char流的输入和输出的两个平行的等级结构的根部。
(2)byte-char对称:InputStream和Reader的子类分别负责byte和插入流的输入;OutputStream和Writer的子类分别负责byte和Char流的输出,它们分别形成平行的等级结构。
java I/O库的两个设计模式
ava I/O库的总体设计是符合装饰模式和适配器模式的。如前所述,这个库中处理流的类叫流类。
装饰模式:在由InputStream、OutputStream、Reader和Writer代表的等级结构内部,有一些流处理器可以对另一些流处理器起到装饰作用,形成新的、具有改善了的功能的流处理器。
适配器模式:在由InputStream、OutputStream、Reader和Writer代表的等级结构内部,有一些流处理器是对其他类型的流处理器的适配。这就是适配器的应用。
装饰模式的应用
装饰模式在java中的最著名的应用莫过于java I/O标准库的设计了。
由于java I/O库需要很多性能的各种组合,如果这些性能都是用继承来实现,那么每一种组合都需要一个类,这样就会造成大量行重复的类出现。如果采用装饰模式,那么类的数目就会大大减少,性能的重复也可以减至最少。因此装饰模式是java I/O库基本模式。
装饰模式的引进,造成灵活性和复杂性的提高。因此在使用 java I/O 库时,必须理解java I/O库是由一些基本的原始流处理器和围绕它们的装饰流处理器所组成的。
InputStream类型中的装饰模式 InputStream有七个直接的具体子类,有四个属于FilterInputStream的具体子类,如下图所示:

上图中所有的类都叫做流处理器,这个图叫做(InputStream类型)流处理器图。根据输入流的源的类型,可以将这些流分为两种,即原始流类和链接流处理器。
原始流处理器
原始流处理器接收一个Byte数组对象、String对象、FileDescriptor对象或者不同类型的流源对象(就是前面所说的原始流源),并生成一个InputStream类型的流对象。在InputStream类型的流处理器中,原始流处理器包括以下四种:
(1)ByteArrayInputStream:为多线程的通讯提供缓冲区操作工作,接受一个Byte数组作为流的源。
(2)FileInputStream:建立一个与文件有关的输入流。接受一个File对象作为流的源。
(3)PipedInputStream:可以和PipedOutputStream配合使用,用于读入一个数据管道的数据。接受一个PipedOutputStream作为源。
(4)StringBufferInputStream:将一个字符串缓冲区抓换为一个输入流。接受一个String对象作为流的源。
与原始流处理器相对应的是链接流处理器。
链接流处理器
所谓链接流处理器就是可以接受另一个(同种类的)流对象(就是链接流源)作为流源,并对之进行功能扩展的类。InputStream类型的链接流处理器包括以下几种,它们接受另一个InputStream对象作为流源。
(1)FilterInputStream称为过滤输入流,它将另一个输入流作为流源。这个类的子类包括以下几种:
BufferInputStream:用来从硬盘将数据读入到一个内存缓冲区中,并从此缓冲区提供数据。
DateInputStream:提供基于多字节的读取方法,可以读取原始数据类型的数据。
LineNumberInputStream:提供带有行计算功能的过滤输入流。
PushbackInputStream: 提供特殊的功能,可以将已读取的直接“推回”输入流中。
(2)ObjectInputStream 可以将使用ObjectInputStream串行化的原始数据类型和对象重新并行化。
(3)SequenceInputStream可以将两个已有的输入流连接起来,形成一个输入流,从而将多个输入流排列构成一个输入流序列。
必须注意的是,虽然PipedInuptStream接受一个流对象PipedOutputStream作为流的源,但是PipedOutputStream流对象的类型不是InputStream,因此PipedInputStream流处理器仍属于原始流处理器。
抽象结构图

上面流处理器图与装饰模式的结构图有明显的相同之处。实际上InputStream类型的流处理器结构确实符合装饰模式,而这可以从它们在结构中所扮演的角色中分辩出来。
装饰模式的各个角色 在所有InputStream类型的链接流处理其中,使用频率最大的就是FilterInputStream类,以这个类为抽象装饰角色的装饰模式结构非常明显和典型。以这个类为核心说明装饰模式的各个角色是由哪些流处理器扮演:
抽象构件(Component)角色:由InputStream扮演。这是一个抽象类,为各种子类型处理器提供统一的接口。
具体构建(Concrete Component)角色:由ByteArrayInputStream、FileInputStream、PipedInputStream以及StringBufferInputStream等原始流处理器扮演。它们实现了抽象构建角色所规定的接口,可以被链接流处理器所装饰。
抽象装饰(Decorator)角色:由FilterInputStream扮演。它实现了InputStream所规定的接口。
具体装饰(Concrete Decorator)角色:由几个类扮演,分别是DateInputStream、BufferedInputStream 以及两个不常用到的类LineNumberInputStream和PushbackInputStream。
链接流其实就是装饰角色,原始流就是具体构建角色,如下图所示:

一方面,链接流对象接受一个(同类型的)原始流对象或者另一个(同类型的)链接流对象作为流源;另一方面,它们都对流源对象的内部工作方法做了相应的改变,这种改变是装饰模式所要达到的目的。比如:
(1)BufferedInputStream “装饰” 了InputStream的内部工作方式,使得流的读入操作使用缓冲机制。在使用了缓冲机制后,不会对每一次的流读入操作都产生一个物理的读盘动作,从而提高了程序的效率。在涉及到物理流的读入时,都应当使用这个装饰流类。
(2)LineNumberInputStream和PushbackInputStream也同样“装饰”了InputStream的内部工作方式,前者使得程序能够按照行号读入数据;后者能使程序在读入的过程中退后一个字符。后两个装饰类可能在实际的编程工作中很少用到,因为它们是为了支持用java语言做编译器而准备的。
(3)DateInputStream子类读入各种不同的原始数据类型以及String类型的数据,这一点可以从它提供的各种read()方法看出来:
readByte()、readUnsignedByte()、readShort()、readUnsignedShort()、readChar()、readInt()、readLong()、readFloat()、readDouble()、readUTF()。使用这个流处理器以及它的搭档DateOutputStream,可以将原始数据通过流从一个地方移到另一个地方。
OutputStream 类型中的装饰模式 outputStream是一个用于输出的抽象类,它的接口、子类的等级结构、子类的功能都和InputStream有很好的对称性。在OutputStream给出的接口里,将write换成read就得到了InputStream的接口,而其具体子类则在功能上面是平行的。
(1)针对byte数字流源的链接流类,以ByteArrayInputStream描述输入流,以ByteArrayOutputStream描述输出流。
(2)针对String流源的链接流类,以StringBufferInputStream描述输入流,以StringBufferOutputStream描述输出流。
(3)针对文件流源的链接流类,以FileInputStream描述输入流,以FileOutputStream描述输出流。
(4)针对数据管道流源的链接流类,以PipedInputStream描述输入流,以PipedOutputStream描述输出流。
(5)针对以多个流组成的序列,以SequenceInputStream描述输入流,以SequenceOutputStream描述输出流。
OutputStream类型有哪些子类
outputStream有5个直接的具体子类,加上三个属于FilterInputStream的具体子类,一共有8个具体子类,如下图:
原始流处理器
在OutputStream类型的流处理器中,原始流处理器包括以下三种:
ByteArrayOutputStream:为多线程的通信提供缓冲区操作功能。输出流的汇集是一个byte数组。
FileOutputStream:建立一个与文件有关的输出流。输出流的汇集是一个文件对象。
PipedOutputStream: 可以与PipedInputStream配合使用,用于向一个数据管道输出数据。
链接流处理器 OutputStream类型的链接流处理器包括以下几种:
(1)FilterOutputStream:称为过滤输出流,它将另一个输出流作为流汇。这个类的子类有如下几种:
BufferedOutputStream:用来向一个内存缓冲区中写数据,并将此缓冲区的数据输入到硬盘中。
DataOutputStream:提供基于多字节的写出方法,可以写出原始数据类型的数据。
PrintStream:用于产生格式化输出。System.out 静态对象就是一个
PrintStream。
(2)ObjectOutputStream 可以将原始数据类型和对象串行化。
装饰模式的各个角色
在所有的链接流处理器中,最常见的就是FilterOutputStream类。以这个类为核心的装饰模式结构非常明显和典型,如下图:

装饰模式所涉及的各个角色:
抽象构件(Component)角色:由OutputStream扮演,这是一个抽象类,为各种的子类型流处理器提供统一的接口。
具体构件(Concrete Component)角色:由ByteArrayOutputStream、FileOutputStream、PipedOutputStream等扮演,它们均实现了OutputStream所声明的接口。
抽象装饰(Decorator)角色:由FilterOutputStream扮演,它与OutputStream有相同的接口,而这正是装饰类的关键。
具体装饰(Concrete Decorator)角色:由几个类扮演,分别是BufferedOutputStream、DateOutputStream、以及PrintStream。
所谓链接流,就是装饰模式中的装饰角色,原始流就是具体构件角色。
与DateInputStream相对应的是DataOutputStream,后者负责将由原始数据类型和String对象组成的数据格式化,并输出到一个流中,使得任何机器上的任何DataInputStream类型的对象都可以读入这些数据。所有的方法都是以write开始。
如果需要对数据进行真正的格式化,以便输出到像控制台显示那样,那就需要使用PrintStream。
PrintStream可以对由原始数据类型和String对象组成的数据进行格式化,以形成可以阅读的格式;而DataOutputStream则不同,它将数据输出到一个流中,以便DataInputStream可以在任何机器而后操作系统中都可以重新将数据读入,并进行结构重建。
PrintStream对象最重要的两个方法是print() 和println(),这两个方法都是重载的,以便可以打印出所有使用类型的数据。这两个方法之间的区别是后者每行结束时多打印出一个换行符号。
BufferedOutputStream对一个输出流进行装饰,使得流的写出操作使用缓冲机制。在使用缓冲机制后,不会对每一次的流的写入操作都产生一个物理的写动作,从而提高的程序的效率。在涉及到物理流的地方,比如控制台I/O、文件I/O等,都应当使用这个装饰流处理器。
Reader类型中的装饰模式 在Reader类型的流处理器中,
原始流处理器包括以下四种:
(1)CharArrayReader:为多线程的通信提供缓冲区操作功能。
(2)InputStreamReader:这个类有一个子类--FileReader。
(3)PipedReader:可以与PipedOutputStream配合使用,用于读入一个数据管道的数据。
(4)StringReader:建立一个与文件有关的输入流。
链接流处理器包括以下:
(1)BufferedReader:用来从硬盘将数据读入到一个内存缓冲区,并从此缓冲区提供数据,这个类的子类为
LineNumberReader。
(2)FilterReader:成为过滤输入流,它将另一个输入流作为流的来源。这个类的子类有PushbackReader,提供基于多字节的读取方法,可以读取原始数据类型的数据,Reader类型的类图如下所示:

Reader类型中,装饰模式所涉及的各个角色:
(1)抽象构建(Component)角色:有Reader扮演。这是一个抽象类,为各种的子类型流处理器提供统一的接口。
(2)具体构建(Concrete Component)角色:由CharArrayReader、InputStreamReader、PiPedReader、StringReader等扮演,他们均实现了Reader所声明的接口。
(3)抽象装饰(Decorator)角色:由BufferedReader和FilterReader扮演。这两者有着与Reader相同的接口,它们分别给出两个装饰角色的等级结构,第一个给出LineNumberReader作为具体装饰角色,另一个给出PushbackReader 作为具体装饰角色。
(4)具体装饰(Concrete Decorator)角色:LineNumberReader作为BufferedReader的具体装饰角色,BufferedReader作为FilterReader的具体装饰角色。
如下图所示,标有聚合连线的就是抽象装饰角色:
Writer类型中的装饰模式 Writer类型是一个与Reader类型平行的等级结构,而且Writer类型的等级结构几乎与Reader的等级结构关于输入/输出是对称的。如图所示:

在Writer类型的流处理器中,原始流处理器包括以下四种:
(1)CharArrayWriter:为多线程的通信提供缓冲区的操作功能。
(2)OutputStreamWriter:建立一个与文件有关的输出流。含有一个具体子类FileWrite,为Write类型的输出流提供文件输出功能。
(3)PipedWriter:可以和PipedOutputStream配合使用,用于读如果一个数据管道的数据。
(4)StringWriter:想一个StringBuffer写出数据。
链接流处理器包括以下三种:
(1)BufferedWriter:为Writer类型的流处理器提供缓冲区功能。
(2)FilterWriter:称为过滤输入流,它将另一个输入流作为流的来源。这是一个没有子类的抽象类。
(3)PrintWriter:支持格式化的文字输出。
Writer类型中,装饰模式所涉及的各个角色:
(1)抽象构建(Component)角色:由Write扮演。这是一个抽象类,为为各种子类型的流处理器提供统一的接口。
(2)具体构建(Concrete Component):角色由
CharArrayWriter、OutputStreamWriter、
PipedWriter、StringWriter扮演,它们实现了Writer所声明的接口。 (3)抽象装饰(Decorator)角色:由
BufferedWriter、FilterWriter、PrintWriter扮演,它们有着与Write
相同的接口。
(4)具体装饰(Concrete Decorator)角色:与抽象装饰角色合并。
如下图所示,标出了从抽象装饰角色到抽象构件角色的聚合连线,更易于与装饰模式的结构图比较。
适配器模式的应用
适配器模式是java I/O库中第二个最重要的设计模式。
InputStream原始流处理器中的适配器模式 InputStream类型的原始流处理器是适配器模式的应用。
ByteArrayInputStream是一个适配器类
ByteArrayInputStream继承了InputStream的接口,而封装了一个byte数组。换而言之,它将一个byte数组的接口适配成了InputStream流处理器的接口。
java语言支持四种类型:java类、java接口、java数组和原始类型。前三章是引用类型,类和数组的实例都是对象,原始类型的值不少对象。java语言的数组是像所有其他对象一样的对象,而不管数组中所存放的元素的类型是什么。这样一来,ByteArrayInputStream就符合适配器模式的描述,而且是一个对象形式的适配器类。如下图所示:
StringBufferInputStream是一个适配器类
StringBufferInputStream继承了InputStream类型,同时持有一个对String类型的引用。这是将String对象适配成InputStream类型的对象形式的适配器模式,如下图:
OutputStream原始流处理器中的适配器模式
在OutputStream类型中,所有的原始流处理器都是适配器类。
ByteArrayOutputStream是一个适配器类
ByteArrayOutputStream继承了OutputStream类型,同事持有一个对byte数组的引用。它把一个byte数组的接口适配成OutputStream类型的接口,因此也是一个对象类型的适配器模式的应用。如下图:

FileOutputStream是一个适配器类
FileOutputStream继承OutputStream,同时持有一个对FileDescriptor对象的引用。这是一个将FileDescriptor适配成OutputStream接口的对象形式的适配器模式,如下图所示:

PipedOutputStream是一个适配器类
PipedOutputStream总是和PipedInputStream一起使用,它接收一个类型为PipedInputStream的输入类型,并将之转换成OutputStream类型的输出流,这是一个对象形式的适配器模式应用。如下图:

Reader原始流处理器中的适配器模式
Reader 类型的原始流处理器都是适配器模式的应用。
CharArrayReader是一个适配器类。
CharArrayReader将一个Char数组适配成Reader类型的输入流,因此它是一个对象形式的适配器应用,如下图所示:

StringReader是一个适配器类
StringReader 继承了Reader类型,持有一个对String类型的引用。它将String的接口适配成Reader类型的接口,如下图所示:
Writer类型中的适配器模式
Writer类型中的原始流处理器就是适配器模式的具体应用。
CharArrayWriter是一个适配器类。
CharArrayWriter将一个Char数组适配成Writer 接口,如下图所示:

PipedWriter是一个适配器类
PipedWriter总是与PiPedReader一同使用,它将一个PipedReader对象的接口适配成一个Writer类型的接口,如下图所示:

StringWriter是一个适配器类
StringWriter继承Writer类型,同时持有一个StringBuffer对象,它将StringBuffer对象的接口适配成为了
Writer类型的接口,是一个对象形式的适配器 模式的应用,如下图所示:

从byte流到char流的适配
在java语言的标准库 java I/O 里面,有一个InputStreamReader类叫做桥梁(bridge)类。InputStreamReader是从byte流到char流的一个桥梁,它读入byte数据并根据指定的编码将之翻译成char数据。
InputStreamReader虽然叫“桥梁”,但它不爽桥梁模式,是适配器模式的应用。
InputStreamReader
InputStreamReader是从byte输入流到char输入流的一个适配器。下图所示就是InputStreamReader 的结构图:

为了说明适配器类InputStreamReader是如何使用,请看下面例子。Echo类可以将控制台输入的任何字符串从新打印出来,源代码如下:
Echo.java
01 |
package com.think.cla; |
03 |
import java.io.BufferedReader; |
04 |
import java.io.IOException; |
05 |
import java.io.InputStreamReader; |
09 |
public static void main(String [] args) throws IOException{ |
11 |
InputStreamReader input = new InputStreamReader(System.in); |
12 |
System.out.println( "Enter data and push enter:" ); |
13 |
BufferedReader reader = new BufferedReader(input); |
14 |
line = reader.readLine(); |
15 |
System.out.println( "Data entered :" +line); |
可以看出,这个类接受一个类型为inputStream的System.in对象,将之适配成Reader类型,然后再使用
BufferedReader类“装饰”它,将缓冲功能加上去。这样一来,就可以使用BufferedReader对象的readerLine()
方法读入整行的输入数据,数据类型是String。
在得到这个数据之后,程序又将它写出到System.out 中去,完成了全部的流操作,下图所示为其管道图:
本系统使用了BufferedReader来为流的读入提供缓冲功能,这样做的直接效果是可以使用readLine()方法按行读入数据。但是由于Reader接口并不提供readLine()方法,所以这样一来,系统就必须声明一个BufferedReader类型的流处理器,而不是一个Reader类型的流处理器,这意味着装饰模式的退化。
在上面的管道连接过程中,InputStreamReader 起到了适配器的作用,它将一个byte类型的输入流适配成为一个char类型的输入流。在这之后,BufferedReader则起到了装饰模式的作用,将缓冲机制引入到流的读入中。因此这个例子涉及到了两个设计模式。
package com.scpii.ent.util;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.xssf.usermodel.XSSFCell;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import com.scpii.ent.mode.bean.DataSet;
public class ExcelOperClass {
private static String EXCEL_2003 = ".xls";
private static String EXCEL_2007 = ".xlsx";
public static void readExcelJXL() {
}
/**
* 通过POI方式读取Excel
*
* @param excelFile
*/
public static DataSet readExcelPOI(String filePath, Integer cons) throws Exception {
File excelFile = new File(filePath);
if (excelFile != null) {
String fileName = excelFile.getName();
fileName = fileName.toLowerCase();
if (fileName.toLowerCase().endsWith(EXCEL_2003)) {
DataSet dataSet = readExcelPOI2003(excelFile, cons);
return dataSet;
}
if (fileName.toLowerCase().endsWith(EXCEL_2007)) {
DataSet dataSet = readExcelPOI2007(excelFile, cons);
return dataSet;
}
}
return null;
}
/**
* 读取Excel2003的表单
*
* @param excelFile
* @return
* @throws Exception
*/
private static DataSet readExcelPOI2003(File excelFile, Integer rCons)
throws Exception {
List<String[]> datasList = new ArrayList<String[]>();
Set<String> colsSet = new HashSet<String>();
InputStream input = new FileInputStream(excelFile);
HSSFWorkbook workBook = new HSSFWorkbook(input);
// 获取Excel的sheet数量
Integer sheetNum = workBook.getNumberOfSheets();
// 循环Sheet表单
for (int i = 0; i < sheetNum; i++) {
HSSFSheet sheet = workBook.getSheetAt(i);
if (sheet == null) {
continue;
}
// 获取Sheet里面的Row数量
Integer rowNum = sheet.getLastRowNum() + 1;
for (int j = 0; j < rowNum; j++) {
if (j>rCons) {
System.out.println("===========");
HSSFRow row = sheet.getRow(j);
if (row == null) {
continue;
}
Integer cellNum = row.getLastCellNum() + 1;
String[] datas = new String[cellNum];
for (int k = 0; k < cellNum; k++) {
HSSFCell cell = row.getCell(k);
if (cell == null) {
continue;
}
if (cell != null) {
cell.setCellType(HSSFCell.CELL_TYPE_STRING);
String cellValue = "";
int cellValueType = cell.getCellType();
if (cellValueType == cell.CELL_TYPE_STRING) {
cellValue = cell.getStringCellValue();
}
if (cellValueType == cell.CELL_TYPE_NUMERIC) {
Double number = cell.getNumericCellValue();
System.out.println("字符串+++=========="+number.intValue());
cellValue = cell.getNumericCellValue() + "";
}
if (rCons==k) {
colsSet.add(cellValue);
}
System.out.println(cellValue);
datas[k] = cellValue;
}
}
datasList.add(datas);
}
}
}
DataSet dataSet = new DataSet(null, null, datasList, colsSet);
return dataSet;
}
/**
* 读取Excel2007的表单
*
* @param excelFile
* @return
* @throws Exception
*/
private static DataSet readExcelPOI2007(File excelFile, Integer rCons) throws Exception {
List<String[]> datasList = new ArrayList<String[]>();
Set<String> cosSet = new HashSet<String>();
InputStream input = new FileInputStream(excelFile);
XSSFWorkbook workBook = new XSSFWorkbook(input);
// 获取Sheet数量
Integer sheetNum = workBook.getNumberOfSheets();
for (int i = 0; i < sheetNum; i++) {
XSSFSheet sheet = workBook.getSheetAt(i);
if (sheet == null) {
continue;
}
// 获取行值
Integer rowNum = sheet.getLastRowNum() + 1;
for (int j = 0; j < rowNum; j++) {
if (j > rCons) {
System.out.println("=============");
XSSFRow row = sheet.getRow(j);
if (row == null) {
continue;
}
Integer cellNum = row.getLastCellNum() + 1;
String[] datas = new String[cellNum];
for (int k = 0; k < cellNum; k++) {
XSSFCell cell = row.getCell(k);
if (cell==null) {
continue;
}
if (cell != null) {
cell.setCellType(XSSFCell.CELL_TYPE_STRING);
String cellValue = "";
int cellValueType = cell.getCellType();
if (cellValueType == cell.CELL_TYPE_STRING) {
cellValue = cell.getStringCellValue();
}
if (cellValueType == cell.CELL_TYPE_NUMERIC) {
Double number = cell.getNumericCellValue();
System.out.println("字符串+++=========="+number.toString());
cellValue = cell.getNumericCellValue() + "";
}
System.out.println(cellValue);
if (rCons == k) {
cosSet.add(cellValue);
}
datas[k] = cellValue;
}
}
datasList.add(datas);
}
}
}
DataSet dataSet = new DataSet(null, null, datasList,cosSet);
return dataSet;
}
public static void main(String[] args) {
// try {
// DataSet dataSet = readExcelPOI("D:\\部门员工资料.xls", 0);
// System.out.println("================================");
// Set<String> datas = dataSet.getConStrctSet();
// String[] datastr = new String[datas.size()];
// datastr = datas.toArray(datastr);
// for (int i = 0; i < datastr.length; i++) {
// System.out.println(datastr[i]);
// }
// } catch (Exception e) {
// e.printStackTrace();
// }
System.out.println(52%4);
}
}
package com.scpii.ent.mode.bean;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
public class DataSet {
private String[] headers;
private String[] rowHeaders;
private List<String[]> datasList = new ArrayList<String[]>();
private Set<String> conStrctSet;
public DataSet(String[] headers, String[] rowHeaders,
List<String[]> datasList, Set<String> conStrctSet) {
this.headers = headers;
this.rowHeaders = rowHeaders;
this.datasList = datasList;
this.conStrctSet = conStrctSet;
}
public DataSet(String[] header, String[] rowsHeader,
List<String[]> datasList2) {
this.headers = header;
this.rowHeaders = rowsHeader;
this.datasList = datasList2;
}
public String[] getHeaders() {
return headers;
}
public void setHeaders(String[] headers) {
this.headers = headers;
}
public String[] getRowHeaders() {
return rowHeaders;
}
public void setRowHeaders(String[] rowHeaders) {
this.rowHeaders = rowHeaders;
}
public List<String[]> getDatasList() {
return datasList;
}
public void setDatasList(List<String[]> datasList) {
this.datasList = datasList;
}
public Set<String> getConStrctSet() {
return conStrctSet;
}
public void setConStrctSet(Set<String> conStrctSet) {
this.conStrctSet = conStrctSet;
}
}
Jquery框架为jquery对象定义了独立使用的方法和属性,它无法直接调用dom对象的方法,dom对象也无法直接调用jquery对象的方法和属性。
Jquery对象和dom对象是可以相互转换的,因为他们所操作的对象都是dom元素,只不过jquery对象包含了多个dom元素,而dom对象本身就是一个dom元素,简单地说,jquery对象是dom元素的数组,称为类数组,而dom对象就是单个的dom元素。
1.把jquery对象转换成dom对象
(1)借助数组下标来读取jquery对象集合中的某个dom元素对象。
Var $li = $(‘li’);//jquery对象
Var li = $li[0];//dom对象
(2)借助jquery对象的get()方法
Var $li = $(‘li’);//jquery对象
Var li = $li.get(0);//dom对象
2.dom对象转换为jquery对象
Var li = document.getElementsByTagName(‘div’);
Var $li = $(li[o]);//把第一个div元素封装为jquery对象
Var li = document.getElementsByTagName(‘div’);
Var $li = $(li);//把所以的div元素封装为jquery对象
Load事件必须等到网页中所以内容全部加载完毕后才执行。
当网页中内容很多时,load事件就会延迟
Jquery的ready事件是在dom结构绘制完毕后就执行,也就是说它在外部文件加载之前就执行了,ready事件先于load事件。
Load事件只能被编写一次,但是ready事件可以在同一个文档中多次定义。
<html>
<head>
</head>
<body>
<div class="panel"/>wlecome</div>
<script type="text/javascript" src="jquery-1.5.1.min.js"></script>
<script type="text/javascript">
$(document).ready(function(){
$('<input type="button" value="click me" /><input type="button" value="triggle click me" /><input type="button" value="detach handler" /><input type="button" value="show/hide text" />').appendTo($('body'));
$('input[type="button"]')
.eq(0).click(function(){
$(this).val("红色").addClass('red'); }).end().eq(1).click(function(){
alert(1);
}).end().eq(2).click(function(){
alert(2);
}).end().eq(3).toggle(function(){
$('.panel').hide('slow');
},function(){
$('.panel').show('slow');
}
);
});
</script>
</body>
<html/>
<tbody>
<tr>
<td width="20"><input type="checkbox" /></td>
<td>第二行</td>
</tr>
</tbody>
创建tbody中的内容
var tr = document.createElement('tr');
var ck_td = document.createElement('td');
var txt_td = document.createElement('td');
var ck = document.createElement('input');
var todo = document.createTextNode('第二行');
ck_td.setAttribute('width','20');
ck.setAttribute('type','checkbox');
ck_td.appendChild(ck);
txt_td.appendChild(todo);
tr.appendChild(ck_td);
tr.appendChild(txt_td);
document.getElementsByTagName('tbody')[0].appendChild(tr);
其他方法
tr.parentNode;//得到tr的父节点
tr.removeChild(td);//删除tr节点的子节点td
tr.nextElementSibling;//tr的下一个同级元素
tr.nextSibling;//tr的下一个同级元素//
<html>
<head>
</head>
<body>
<script type="text/javascript">
//继承之对象冒充方式,可以继承多个父类
function user(name){
this.name = name;
this.sayname = function(){
alert(this.name);
}
}
function student(name,score){
//user(name);
this.temp = user;
this.temp(name);
delete this.temp;
this.score = score;
this.sayscore = function(){
alert(this.score);
}
}
var s = new student('tom',33);
//s.sayname();
//s.sayscore();
//用call()函数实现继承
function user(name){
this.name = name;
this.sayname = function(){
alert(this.name);
}
}
function student(name,score){
user.call(this,name);
this.score = score;
this.sayscore = function(){
alert(this.score);
}
}
var s = new student('tom',33);
//s.sayname();
//s.sayscore();
//用apply()函数实现继承
function user(name){
this.name = name;
this.sayname = function(){
alert(this.name);
}
}
function student(name,score){
user.apply(this,[name]);
this.score = score;
this.sayscore = function(){
alert(this.score);
}
}
var s = new student('tom',33);
//s.sayname();
//s.sayscore();
//原型链方式实现继承
//1.将父类中所用通过prototype设置的属性或方法放到子类中
//2.并覆盖子类中所以的prototype的设置
//3.所以子类自己的所以的prototype的设置要放在继承父类的下面
//4.缺点是不支持多个继承,构造函数不能有参数
function user(){}
user.prototype.name = '';
user.prototype.say = function(){
alert(this.name);
}
function student(){}
student.prototype =new user();
student.prototype.age = 0;
student.prototype.show = function(){
alert(this.age);
}
var s = new student();
s.name = 'tom';
s.age = 44;
//s.say();
//s.show();
//alert(s instanceof user);
//alert(s instanceof student);
//混合模式实现继承
function user(name){
this.name = name;
}
user.prototype.sayname = function(){
alert(this.name);
}
function student(name){
user.call(this.name);
}
//将user中所有通过prototype设置的方法放到student中
student.prototype = new user();
student.prototype.age = 0;
student.prototype.sayage = function(){
alert(this.age);
}
var s = new student();
s.name = 'tom';
s.age = 44;
s.sayname();
s.sayage();
alert(s instanceof user);
alert(s instanceof student);
</script>
</body>
<html/>
function stringbuffer(){
this.array = new Array();
}
stringbuffer.prototype.append = function(s){
this.array.push(s);
}
stringbuffer.prototype.tostring = function(){
return this.array.join('-');
}
var sb = new stringbuffer();
sb.append('tom');
sb.append('lily');
alert( sb.tostring());
<html>
<head>
</head>
<body>
<script type="text/javascript">
//工厂模式创建对象,缺点是不能知道对象的类型
function createUser(name,age){
var o = {};
o.name=name;
o.age=age;
o.say=function(){
alert(this.name);
}
return o;
}
//user1 = createUser("tom",11);
//alert(user1.name);
//user2 = createUser("tom1",111);
//user2.say();
//构造函数创建对象。缺点是对象中的方法需要写在构造函数外面,有可能写很多方法
function user(name,age){
this.name=name;
this.age = age;
this.say = say;
}
function say(){
alert(this.name);
}
//var user1 = new user("tom",44);
//var user2 = new user("lily",66);
//alert(user1.name);
//user2.say();
//alert(user1 instanceof user);
//原型模式,缺点是不能有构造函数
function user(){}
user.prototype.name='';
user.prototype.age = 0;
user.prototype.address = [];
user.prototype.say = function(){
alert(this.name);
}
var user1 = new user();
user1.name = 'tom';
user1.age = 11;
user1.address = [1,2];
//user1.address.push("1","2");
var user2 = new user();
user2.name = 'lily';
user2.age = 22;
user2.address = [3,4];
//user2.address.push("3","4");
//alert(user1.name);
//alert(user1.age);
//alert(user1.address);
//user1.say();
//alert(user2.name);
//alert(user2.age);
//alert(user2.address);
//user2.say();
//构造函数+原型模式,构造方法构造属性,原型模式构造方法
function user(name,age){
this.name = name;
this.age = age;
this.address = ['1','2'];
}
user.prototype.say = function(){
alert(this.name);
}
var user1 = new user('tom',11);
var user2 = new user('lily',22);
user1.address.push('a','b');
user2.address = ['cc','dd'];
alert(user1.address);
alert(user2.address);
//动态原型模式
function user(name,age){
this.name = name;
this.age = age;
this.address = ['1','2'];
if(typeof this.say != 'function'){
user.prototype.say = function(){
alert(this.name);
}
}
}
var user1 = new user('tom',11);
var user2 = new user('lily',22);
alert(user1.say==user2.say);
</script>
</body>
<html/>
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>My JSP 'car.jsp' starting page</title>
</head>
<body>
<select id="car" onchange="sendAjax()">
<option>-- 请选择汽车品牌 --</option>
<option value="bmw">宝马</option>
<option value="audi">奥迪</option>
<option value="benz">奔驰</option>
</select>
<select id="type" onchange="sendType()">
<option>-- 请选择系列 --</option>
</select>
<script type="text/javascript">
var xmlHttp;
/*创建XMLHttpRequest对象*/
function createXMLHttpRequest() {
if(window.ActiveXObject) {
//IE
xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
} else {
//chrome firefox opera
xmlHttp = new XMLHttpRequest();
}
}
function sendAjax(){
createXMLHttpRequest();
var name = document.getElementById("car").value;
xmlHttp.onreadystatechange = callback;//回调函数
xmlHttp.open("GET","car.jspx?name="+name,true);
xmlHttp.send();
}
function callback() {
if(xmlHttp.readyState == 4) {
if(xmlHttp.status == 200) {
var xml = xmlHttp.responseXML;
var types = xml.getElementsByTagName("recode");
document.getElementById("type").options.length = 1;
for(var i = 0;i < types.length;i++) {
//alert(types[i].childNodes[0].nodeValue);
var myOption = new Option(types[i].childNodes[0].nodeValue,types[i].childNodes[0].nodeValue);
document.getElementById("type").options.add(myOption);
}
} else {
alert("Ajax Error1!");
}
}
}
function sendType(){
createXMLHttpRequest();
var name = document.getElementById("type").value;
xmlHttp.onreadystatechange = callback2;//回调函数
xmlHttp.open("GET","ajax.jspx?name="+name,true);
xmlHttp.send();
}
function callback2() {
if(xmlHttp.readyState == 4) {
if(xmlHttp.status == 200) {
var result = xmlHttp.responseText;
alert(result);
}
} else {
alert("Ajax Error2!");
}
}
</script>
</body>
</html>
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class CarServlet extends HttpServlet {
/**
*
*/
private static final long serialVersionUID = 1L;
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
//DB取出数据
Map<String, List<String>> data = new HashMap<String, List<String>>();
List<String> bmwList = new ArrayList<String>();
bmwList.add("521");
bmwList.add("621");
bmwList.add("721");
bmwList.add("821");
bmwList.add("X6");
List<String> audiList = new ArrayList<String>();
audiList.add("A1");
audiList.add("A2");
audiList.add("A3");
audiList.add("A4");
audiList.add("A5");
audiList.add("A6");
audiList.add("A8");
List<String> benzList = new ArrayList<String>();
benzList.add("B1");
benzList.add("B2");
benzList.add("B3");
benzList.add("B4");
benzList.add("B5");
data.put("bmw", bmwList);
data.put("audi", audiList);
data.put("benz", benzList);
//----------------------------------------------------------
String name = request.getParameter("name");
List<String> dataList = data.get(name);
response.setContentType("text/xml;charset=UTF-8");
PrintWriter out = response.getWriter();
out.print("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
out.print("<data>");
for(String str : dataList) {
out.print("<recode>"+str+"</recode>");
}
out.print("</data>");
out.flush();
out.close();
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet( request, response);
}
}
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class AjaxServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
@Override
protected void service(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
System.out.println("method:" + request.getMethod());
String name = request.getParameter("name");
System.out.println("Hello! " + name);
response.setContentType("text/html");
PrintWriter out = response.getWriter();
/* if("tom".equals(name)) {
out.print("error");
} else {
out.print("ok");
}*/
out.print(name);
out.flush();
out.close();
}
}
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>My JSP 'index.jsp' starting page</title>
</head>
<body>
<input type="text" id="name" onblur="sendAjax()"/>
<img src="img/ajax.gif" style="display:none" id="loading"/>
<span id="result"></span>
<br/>
<!--
<input type="button" value="Send Ajax" onclick="sendAjax()"/>
-->
<script type="text/javascript">
var xmlHttp;
/*创建XMLHttpRequest对象*/
function createXMLHttpRequest() {
if(window.ActiveXObject) {
//IE
xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
} else {
//chrome firefox opera
xmlHttp = new XMLHttpRequest();
}
}
function sendAjax(){
createXMLHttpRequest();
var name = document.getElementById("name").value;
//post
xmlHttp.open("POST", "ajax.jspx", true);
xmlHttp.onreadystatechange = callback;
xmlHttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
xmlHttp.send("name="+name);
//get
//xmlHttp.open("GET","ajax.jspx?name="+name,true);
//xmlHttp.onreadystatechange = callback;
//xmlHttp.send();
}
function callback() {
if(xmlHttp.readyState == 4) {//服务器响应返回
document.getElementById("loading").style.display = "none";
if(xmlHttp.status == 200) {//响应正确
var result = xmlHttp.responseText;
if(result == "ok") {
document.getElementById("result").innerHTML = "√";
} else {
document.getElementById("result").innerHTML = "用户名已占用";
}
} else {
alert("Ajax Error!");
}
} else {
//进度条
document.getElementById("loading").style.display = "inline";
}
}
</script>
</body>
</html>
<html>
<head>
<script type="text/javascript">
var user = {name:'tom',age:'22'};
alert(user.name);
alert(user["name"]);
delete user.name;//删除属性
alert("name" in user);//判断属性是否在对象中






</script>
</head>
</html>
<html>
<head>
<script type="text/javascript">
function save(n1,n2){
function fn(){
return n1+n2;
}
return fn();
}
alert(save(2,3));
//闭包第一种
function test(){
var num = 10;
function inner(){
alert(num);
}
inner();
}
//test();
//闭包第二种
function add(n1,n2){
return function(){
return n1+n2;
}
}
//alert(add(2,3)());
</script>
</head>
</html>
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;
public class JdbcTest {
public static void main(String[] args) throws ClassNotFoundException,SQLException {
//1.加载数据库驱动(提供一个jdbc的数据库驱动的名称)
Class.forName("com.mysql.jdbc.Driver");
//2.获取数据库连接
String url = "jdbc:mysql:///gooddb";
Connection conn = DriverManager.getConnection(url, "root", "root");
//3.获取Statment对象(该对象用于对数据库进行CRUD操作)
Statement stat = conn.createStatement();
//4.执行SQL语句
//String sql = "INSERT INTO t_class(classname) VALUES('java07')";
String sql = "UPDATE t_class SET classname = 'sql01' WHERE id = 2";
//executeUpdate()方法用于执行insert、update、delete语句,该方法返回影响数据库的行数
int rows = stat.executeUpdate(sql);
if(rows > 0) {
System.out.println("操作成功!");
}
//5.释放连接
stat.close();
conn.close();
}
}
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
public class SelectTest {
public static void main(String[] args) {
Connection conn = null;
Statement stat = null;
ResultSet rs = null;
try {
Class.forName("com.mysql.jdbc.Driver");
conn = DriverManager.getConnection("jdbc:mysql:///gooddb","root","root");
stat = conn.createStatement();
String sql = "select id,classname from t_class";
//获取结果集对象
rs = stat.executeQuery(sql);
while(rs.next()) {
//int id = rs.getInt("id");
int id = rs.getInt(1);
//String name = rs.getString("classname");
String name = rs.getString(2);
System.out.println("id:" + id + "\tclassname:" + name);
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
} finally {
//释放连接
try {
if(rs != null) {
rs.close();
}
} catch (SQLException e) {
e.printStackTrace();
} finally {
try {
if(stat != null) {
stat.close();
}
} catch (SQLException e) {
e.printStackTrace();
} finally {
try {
if(conn != null) {
conn.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
}
}
package com.tCalendar.d;
/*
* java.util.Calendar 类学习
*/
import java.text.SimpleDateFormat;
/**
*
* @author Icer
*/
public class TCalendar {
private static SimpleDateFormat sDateFormat = new SimpleDateFormat("yyyyMMdd");
private String dayInfo[][];
private int dayCount;//间隔天数
public static void main(String[] args) {
String startDate = "20120101";
String endDate = "20120102";
TCalendar tCalendar = new TCalendar();
tCalendar.initDayInfo(startDate, endDate);
System.out.println("天数: " + tCalendar.getDayCount());
}
public void initDayInfo(String start,String end)
{
//初始化日期信息
java.util.Calendar cal1=java.util.Calendar.getInstance();
java.util.Calendar cal2=java.util.Calendar.getInstance();
java.util.Calendar cal3=java.util.Calendar.getInstance();
int year,month,day;
int i=0;
year=Integer.parseInt(start.substring(0,4));
month=Integer.parseInt(start.substring(4,6));
day=Integer.parseInt(start.substring(6,8));
cal1.set(year, month-1, day);
cal3.set(year, month-1, day);
year=Integer.parseInt(end.substring(0,4));
month=Integer.parseInt(end.substring(4,6));
day=Integer.parseInt(end.substring(6,8));
cal2.set(year, month-1, day);
while(!cal2.before(cal3))
{
i++;
cal3.add(java.util.Calendar.DAY_OF_MONTH, 1);//日期时间+1
}
//每日数据列表
dayInfo=new String[i+1][3];
i=0;
while(!cal2.before(cal1))
{
System.out.println("==" + cal1.getTime());
dayInfo[i][0]=sDateFormat.format(cal1.getTime());
i++;
cal1.add(java.util.Calendar.DAY_OF_MONTH, 1);
}
this.dayCount=i;
for (int j=0;j<i;j++)
{
this.dayInfo[j][1]="0";
this.dayInfo[j][2]="0";
}
}
public int getDayCount() {
return dayCount;
}
public void setDayCount(int dayCount) {
this.dayCount = dayCount;
}
public String[][] getDayInfo() {
return dayInfo;
}
public void setDayInfo(String[][] dayInfo) {
this.dayInfo = dayInfo;
}
}
package com.fanshe.obj;
import java.lang.reflect.*;
import java.io.IOException;
/**
*获取指定类的构造器相关信息
*/
public class ConstructorTest
{
private int i;
private double j;
//默认的构造器
public ConstructorTest(){
}
//重载的构造器
public ConstructorTest(int i,double j)throws IOException{
this.i=i;
this.j=j;
}
public static void main(String[] args) throws Exception
{
//得到本类的类对象
Class<?> cls=Class.forName("com.fanshe.obj.ConstructorTest");
//取得所有在本类声明的构造器
Constructor<?> []cs=cls.getDeclaredConstructors();
//遍历
System.out.println("----------------");
for(Constructor<?> c:cs){
//构造器名称
System.out.println("构造器名="+c.getName());
//构造器声明所在的类
System.out.println("其声明的类="+c.getDeclaringClass());
//取得参数的类型集合
Class<?> []ps=c.getParameterTypes();
//遍历参数类型
for(int i=0;i<ps.length;i++){
System.out.println("参数类型"+i+"="+ps[i]);
}
//取得异常的类型集合
Class<?> []es=c.getExceptionTypes();
//遍历异常类型
for(int j=0;j<es.length;j++){
System.out.println("异常类型"+j+"="+es[j]);
}
//结束一层循环标志
System.out.println("-----------");
}
}
}
package com.fanshe.obj;
import java.lang.reflect.*;
/**
*通过反射创新类的新对象
*/
class CreateNewObj
{
//显式默认的构造器
public CreateNewObj(){
}
//重载构造器
public CreateNewObj(int a,int b){
System.out.println("a= "+a+" b="+b);
}
public static void main(String[] args) throws Exception
{
//得到本类的类对象
Class<?> c=Class.forName("com.fanshe.obj.CreateNewObj");
//声明构造器的参数类型集合
Class<?> []paramTypes=new Class[2];
//都为int型
paramTypes[0]=Integer.TYPE;
paramTypes[1]=Integer.TYPE;
//根据参数类型决定得到哪个构造器
Constructor<?> cs=c.getConstructor(paramTypes);
//声明要传入的参数集合
Object []argList=new Object[2];
//传入37和43
argList[0]=new Integer(37);
argList[1]=new Integer(43);
//根据符合上述参数类型的构造器来创建新的对象
Object rtnObj=cs.newInstance(argList);
}
}
package com.fanshe.obj;
import java.lang.reflect.*;
/**
*获取指定类的字段相关信息
*/
class FieldTest
{
//字段1
private double d;
//字段2
public static final int i=37;
//字段3
String str="fieldstest";
public static void main(String[] args) throws Exception
{
//获取本类的类对象
Class<?> c=Class.forName("com.fanshe.obj.FieldTest");
//获取所有声明的的字段,getFields()包括继承来的字段
Field []fs=c.getDeclaredFields();
//遍历
for(int i=0;i<fs.length;i++){
Field f=fs[i];
//字段名
System.out.println("字段名"+(i+1)+"="+f.getName());
//字段声明所在的类
System.out.println("该字段所在的类为:"+f.getDeclaringClass());
//字段的类型
System.out.println("字段"+(i+1)+"的类型:"+f.getType());
//查看修饰符
int mod=f.getModifiers();
//为0就是默认的包类型
if(mod==0){
System.out.println("该字段的修饰符为:默认包修饰符");
}else{
//否则就是相应的类型
System.out.println("该字段的修饰符为:"+Modifier.toString(mod));
}
System.out.println("---结束第"+(i+1)+"循环---");
}
}
}
package com.fanshe.obj;
import java.lang.reflect.*;
/**
*获取指定类的方法相关信息
*/
class InformationTest
{
public static void main(String[] args) throws Exception
{
//得到String类对象
Class<?> cls=Class.forName("java.lang.String");
//得到所有的方法,包括从父类继承过来的方法
Method []methList=cls.getMethods();
//下面是得到的是String类本身声明的方法
//Method []methList=cls.getDeclaredMethods();
//遍历所有的方法
for(Method m:methList){
//方法名
System.out.println("方法名="+m.getName());
//方法声明所在的类
System.out.println("声明的类="+m.getDeclaringClass());
//获取所有参数类型的集体
Class<?> []paramTypes=m.getParameterTypes();
//遍历参数类型
for(int i=0;i<paramTypes.length;i++){
System.out.println("参数 "+i+" = "+paramTypes[i]);
}
//获取所有异常的类型
Class<?> []excepTypes=m.getExceptionTypes();
//遍历异常类型
for(int j=0;j<excepTypes.length;j++){
System.out.println("异常 "+j+" = "+excepTypes[j]);
}
//方法的返回类型
System.out.println("返回类型 ="+m.getReturnType());
//结束一层循环标志
System.out.println("---------");
}
}
}
package com.fanshe.obj;
import java.lang.reflect.*;
/**
*通过反射改变字段的值
*/
class ModifyField
{
//声明一个字段
public double d;
public static void main(String[] args) throws Exception
{
//得到类的类对象
Class<?> c=Class.forName("com.fanshe.obj.ModifyField");
//根据字段名得到字段对象
Field f=c.getField("d");
//创建类的实例
ModifyField mf=new ModifyField();
//打印修改前字段的值
System.out.println("修改 "+f.getName()+" 前的值为:"+mf.d);
//修改d的值为12.34
f.setDouble(mf,12.34);
//打印修改后的值
System.out.println("修改 "+f.getName()+" 后的值为:"+mf.d);
}
}
package com.fanshe.obj;
import java.lang.reflect.*;
/**
*通过反射执行类的方法
*/
class PerformMethod
{
//声明一个简单的方法,用于测试
public int add(int a,int b){
return a+b;
}
public static void main(String[] args)throws Exception
{
//获取本类的类对象
Class<?> c=Class.forName("com.fanshe.obj.PerformMethod");
/**
*声明add方法参数类型的集合
*共有两个参数,都为Integer.TYPE
*/
Class<?> []paramTypes=new Class[2];
paramTypes[0]=Integer.TYPE;
paramTypes[1]=Integer.TYPE;
//根据方法名和参数类型集合得到方法
Method method=c.getMethod("add",paramTypes);
//声明类的实例
PerformMethod pm=new PerformMethod();
//传入参数的集合
Object []argList=new Object[2];
//传入37和43
argList[0]=new Integer(37);
argList[1]=new Integer(43);
//执行后的返回值
Object returnObj=method.invoke(pm,argList);
//类型转换下
Integer returnVal=(Integer)returnObj;
//打印结果
System.out.println("方法执行结果为:"+returnVal.intValue());
}
}
package com.fanshe.obj;
import java.lang.reflect.*;
/**
*通过反射来操作数组
*/
class UserArray
{
public static void main(String[] args) throws Exception
{
//得到String类的类对象
Class<?> c=Class.forName("java.lang.String");
//通过Array类的反射创建一个含有10个元素的String类型的数组
Object arr=Array.newInstance(c,10);
//为数组第5个位置元素赋一个值
Array.set(arr,5,"第5个位置元素");
//取得第5个位置元素的值
String s=(String)Array.get(arr,5);
//打印这个元素的值
System.out.println("值为:"+s);
}
}
package com.fanshe.obj;
import java.lang.reflect.*;
/**
*通过反射创建和使用更复杂的数组
*/
class UserArrayComplex
{
public static void main(String[] args) throws Exception
{
//声明数组的维数为5X10X15
int dims[]=new int []{5,10,15};
//创建该类型的数组,元素的类型为Integer
Object arr=Array.newInstance(Integer.TYPE,dims);
//得到第3个10X15的二维数组
Object arrObj=Array.get(arr,3);
//Class c=arrObj.getClass().getComponentType();
//System.out.println(c);
//得到第2维中的第2个15位长度的数组
arrObj=Array.get(arrObj,5);
//然后设置该数组里第10个元素的值为37
Array.set(arrObj,10,37);
//再将数组还原
int [][][]arrCast=(int [][][])arr;
//打印刚刚那个值
System.out.println(arrCast[3][5][10]);
}
}
门面模式是对象的结构模式,外部与一个子系统的通信必须通过一个统一的门面对象进行。门面模式提供一个高层次的接口,使得子系统更易于使用。使用门面模式还有一个附带的好处,就是能够有选择性地暴露方法。一个模块中定义的方法可以分成两部分,一部分是给子系统外部使用的,一部分是子系统内部模块之间相互调用时使用的。有了Facade类,那么用于子系统内部模块之间相互调用的方法就不用暴露给子系统外部了。public interface ServiceA {
void methodA() ;
}
public class ServiceAImpl implements ServiceA{
@Override
public void methodA() {
System.out.println("这是服务A");
}
}
public interface ServiceB {
void methodB() ;
}
public class ServiceBImpl implements ServiceB{
@Override
public void methodB() {
System.out.println("这是服务B");
}
}
public interface ServiceC {
void methodC() ;
}
public class ServiceCImpl implements ServiceC{
@Override
public void methodC() {
System.out.println("这是服务C");
}
}
public class Facade {
ServiceA sa;
ServiceB sb;
ServiceC sc;
public Facade() {
sa = new ServiceAImpl();
sb = new ServiceBImpl();
sc = new ServiceCImpl();
}
public void methodA() {
sa.methodA();
sb.methodB();
}
public void methodB() {
sb.methodB();
sc.methodC();
}
public void methodC() {
sc.methodC();
sa.methodA();
}
}
测试类:
public class Test {
public static void main(String[] args) {
ServiceA sa = new ServiceAImpl();
ServiceB sb = new ServiceBImpl();
sa.methodA();
sb.methodB();
System.out.println("========");
//facade
Facade facade = new Facade();
facade.methodA();
facade.methodB();
facade.methodC();
}
}
推荐免费下载430套大型商业源码
下载地址:http://www.hur.cn/tg/linkin.asp?linkid=200978
PB-商业源码
金科信进销存软件源码(81M)
制造业管理系统源码(257M)
PB连锁药店GSP源码(136M)
创某医院系统源码(813M)
人力资源管理系统源码(182M)
浪某财务系统源码(131M)
医院系统源码(58M)
医院管理软件门诊挂号收费系统源码(83M)
医疗保险管理系统源码(191M)
拓某连锁专卖宝典源码(90M)
普某ERP系统源码(300M)
科某企业ERP源码(154M)
重庆运通商业连锁系统源码(293M)
供电局MIS管理信息系统源码(196M)
社区信息管理系统源码(122M)
暂住人口管理系统4.0(网络版)源码(25M)
高某医院系统源码(200M)
思某商业管理系统源码(40M)
电子厂用小型ERP系统源码(51M)
点某财务软件源码(121M)
和某ERP系统源码(73M)
医院管理系统源码(956M)
河南医院信息系统源码(400M)
瑞某酒店管理系统源码(48M)
飞某商业管理系统源码(87M)
PowerBuilder 8.0 自定义报表系统(5M)
动态报表系统(10M)
致某动态报表模块源码(5M)
小型商业进销存系统(带POS)(34M)
大型酒店管理最新版本PB8(60M)
中小超市POS综合管理系统(142M)
检查科室报告单管理软件(17M)
商某5.0 POS系统(20M)
威某酒店管理系统(365M)
鞋业ERP系统(繁体)(160M)
新某大财务系统(301M)
医生工作站源码(30M)
宏声人力资源管理系统(41M)
医疗保险系统(37M)
医药卫生综合管理系统(54M)
MIS系统源代码pb9(40M)
PB影碟出租管理系统8.03(14M)
pb-oracle通用开发框架(27M)
PB编写的电子地图源码(5M)
大众医院门诊收费系统(28M)
pb洗浴管理系统(9M)
餐饮管理程序源代码(14M)
仓库管理系统源码(6M)
查询打印数据窗口共享排序定制基类(5M)
长江科学院合同成果管理(27M)
工程造价系统源码(17M)
国泰商业管理系统MIS(135M)
华泰印刷源码(122M)
检查科室报告单管理软件(17M)
金华医院门诊挂号收费系统PB(80M)
酒店管理系统(网络版)(73M)
某配件公司生产管理系统(154M)
某企业财务管理系统(125M)
瑞通hms(245M)
瑞通酒店管理系统V8.0网络版(102M)
商场管理系统源代码pb(15M)
商品进销存管理系统(pb)(9M)
天河进销存POS系统(211M)
物流程序源码(53M)
小型商业进销存系统(带POS)(32M)
鞋业ERP源码(153M)
旭日2000企业管理系统(65M)
血库的软件用pb做(6M)
药品管理(27M)
医疗保险系统pb(258M)
普阳Erp源码(61M)
科研管理系统源码(15M)
酒店管理系统(59M)
Delphi-商业源码
美容院管理系统源码(70M)
MRPII制造资源计划系统源码(147M)
ERP企业管理系统源码(74M)
福某制衣MRP管理系统源码(43M)
胜某进销存系统源码(88M)
立某酒店、餐饮、洗浴、休闲管理系统源码(55M)
实某聊天系统 v3.0源码(71M)
社保管理系统源码(22M)
商业通医药连锁经营管理系统源码(40M)
商业管理系统源码(135M)
日某餐饮系统源码(173M)
企业进销存系统源码(41M)
贸易网站登陆器源码(60M)
遵某的视频会议系统代码源码(26M)
贸易管理系统源码(65M)
酒店管理系统源码(106M)
汽车租赁信息咨询系统源码(62M)
牙科诊所管理系统源码(31M)
制衣MRPII系统源码(65M)
中国眼科病历系统源码(103M)
远程控制源码(20M)
医药连锁源码源码(55M)
语音故障报修系统(需要TW8VID语音卡)源码(18M)
行业应急系统源码(23M)
销售管理系统源码(24M)
洗浴中心管理系统源码(20M)
五金管理信息系统源码(18M)
网络教室系统源码(网络版)源码(58M)
天某ERP系统源码(281M)
医院病案管理系统源码(26M)
VOD点歌系统源码(59M)
国外的财务软件源码(126M)
旅游公司信息系统源码(43M)
人力资源管理系统源码(24M)
POS超市管理系统源码(60M)
POS系统源码(43M)
医院收费与信息管理系统源码(122M)
安某销售系统源码(10M)
GIS系统—有线电视网络设备管理系统源码(30M)
ICQ(客服服务器)源码(55M)
办公自动化系统源代码源码(27M)
仓储物流信息管理系统源码(137M)
传奇游戏源码(178M)
电能表载波抄表软源码(44M)
电子试卷生成系统源码(30M)
美容院管理系统源码(16M)
泰某工程管理软件源码(40M)
环某美容美发管理系统源码(23M)
机房收费管理源码(78M)
计划生育管理系统源码(21M)
驾驶员考试源码(40M)
金某验布系统源码(82M)
进销存系统源码(43M)
超市库存管理系统源码(23M)
中移动大客户管理系统(7M)
思微pos系统(48M)
泰达图书馆工程管理软件源码(24M)
Delphi编写的企业进销存系统源代码(11M)
ENO企业人事信息管理系统(6M)
NiceERP企业系统(42M)
ST进销存源码(12M)
宾馆软件源码(12M)
采购应用系统源码(11M)
超市管理系统源代码(7M)
非常方便的物业管理系统(7M)
钢铁进销存源码(12M)
港汇客户管理系统源码(13M)
海信商业管理系统完整源码版(99M)
进销存ForD7(8M)
牧羊人服饰系统 (ADO+SQL)(6M)
实达企业在线EOL三层系统Delphi源码(11M)
手机营销系统源码(10M)
通用的进销存系统源码(10M)
通用人力资源系统源码(7M)
完整的市一级工资管理程序源码(142M)
西恩软件机房管理源码(26M)
信息管理程序源码(14M)
制衣MRP管理系统源码(45M)
胜天财务进销存2003源码(82M)
AL源码(10M)
DAGL 档案管理程序 v1.0 (SQL Server)(22M)
delphi BookMIS 教材管理系统(7M)
delphi_宏远VOD原代码(45M)
大型企业ERP管理系统(84M)
大型企业邮件管理系统(7M)
delphi_柯龙中草药进销存 v3.0(22M)
delphi_企业管理Erp(64M)
delphi_思微POS连锁超市管理系统(60M)
delphi个人理财软件源码(7M)
delphi名佳商务系统源码(74M)
delphi万家福超市管理系统(17M)
delphi物流供应链管理系统(5M)
delphi医院管理系统(18M)
delphi咏南进销存 两层(C_S)(8M)
NDOA南都办公自动化系统(delphi)(8M)
POS连锁超市管理系统 (商业代码)(60M)
delphi灰鸽子vip1.2 版本(43M)
地磅称量系统(7M)
典当综合业务管理系统(10M)
电子寻更源程序(20M)
东莞和富有限公司进销存管理系统(33M)
动感立体KTV VOD(18M)
工资管理系统(53M)
广电行业GIS系统(10M)
华丝贸易国内销售管理系统(30M)
火锅城管理系统1.0版(10M)
机动车驾驶员无纸化理论考试系统(38M)
局域网即时通信系统(52M)
客房管理系统(网络版)(100M)
客户关系管理系统(CRM)(11M)
力信消费管理系统2000(12M)
龙邦进销存源码(16M)
美容院管理系统修改版(ADO)(21M)
某公司工资管理系统(17M)
某企业ERP企业管理系统(32M)
某通用进销存系统(20M)
配件仓库管理(24M)
企业管理Erp(商业源码)(64M)
全球数码仓库仓储管理信息系统(110M)
思雷特(sunnet)物业管理信息系统(232M)
台湾公司做的一个ERP管理系统(235M)
万佳圆宾馆桑拿洗浴管理系统(20M)
网络营销专家(25M)
维修管理工具(15M)
五金材料商业进销存(23M)
物业管理(22M)
校园网多媒体自动播放系统(10M)
新艺VOD系统(59M)
眼镜行业财务进销存后台管理代码 V1.0v(72M)
异洲酒店(餐饮)管理系统delphi源码(delphi+sql)(20M)
P2P即时通讯源码Delphi(46M)
POS消费管理系统2000delhi源码(12M)
大型超市销售连锁管理系统(16M)
电子寻更源程序delphi(20M)
远程控制DELPHI源代码(17M)
高考网上招生省招办投档系统(11M)
湖南佳某软件公司商业POS通系统delphi源码(98M)
化工颜料生产管理源码(30M)
科技计划信息管理系统delphi源码(22M)
视频会议系统delphi源码(45M)
某医院HIS管理系统delphi源码(86M)
顺某指纹考勤管理系统delphi源码(64M)
delphi超市管理系统源码(16M)
VB-商业源码
新世某ERP5.0升级版源码(796M)
MIS管理信息系統源码(583M)
医药卫生管理系统源码(60M)
制造业ERP系统源码(125M)
专卖店POS系统源码(36M)
售房管理系统源码(89M)
用某u850源码(9M)
易某点歌系统源码(18M)
医院系统源码(202M)
医药管理GSP源码(36M)
新开某酒店系统源码(29M)
网吧管理系统源码(15M)
太平某信息管理系统源码(33M)
金算某财务及企业管理软件源码(134M)
教师住房管理系统源码(12M)
惠某ERP系统源码(442M)
报业广告发行管理系统源码(42M)
宝某售饭系统源码(15M)
新世某ERP5.0完全版源码(399M)
宛某书社图书管理系统源码(9M)
VB+SQL开发银行模拟系统(167M)
VB超巿管理系统(11M)
材料目录软件(10M)
进销存软件(13M)
全球通商务管理系统——POS管理系统(另一版本)(75M)
四季青污水处理厂系统(62M)
网吧管理系统服务器客户端源程序(另一版本)(15M)
住房公积金监管系统(46M)
邮件管理与群发系统(30M)
学生信息管理系统(5M)
通用文档一体化档案管理系统(127M)
升瑞售楼管理系统(60M)
设计系统2000(报表设计与管理系统)(12M)
人力资源管理系统(28M)
网络营销软件(25M)
某企业物资管理信息系统(14M)
某计算机网络管理系统VB(74M)
财务系统源码(70M)
路桥收费系统VB(702M)
大型企业内部管理系统(228M)
伯乐人力资源管理系统2000(161M)
北京市区绿化隔离地区信息系统2000(34M)
学生信息管理系统v1.0(附源码)(5M)
馨香物业管理糸统(13M)
新版图书综合管理系统(6M)
审核管理系统-完整版(35M)
华成酒店管理系统(10M)
大型商业ERP系统2-财务系统部分(65M)
超市销售管理系统(5M)
宾馆桑拿休闲中心管理系统(30M)
宾馆客房管理系统(6M)
vb酒店管理系统(10M)
VB物流管理系统源码(11M)
计划生育管理系统(56M)
vb和Mapx开发的房屋测绘系统GIS商业源码(10M)
乡镇供电所电费处理系统(14M)
VB人事工资管理系统(27M)
VB财务软件源码(19M)
VC-商业源码
网络听诊管理监控系统源码(1540M)
速某(c++)MRPII系统源码(320M)
贸易网站登陆器源码(60M)
工厂自动化生产整合管理系统源码(233M)
高速公路收费系统源码(44M)
北京某大卖场公司自主开发首套linux平台Pos源码(245M)
酒店餐饮管理系统(21M)
伯克公司生产销售系统源码(14M)
企业短信助理源代码(20M)
一个超完整的医药管理系统源码(59M)
综合人事管理系统源码(vc+sql2000)(18M)
综合人事管理系统源码(vc+sql2000)(5M)
Hotel酒店管理系统源码(4M)
POS前台C++程序源码(7M)
quakeIII 源码(26M)
视频会议系统源码(50M)
VC客房管理系统源码(10M)
VC数字图像模式技术及工程应用源码(106M)
串口编程调试及双机互联源码(44M)
代码名称:Microsoft MS-DOS6.0 完整源代码(63M)
家族信息管理系统源码(7M)
酒店管理系统2003(8M)
考勤管理系统源代码下载(9M)
利用MFC开发的OpenGL开发包(27M)
屏幕转换成AVI文件的程序源码(25M)
赛克思书店销售管理系统源码(7M)
数字图像处理源码(30M)
数字图像获取、处理与分析源盘(42M)
图形图象类代码(8M)
用Visual C++开发GIS系统(16M)
游戏编程精粹源码(36M)
云台镜头控制系统源码(20M)
智能安防报警系统源码(37M)
Vc视频会议源代码压缩文件(314M)
VC数字图像模式技术及工程应用(103M)
vc医院门诊收费系统(5M)
互联天下im(95M)
某公司VC视频核心代码(35M)
视频会议开发代码(259M)
视频监控(55M)
视音频代码(35M)
用Visual C++开发GIS系统(15M)
真正的速达源码(CB5可编译)(54M)
IM企业即时通讯软件源代码(18M)
宾馆酒店管理系统源码(25M)
可视电话软件源码(16M)
商品采购管理系统vc源码(25M)
网络视频会议系统vc源码(41M)
.NET-商业源码
和某大型ERP系统源码(510M)
商务管理教学源码(28M)
C#写的网上汽修汽配管理系统(52M)
企业公文管理信息系统(87M)
教材管理中心(3M)
商务之星(ASP.NET)(618M)
物流系统Logistics(v1.0)(217M)
若冰.net远程教育系统(18M)
asp.net+c#的人事系统(2M)
Coffice协同办公管理系统(C#)(176M)
NET的bbs论坛源码(6M)
OA办公自动化系统源码(21M)
嘉惠药品进销存管理系统(vb.net)(55M)
企业内部信息交流系统源码(9M)
若冰企业商务平台.net(31M)
数据结构动画演示系统(c#)DataStructure(8M)
医院管理系统ASP.NET+MSSQL(9M)
中铁五局Mis系统原型设计(9M)
住房公积金管理中ASP.NET+MSSQL(5M)
房地产信息网(c#.net+sql)(6M)
net网上购书系统(11M)
NET药品进销存系统(5M)
net采购仓库核销管理系统(6M)
net计算机基础考试系统(10M)
net精品OA(91M)
net客户关系管理系统(6M)
net企业客户服务系统(5M)
net企业销售管理信息系统(8M)
net汽车销售公司ERP进销存系统(38M)
net图书馆管理系统(11M)
net学生寝室管理系统(12M)
net真正的全动态报表(5M)
net自定义报表(16M)
vb.net 销售管理系统(5M)
vbnet进销存系统源码(6M)
多层架构的大型.NET OA 系统(16M)
客户关系管理系统(8M)
某公司CRM管理系统 net(29M)
三甲医院管理系统HIS(C#版)(27M)
局域网考试系统C#(9M)
进出仓管理系统(17M)
Asp.Net用友华表(V5.1)制作自定义报表(16M)
Asp.net通用OA系统源代码(12M)
C#酒店管理系统(20M)
PowerOA办公自动化系统商业源码(15M)
餐饮管理系统(C#源码)(32M)
公司客户关系管理系统CRM ASP.NET源码(27M)
机械制造业信息管理系统源码(21M)
C#某橱柜销售企业ERP管理系统(16M)
公司的业务管理系统(15M)
商业进销管理系统(47M)
公路运输管理系统asp.net(30M)
汽车销售公司ERP进销存系统(39M)
现代教务管理系统源码(25M)
药店管理系统(33M)
餐饮管理系统源码(10M)
智能办公系统(14M)
JAVA-商业源码
大型企业JAVA的ERP源码(193M)
可乐吧在线游戏最新服务器端及部分源代码源码(18M)
华某物业管理系统源码-JSP源码(97M)
华某物业管理系统安装程序源码(43M)
乐趣大型购物系统源码(7M)
Java做的WebMail源码(9M)
JAVA进销存源码(60M)
哈工大CERP系统源码(17M)
JSP开发的项目跟踪系统源码(11M)
季风进销存管理系统1.1(JSP版)源码(4M)
java框架开源订销管理系统MYSQL(6M)
条形码商品管理信息系统源码(12M)
信用卡管理系统源码(4M)
学生课绩管理系统(5M)
工作流管理系统openwfe源码(38M)
开源网上会议系统iula-0.1.0 java(5M)
java 学生管理系统(全部代码+数据库)(5M)
java超市购物系统(9M)
java网上oa办公系统原码(5M)
JAVA写的个人博客源码(8M)
java阳光酒店管理系统(14M)
投票管理系统java(16M)
宠物销售管理系统 java(11M)
网站在线客服系统(Jsp+MySql)(19M)
企富商贸网 java(12M)
商城之家JSP商城企业版v6.8(15M)
石大在线财务管理系统(含源码)java(5M)
AWT图形设计源代码(9M)
iText可以制作中文PDF文件的JAVA源程序(5M)
Java+sqlserver2000做的员工管理系统(5M)
6JAVA的ICQ系统源码(7M)
Java开发的网络办公系统(33M)
Java设计源码(25M)
Java做的WebMail(9M)
雇员管理系统源码(5M)
酒店管理系统(16M)
员工管理系统(8M)
CRM客户管理系统源代码(12M)
J2EE项目源码DigitalCampus数字校园(17M)
JAVA网上商城项目完整源码(10M)
Java实现图书馆管理系统源码(13M)
Java写的ERP系统(30M)
java大型企业DRP分销系统源码(11M)
CRM项目java源码(10M)
JBuilder固定资产管理系统java项目源码(12M)
基于J2EE三层结构设计ERP源码(12M)
..............
<!-- 配置方法级别的校验 -->
<interceptor-ref name="validation">
<param name="excludeMethods">input,back,cancel,browse</param>
<param name="validateAnnotatedMethodOnly">true</param>
</interceptor-ref>
所以action中的这四个方法不需要验证
// 保存
@Validations(
requiredStrings = {
@RequiredStringValidator(fieldName = "admin.username", message = "用户名不允许为空!"),
@RequiredStringValidator(fieldName = "admin.password", message = "密码不允许为空!"),
@RequiredStringValidator(fieldName = "admin.email", message = "E-mail不允许为空!")
},
requiredFields = {
@RequiredFieldValidator(fieldName = "admin.isAccountEnabled", message = "是否启用不允许为空!")
},
stringLengthFields = {
@StringLengthFieldValidator(fieldName = "admin.username", minLength = "2", maxLength = "20", message = "用户名长度必须在${minLength}到${maxLength}之间!"),
@StringLengthFieldValidator(fieldName = "admin.password", minLength = "4", maxLength = "20", message = "密码长度必须在${minLength}到${maxLength}之间!")
},
emails = {
@EmailValidator(fieldName = "admin.email", message = "E-mail格式错误!")
},
regexFields = {
@RegexFieldValidator(fieldName = "admin.username", expression = "^[0-9a-z_A-Z\u4e00-\u9fa5]+$", message = "用户名只允许包含中文、英文、数字和下划线!")
}
)
一个轻量级的cookie 插件,可以读取、写入、删除 cookie。
jquery.cookie.js 的配置
首先包含jQuery的库文件,在后面包含 jquery.cookie.js 的库文件。
<script type="text/javascript" src="js/jquery-1.6.2.min.js"></script>
<script type="text/javascript" src="js/jquery.cookie.js"></script>
使用方法
1.新添加一个会话 cookie:
$.cookie('the_cookie', 'the_value');
注:当没有指明 cookie有效时间时,所创建的cookie有效期默认到用户关闭浏览器为止,所以被称为
“会话cookie(session cookie)”。
2.创建一个cookie并设置有效时间为 7天:
$.cookie('the_cookie', 'the_value', { expires: 7 });
注:当指明了cookie有效时间时,所创建的cookie被称为“持久 cookie (persistent cookie)”。
3.创建一个cookie并设置 cookie的有效路径:
$.cookie('the_cookie', 'the_value', { expires: 7, path: '/' });
注:在默认情况下,只有设置 cookie的网页才能读取该 cookie。如果想让一个页面读取另一个页面设
置的cookie,必须设置cookie的路径。cookie的路径用于设置能够读取 cookie的顶级目录。将这
个路径设置为网站的根目录,可以让所有网页都能互相读取 cookie (一般不要这样设置,防止出现冲突) 。
4.读取cookie:
$.cookie('the_cookie'); // cookie存在 => 'the_value'
$.cookie('not_existing'); // cookie不存在 => null
5.删除cookie,通过传递null作为cookie的值即可:
$.cookie('the_cookie', null);
----------相关参数的解释---------------
1).expires: 365
定义cookie的有效时间,值可以是一个数字(从创建cookie时算起,以天为单位)或一个Date 对
象。如果省略,那么创建的cookie是会话cookie,将在用户退出浏览器时被删除。
2).path: '/'
默认情况:只有设置cookie的网页才能读取该cookie。
定义cookie的有效路径。默认情况下, 该参数的值为创建 cookie 的网页所在路径(标准浏览器的行为) 。
如果你想在整个网站中访问这个cookie需要这样设置有效路径:path: '/'。如果你想删除一个定义
了有效路径的 cookie,你需要在调用函数时包含这个路径:$.cookie('the_cookie', null,
{ path: '/' });。 domain: 'example.com'
默认值:创建 cookie的网页所拥有的域名。
3).secure: true
默认值:false。如果为true,cookie的传输需要使用安全协议(HTTPS)。
4).raw: true
默认值:false。
默认情况下,读取和写入 cookie 的时候自动进行编码和解码(使用encodeURIComponent 编码,
decodeURIComponent 解码)。要关闭这个功能设置 raw: true 即可。
public class DBHelp<T> {
private static String driver;
private static String url;
private static String username;
private static String password;
private static BasicDataSource dataSource;
static{
Properties properties = new Properties();
try {
//读取到src目录中存放的db.properties配置文件
properties.load(DBHelp.class.getClassLoader().getResourceAsStream("db.properties"));
driver = properties.getProperty("driver");
url = properties.getProperty("url");
username = properties.getProperty("username");
password = properties.getProperty("password");
} catch (IOException e) {
e.printStackTrace();
}
dataSource = new BasicDataSource();
dataSource.setDriverClassName(driver);
dataSource.setUrl(url);
dataSource.setUsername(username);
dataSource.setPassword(password);
dataSource.setInitialSize(5);
dataSource.setMaxWait(5000);
dataSource.setMaxActive(20);
dataSource.setMinIdle(10);
}
public Connection getConnection(){
try {
Connection conn = dataSource.getConnection();
return conn;
} catch (SQLException e) {
e.printStackTrace();
}
return null;
}
public List<T> executeForList(RowMapper<T> rowMapper,String sql) {
Connection conn = null;
PreparedStatement stat = null;
ResultSet rs = null;
List<T> list = new ArrayList<T>();
try {
conn = getConnection();
stat = conn.prepareStatement(sql);
rs = stat.executeQuery();
while(rs.next()) {
list.add(rowMapper.mapperRow(rs));
}
System.out.println("SQL"+sql);
} catch (SQLException e) {
e.printStackTrace();
}finally{
close(rs, stat, conn);
}
return list;
}
public List<T> executeForList(String sql,RowMapper<T> rowMapper,Object... args) {
Connection conn = null;
PreparedStatement stat = null;
ResultSet rs = null;
List<T> list = new ArrayList<T>();
try {
conn = getConnection();
stat = conn.prepareStatement(sql);
for (int i = 0; i < args.length; i++) {
stat.setObject(i+1,args[i]);
}
rs = stat.executeQuery();
while(rs.next()) {
list.add(rowMapper.mapperRow(rs));
}
System.out.println("SQL"+sql);
} catch (SQLException e) {
e.printStackTrace();
}finally{
close(rs, stat, conn);
}
return list;
}
public T executeForObject(String sql,RowMapper<T> rowMapper,Object... args) {
Connection conn = null;
PreparedStatement stat = null;
ResultSet rs = null;
T obj = null;
try {
conn = getConnection();
stat = conn.prepareStatement(sql);
for (int i = 0; i < args.length; i++) {
stat.setObject(i+1, args[i]);
}
rs = stat.executeQuery();
if(rs.next()) {
obj = rowMapper.mapperRow(rs);
}
System.out.println("SQL"+sql);
} catch (SQLException e) {
e.printStackTrace();
}finally{
close(rs, stat, conn);
}
return obj;
}
public int executeForCount(String sql,Object... args){
Connection conn = null;
PreparedStatement stat = null;
ResultSet rs = null;
int count = 0;
try {
conn = getConnection();
stat = conn.prepareStatement(sql);
rs = stat.executeQuery();
for(int i = 0;i < args.length;i++){
stat.setObject(i+1, args[i]);
}
if(rs.next()) {
count = rs.getInt(1);
}
System.out.println("SQL"+sql);
} catch (SQLException e) {
e.printStackTrace();
}finally{
close(rs, stat, conn);
}
return count;
}
public void executeUpdate(String sql,Object... args) {
Connection conn = null;
PreparedStatement stat = null;
try {
conn = getConnection();
stat = conn.prepareStatement(sql);
for(int i = 0;i < args.length;i++){
stat.setObject(i+1, args[i]);
}
stat.executeUpdate();
System.out.println("SQL"+sql);
} catch (SQLException e) {
e.printStackTrace();
}finally{
close(stat,conn);
}
}
public void close(PreparedStatement stat,Connection conn) {
close(null,stat,conn);
}
public void close(ResultSet rs,PreparedStatement stat,Connection conn) {
try {
if(rs != null){
rs.close();
}
} catch (SQLException e) {
e.printStackTrace();
}finally{
try {
if(stat != null) {
stat.close();
}
} catch (SQLException e) {
e.printStackTrace();
}finally{
try {
if(conn != null) {
conn.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
}
public interface RowMapper<T> {
public T mapperRow(ResultSet rs) throws SQLException;
}
public class TourDao {
private DBHelp<Tour> db = new DBHelp<Tour>();
public Tour findByName(String name){
String sql = "SELECT id,tourname FROM t_tour WHERE tourname=?";
Tour t = db.executeForObject(sql, new TourRowMapper(), name);
return t;
}
public void insertSale(String name){
String sql = "INSERT INTO t_tour (tourname) VALUE(?)";
db.executeUpdate(sql, name);
}
public class TourRowMapper implements RowMapper<Tour>{
public Tour mapperRow(ResultSet rs) throws SQLException {
Tour t = new Tour();
t.setId(rs.getInt("id"));
t.setTourname(rs.getString("tourname"));
return t;
}
}
}
备忘录(Memento)模式又称标记(Token)模式。GOF给备忘录模式的定义为:在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。这样以后就可将该对象恢复到原先保存的状态。
其实单就实现保存一个对象在某一时刻的状态的功能,还是很简单的——将对象中要保存的属性放到一个专门管理备份的对象中,需要的时候则调用约定好的方法将备份的属性放回到原来的对象中去。
备忘录模式的组成部分:
1) 备忘录(Memento)角色:备忘录角色存储“备忘发起角色”的内部状态。“备忘发起角色”根据需要决定备忘录角色存储“备忘发起角色”的哪些内部状 态。为了防止“备忘发起角色”以外的其他对象访问备忘录。备忘录实际上有两个接口,“备忘录管理者角色”只能看到备忘录提供的窄接口——对于备忘录角色中 存放的属性是不可见的。“备忘发起角色”则能够看到一个宽接口——能够得到自己放入备忘录角色中属性。
2) 备忘发起(Originator)角色:“备忘发起角色”创建一个备忘录,用以记录当前时刻它的内部状态。在需要时使用备忘录恢复内部状态。
3) 备忘录管理者(Caretaker)角色:负责保存好备忘录。不能对备忘录的内容进行操作或检查。
使用备忘录模式的前提:
1) 必须保存一个对象在某一个时刻的(部分)状态, 这样以后需要时它才能恢复到先前的状态。
2) 如果一个用接口来让其它对象直接得到这些状态,将会暴露对象的实现细节并破坏对象的封装性。
例子如下:
//存储信息类
public class Caretaker {
private Memento memento;
public Memento getMemento(){
return this.memento;
}
public void setMemento(Memento memento){
this.memento = memento;
}
}
//备忘录模式
public class Memento {
private String state;
public Memento(String state) {
this.state = state;
}
public String getState() {
return state;
}
public void setState(String state) {
this.state = state;
}
}
public class Originator {
private String state;
public String getState() {
return state;
}
public void setState(String state) {
this.state = state;
}
public Memento createMemento() {
return new Memento(state);
}
public void setMemento(Memento memento) {
state = memento.getState();
}
public void showState(){
System.out.println(state);
}
}
测试类:
public class Test {
public static void main(String[] args) {
Originator org = new Originator();
org.setState("开会中");
org.showState();//显示
System.out.println("---------------");
Caretaker ctk = new Caretaker();
ctk.setMemento(org.createMemento());//将数据封装在Caretaker
System.out.println("---------------");
org.setState("睡觉中");
org.showState();//显示
System.out.println("---------------");
org.setMemento(ctk.getMemento());//将Caretaker中的数据重新导入
org.showState();
System.out.println("---------------");
}
}
Java深入到一定程度,就不可避免的碰到设计模式这一概念,了解设计模式,将使自己对java中的接口或抽象类应用有更深的理解.设计模式在java的 中型系统中应用广泛,遵循一定的编程模式,才能使自己的代码便于理解,易于交流,Mediator(中介者模式)模式是比较常用的一个模式.
Mediator中介者模式,当多个对象彼此间都有联系的时候,我们就可以应用Mediator将对象间的多对多关系转换为一对多的关系,这样做,可以使各个对象间的耦合松散。统一管理对象间的交互。但也可能使得Mediator对象成为一个系统中的庞然大物,难以维护
使用场景:集中负责维护对象模型的关系完整性 以及需要 封装对象间交互方式的时候.
其实MVC中的controller就是一种Mediator,是UI层 和后端应用sevice层间的中介者。中介者将交互的复杂性变为中介者的复杂性
例子如下:
业务类的接口:
public interface Colleague {
void action();
}
业务类的2个实现类:
public class ColleagueA implements Colleague{
@Override
public void action() {
System.out.println("普通员工努力工作aaaaaaa");
}
}
public class ColleagueB implements Colleague{
@Override
public void action() {
System.out.println("前台注意了bbbb");
}
}
中介者接口:
public interface Mediator {
void notice(String content);
}
public class ConcreteMediator implements Mediator{
private ColleagueA ca;
private ColleagueB cb;
public ConcreteMediator() {
ca = new ColleagueA();
cb = new ColleagueB();
}
public void notice(String content) {
if (content.equals("boss")) {
//老板来了, 通知员工A
ca.action();
}
if (content.equals("client")) {
//客户来了, 通知前台B
cb.action();
}
}
}
测试类:
public class Test {
public static void main(String[] args) {
Mediator med = new ConcreteMediator();
//老板来了
med.notice("boss");
//客户来了
med.notice("client");
}
}
当客户端传过来的字符串不一样时,中介者类根据字符串实现不同的业务类的对象,处理数据。
function isInRect(x, y, x0, y0, x1, y1) {
if (x0 < x && x < x1 && y0 < y && y < y1)
return true;
else
return false;
}
function ElIn(elId) {
var el = Ext.get(elId);
el.fadeIn( {
endOpacity : 1,
easing : 'easeOut',
duration : 2
});
}
function ElOut(elId) {
var el = Ext.get(elId);
el.fadeOut( {
endOpacity : 0,
easing : 'easeOut',
duration : .5,
useDisplay : true
});
// el.dom.style.display = 'none';
}
function getClickScale(event, target, isShowInfo) {
var imageWidth = target.width;
var imageHeight = target.height;
var eventX = event.xy[0];
var eventY = event.xy[1];
var scalex = eventX / imageWidth;
var scaley = eventY / imageHeight;
var info = '';
info += 'image (' + imageWidth + ', ' + imageHeight + '), ';
info += 'click (' + eventX + ', ' + eventY + '), ';
info += 'scale (' + scalex + ', ' + scaley + ')';
if (typeof (isShowInfo) != 'undefined' && isShowInfo) {
alert(info);
}
return {
scalex : scalex,
scaley : scaley
};
}
Ext.get('main-navigator-image').on(
'mousemove',
function(event, target, obj) {
var scale = getClickScale(event, target);
target.style.cursor = '';
for ( var i = 0; i < areas.length; i++) {
var area = areas[i];
if (isInRect(scale.scalex, scale.scaley,
area.p1.scalex, area.p1.scaley,
area.p2.scalex, area.p2.scaley)) {
target.style.cursor = 'pointer';
break;
}
}
});
});
1.在tomcat的service.xml中把端口改成80
2.把自己的项目名称改成ROOT,覆盖tomcat的原ROOT项目,就可以了
var combo = new Ext.form.ComboBox(
{
store : store,
emptyText : '请选择',
mode : 'local',
triggerAction : 'all',
valueField : 'value',
displayField : 'name',
//autoScroll : true,
//length : 4,
//IdValue : 'name',
listeners : {//选择一行后触发的事件
'select' : function() {
var url = combo
.getValue();//得到valueField的值
if (url != null
&& url != '') {
loactionTo(
combo
.getRawValue(),//得到displayField的值
url);
// typeForm.getForm().submit({});
}
}
}
});
hibernate抓取策略(单端代理的批量抓取)
保持默认,同fetch="select",如:
<many-to-one name="classes" column="classesid" fetch="select"/>
fetch="select",另外发送一条select语句抓取当前对象关联实体或集合
设置fetch="join",如:
<many-to-one name="classes" column="classesid" fetch="join"/>
fetch="join",hibernate会通过select语句使用外连接来加载其关联实体或集合
此时lazy会失效
hibernate抓取策略(集合代理的批量抓取)
保持默认,同fetch="select",如:
<set name="students" inverse="true" cascade="all" fetch="select">
fetch="select",另外发送一条select语句抓取当前对象关联实体或集合
设置fetch="join",如:
<set name="students" inverse="true" cascade="all" fetch="join">
fetch="join",hibernate会通过select语句使用外连接来加载其关联实体或集合 此时lazy会失效
设置fetch="subselect",如:
<set name="students" inverse="true" cascade="all" fetch="subselect">
fetch="subselect",另外发送一条select语句抓取在前面查询到的所有实体对象的关联集合
hibernate抓取策略,,batch-size在<class>上的应用
batch-size属性,可以批量加载实体类,参见:Classes.hbm.xml
<class name="Classes" table="t_classes" batch-size="3">
hibernate抓取策略,batch-size在集合上的应用
batch-size属性,可以批量加载实体类,参见:Classes.hbm.xml
<set name="students" inverse="true" cascade="all" batch-size="5">
hibernate 会下先完发sql,再一次性的大数据
实体类父类:
public class Animal {
private int id;
private String name;
private boolean sex;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public boolean isSex() {
return sex;
}
public void setSex(boolean sex) {
this.sex = sex;
}
}
子类:
public class Bird extends Animal {
private int height;
public int getHeight() {
return height;
}
public void setHeight(int height) {
this.height = height;
}
}
public class Pig extends Animal {
private int weight;
public int getWeight() {
return weight;
}
public void setWeight(int weight) {
this.weight = weight;
}
}
extends.hbm.xml文件:
<hibernate-mapping package="com.hibernate">
<class name="Animal" abstract="true">
<id name="id">
<generator class="assigned"/>
</id>
<property name="name"/>
<property name="sex"/>
<union-subclass name="Pig" table="t_pig">
<property name="weight"/>
</union-subclass>
<union-subclass name="Bird" table="t_bird">
<property name="height"/>
</union-subclass>
</class>
</hibernate-mapping>
数据库表如下:
父类实体类:
public class Animal {
private int id;
private String name;
private boolean sex;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public boolean isSex() {
return sex;
}
public void setSex(boolean sex) {
this.sex = sex;
}
}
子类实体类:
public class Bird extends Animal {
private int height;
public int getHeight() {
return height;
}
public void setHeight(int height) {
this.height = height;
}
}
public class Pig extends Animal {
private int weight;
public int getWeight() {
return weight;
}
public void setWeight(int weight) {
this.weight = weight;
}
}
extends.hbm.xml文件:
<hibernate-mapping package="com.hibernate">
<class name="Animal" table="t_animal">
<id name="id">
<generator class="native"/>
</id>
<property name="name"/>
<property name="sex"/>
<joined-subclass name="Pig" table="t_pig">
<key column="pid"/>
<property name="weight"/>
</joined-subclass>
<joined-subclass name="Bird" table="t_bird">
<key column="bid"/>
<property name="height"/>
</joined-subclass>
</class>
</hibernate-mapping>
在数据库中表如下:
public class Animal {
private int id;
private String name;
private boolean sex;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public boolean isSex() {
return sex;
}
public void setSex(boolean sex) {
this.sex = sex;
}
}
public class Bird extends Animal {
private int height;
public int getHeight() {
return height;
}
public void setHeight(int height) {
this.height = height;
}
}
public class Pig extends Animal {
private int weight;
public int getWeight() {
return weight;
}
public void setWeight(int weight) {
this.weight = weight;
}
}
在extends.hbm.xml文件:
<hibernate-mapping package="com.hibernate">
<class name="Animal" table="t_animal" lazy="false">
<id name="id">
<generator class="native"/>
</id>
<discriminator column="type" type="string"/>
<property name="name"/>
<property name="sex"/>
<subclass name="Pig" discriminator-value="P">
<property name="weight"/>
</subclass>
<subclass name="Bird" discriminator-value="B">
<property name="height"/>
</subclass>
</class>
</hibernate-mapping>
理解如何映射
因为类继承树肯定是对应多个类,要把多个类的信息存放在一张表中,必须有某种机制来区分哪些记录是属于哪个类的。
这种机制就是,在表中添加一个字段,用这个字段的值来进行区分。用hibernate实现这种策略的时候,有如下步骤:
父类用普通的<class>标签定义
在父类中定义一个discriminator,即指定这个区分的字段的名称和类型
如:<discriminator column=”XXX” type=”string”/>
子类使用<subclass>标签定义,在定义subclass的时候,需要注意如下几点:
Subclass标签的name属性是子类的全路径名
在Subclass标签中,用discriminator-value属性来标明本子类的discriminator字段(用来区分不同类的字段)
的值Subclass标签,既可以被class标签所包含(这种包含关系正是表明了类之间的继承关系),也可以与class标
签平行。 当subclass标签的定义与class标签平行的时候,需要在subclass标签中,添加extends属性,里面的值
是父类的全路径名称。子类的其它属性,像普通类一样,定义在subclass标签的内部。
实体类是:
public class CollectionMapping {
private int id;
private String name;
private Set setValue;
private List listValue;
private String[] arrayValue;
private Map mapValue;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Set getSetValue() {
return setValue;
}
public void setSetValue(Set setValue) {
this.setValue = setValue;
}
public List getListValue() {
return listValue;
}
public void setListValue(List listValue) {
this.listValue = listValue;
}
public String[] getArrayValue() {
return arrayValue;
}
public void setArrayValue(String[] arrayValue) {
this.arrayValue = arrayValue;
}
public Map getMapValue() {
return mapValue;
}
public void setMapValue(Map mapValue) {
this.mapValue = mapValue;
}
}
在CollectionMapping.hbm.xml文件中:
<hibernate-mapping>
<class name="CollectionMapping" table="t_CollectionMapping">
<id name="id">
<generator class="native"/>
</id>
<property name="name"/>
<set name="setValue" table="t_set_value">
<key column="set_id"/>
<element type="string" column="set_value"/>
</set>
<list name="listValue" table="t_list_value">
<key column="list_id"/>
<list-index column="list_index"/>
<element type="string" column="list_value"/>
</list>
<array name="arrayValue" table="t_array_value">
<key column="array_id"/>
<list-index column="array_index"/>
<element type="string" column="array_value"/>
</array>
<map name="mapValue" table="t_map_value">
<key column="map_id"/>
<map-key type="string" column="map_key"/>
<element type="string" column="map_value"/>
</map>
</class>
</hibernate-mapping>
在数据库中生成5个表
例如:
普通类:
public class Contact {
private String email;
private String address;
private String zipCode;
private String contactTel;
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public String getZipCode() {
return zipCode;
}
public void setZipCode(String zipCode) {
this.zipCode = zipCode;
}
public String getContactTel() {
return contactTel;
}
public void setContactTel(String contactTel) {
this.contactTel = contactTel;
}
}
实体类:
public class User {
private int id;
private String name;
private Contact contact;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Contact getContact() {
return contact;
}
public void setContact(Contact contact) {
this.contact = contact;
}
}
User.hbm.xml文件:
<hibernate-mapping>
<class name="User" table="t_user">
<id name="id">
<generator class="native"/>
</id>
<property name="name"/>
<component name="contact">
<property name="email"/>
<property name="address"/>
<property name="zipCode"/>
<property name="contactTel"/>
</component>
</class>
</hibernate-mapping>
在数据库中在t_user表中含有Contact类的属性字段
<id name="id" column="user_id" length="32">
<!-- 主键自动生成uuid -->
<generator class="uuid"/>
</id>
<id name="id" column="user_id">
<!-- 主键自动增长 -->
<generator class="native"/>
</id>
<id name="id" column="user_id" length="32">
<!-- 主键需要手动定义 -->
<generator class="assigned"/>
</id>
1.先导入dom4j-1.6.1.jar包
2.xml文件如下:
<?xml version="1.0" encoding="UTF-8"?>
<config>
<action name="user" className="com.kaishengit.web.UserAction">
<result name="success" type="forward">suc.jsp</result>
<result name="error" type="redirect">404.jsp</result>
</action>
<action name="book" className="com.kaishengit.web.BookAction">
<result name="success">book.jsp</result>
<result name="error" type="redirect">bookerror.jsp</result>
</action>
<action name="person" className="com.kaishengit.web.PersonAction" method="del">
<result name="ok">suc.jsp</result>
</action>
</config>
3.解析测试类是:
package com.kaishengit.test;
import java.io.File;
import java.net.URL;
import java.util.List;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
public class Dom4jTest {
public void readXML() {
//拿到src文件夹里的xml配置文件
URL url = getClass().getResource("/");
System.out.println(url);
String filePath = url.getFile() + "struts.xml";
try {
//创建读取配置文件的对象
SAXReader reader = new SAXReader();
//开始读取配置文件
Document doc = reader.read(new File(filePath));
//拿到根节点
Element root = doc.getRootElement();
//拿到根节点下的action接点数组
List<Element> actions = root.elements("action");
for(Element action : actions) {
String name = action.attributeValue("name");
String className = action.attributeValue("className");
String method = action.attributeValue("method");
System.out.println("name="+name);
System.out.println("className="+className);
System.out.println("method="+method);
List<Element> results = action.elements("result");
for(Element result : results) {
String resultName = result.attributeValue("name");
String resultType = result.attributeValue("type");
String pageName = result.getText();
System.out.println("name:" + resultName + "\tresultType:" + resultType + "\tpageName:" + pageName);
}
System.out.println("----------------------");
}
} catch (Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
Dom4jTest d = new Dom4jTest();
d.readXML();
}
}
现在写一个用状态模式实现的根据上班时间状态变化而行为变化的小程序,当时间<12上午上班时间,
<13午休时间,<17下午上班时间,<21加班时间,根据时间不同,条用的类方法不同。
状态模式适用于当对象的状态改变时,行为也改变,就可以使用状态模式
状态接口:
public interface State {
void writeProgram(Work work);
}
不同的实现类:
public class AfterNoonState implements State {
@Override
public void writeProgram(Work work) {
if(work.getHour()<17){
System.out.println("工作");
}else {
work.setCurrent(new EveningState());
work.writeProgram();
}
}
}
public class EveningState implements State {
@Override
public void writeProgram(Work work) {
if(work.isFinish()){
work.setCurrent(new RestState());
work.writeProgram();
}else {
if(work.getHour()<21){
System.out.println("加班");
}else {
work.setCurrent(new SleepState());
work.writeProgram();
}
}
}
}
public class ForenoonState implements State {
@Override
public void writeProgram(Work work) {
if(work.getHour()<12){
System.out.println("工作时间");
}else {
work.setCurrent(new NoonState());
work.writeProgram();
}
}
}
public class NoonState implements State {
@Override
public void writeProgram(Work work) {
if(work.getHour()<13){
System.out.println("午睡");
}else {
work.setCurrent(new AfterNoonState());
work.writeProgram();
}
}
}
public class RestState implements State {
@Override
public void writeProgram(Work work) {
System.out.println("回家");
}
}
public class SleepState implements State {
@Override
public void writeProgram(Work work) {
System.out.println("睡觉");
}
}
调用状态的类:
public class Work {
private State current;
public Work(double hour,boolean finish){
current = new ForenoonState();
this.hour = hour;
this.finish = finish;
}
private double hour;
public double getHour() {
return hour;
}
public State getCurrent() {
return current;
}
public void setCurrent(State current) {
this.current = current;
}
private boolean finish;
public boolean isFinish() {
return finish;
}
public void writeProgram(){
current.writeProgram(this);
}
}
测试类:
public class Test {
public static void main(String[] args) {
Work work = new Work(20, true);
work.writeProgram();
}
}

这是表数据
SELECT * FROM t_user WHERE username IS NULL;查询到id=8的数据
SELECT * FROM t_user WHERE username IS NOT NULL;查询到id=11,12,13,14的四条数据
SELECT * FROM t_user WHERE username ='';查询到id=11,12,13的三条数据
SELECT * FROM t_user WHERE username ='aa';查询到id=14的数据
get和load方法都是是利用对象的主键得到对象,并可以使对象处于持久态。
load方法获取对象时不会立即执行查询操作,而是在第一次使用对象是再去执行查询操作。如果查询的对象在数据库中不存在,load方法返回值不会为null,在第一次使用时抛出org.hibernate.ObjectNotFoundException异常。
使用get方法获取对象时会立即执行查询操作,并且对象在数据库中不存在时返回null值。
所以我们在实际使用中多使用get方法,这样我们可以先判断得到的对象是否是null,再操作
1.在配置文件中的配置:
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="com.mysql.jdbc.Driver" />
<property name="jdbcUrl" value="jdbc:mysql:///struts" />
<property name="properties">
<props>
<prop key="user">root</prop>
<prop key="password">root</prop>
</props>
</property>
</bean>
<bean id="simpleJdbcTemplate" class="org.springframework.jdbc.core.simple.SimpleJdbcTemplate">
<constructor-arg ref="dataSource"></constructor-arg>
</bean>
<bean id="userSimpleJdbcTemplateDao" class="com.yjw.dao.UserSimpleJdbcTemplateDao">
<property name="simpleJdbcTemplate" ref="simpleJdbcTemplate"></property>
</bean>
2.dao中的写法:
package com.yjw.dao;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.jdbc.core.simple.SimpleJdbcTemplate;
import com.yjw.bean.User;
public class UserSimpleJdbcTemplateDao {
private SimpleJdbcTemplate simpleJdbcTemplate;
public void setSimpleJdbcTemplate(SimpleJdbcTemplate simpleJdbcTemplate) {
this.simpleJdbcTemplate = simpleJdbcTemplate;
}
public void save(User user){
String sql = "INSERT INTO t_user (username,PASSWORD) VALUES (?,?)";
simpleJdbcTemplate.update(sql, user.getUsername(),user.getPassword());
}
public void update(User user){
String sql = "UPDATE t_user SET username=:username ,PASSWORD=:password WHERE id=:id?";
simpleJdbcTemplate.update(sql, user.getUsername(),user.getPassword(),user.getId());
}
public void delete(int id){
String sql = "delete from t_user where id=?";
simpleJdbcTemplate.update(sql, id);
}
private class UserRowmapper implements RowMapper<User> {
public User mapRow(ResultSet rs, int rowNum) throws SQLException {
User u = new User();
u.setId(rs.getInt("id"));
u.setUsername(rs.getString("username"));
u.setPassword(rs.getString("password"));
return u;
}
}
public User getUser(int id) {
String sql = "select id,username,password from t_user where id=?";
User user = simpleJdbcTemplate.queryForObject(sql, new UserRowmapper(), id);
return user;
}
public List<User> getList(){
String sql = "select id,username,password from t_user ";
List<User> list = simpleJdbcTemplate.query(sql, new UserRowmapper() );
return list;
}
}
四种通知的执行地方:前置通知
try{
业务代码
后置通知
} catch{
异常通知
} finally{
最终通知
}
1.需要的jar包:aspectjrt.jar,aspectjweaver.jar,cglib-nodep-2.1.3.jar
2.在配置文件中加入
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd
">
<bean id="myXmlAspect" class="com.yjw.aspect.MyXmlAspect"/>
<!-- 配置事务切面-->
<aop:config>
<aop:aspect ref="myXmlAspect">
<aop:pointcut expression="execution(* com.yjw.dao..*.*(..))" id="pointcut"/>
<aop:before method="beforeAdvice" pointcut-ref="pointcut"/>
<aop:after-returning method="afterReturningAdvice" returning="value" pointcut-ref="pointcut"/>
<aop:after-throwing method="exceptionAdvice" pointcut-ref="pointcut" throwing="ex"/>
<aop:after method="afterAdvice" pointcut-ref="pointcut"/>
</aop:aspect>
</aop:config>
</beans>
package com.yjw.aspect;
public class MyXmlAspect {
//前置通知
public void beforeAdvice(){
System.out.println("前置通知");
}
//异常通知,接收异常信息
public void exceptionAdvice(Exception ex){
System.out.println("异常出现"+ex.getMessage());
}
//后置通知,可以接收方法的返回值
public void afterReturningAdvice(Object value){
System.out.println("后置通知"+value);
}
//最终通知
public void afterAdvice(){
System.out.println("after");
}
}
查询集合
String sql = "select id, address,userid from t_address where userid in(select id from t_user where id in (select id from t_card where cardnum=112))";
SQLQuery query = session.createSQLQuery(sql).addEntity(Address.class);
List list = session.createSQLQuery(sql).list();
for(Object a : list){
Object[] address = (Object[]) a;
System.out.println(address[0]+" "+address[1]+" "+address[2]);
}
查询一个对象
String sql = "select id,username,password from t_user where id in (select id from t_card where cardnum=112)";
SQLQuery query = session.createSQLQuery(sql).addEntity(User.class);
User user = (User) query.uniqueResult();
System.out.println(user.getPwd());
单例就是在系统运行中只有一个实例对象
public class Factory {
private static Factory factory = new Factory();
private Factory(){
System.out.println("--");
}
public static Factory getFactory(){
return factory;
}
public void say(){
System.out.println("say");
}
}
第二种
public class Factory {
private static Factory factory =null;
private Factory(){
System.out.println("--");
}
public synchronized static Factory getFactory(){
if(factory==null){
factory = new Factory();
}
return factory;
}
public void say(){
System.out.println("say");
}
}
将一个类的接口转换成客户希望的另外一个接口。Adapter模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。
例子,让羊的叫声和狼一样,羊就是一个适配器:
public class Wolf {
public void run() {
System.out.println("wolf run");
}
public void ho() {
System.out.println("wolf ho");
}
}
适配器接口:
public interface Sheep {
public void run();
public void ho();
}
实现类:
public class SheepAdapter implements Sheep{
private Wolf wolf;
public SheepAdapter(Wolf wolf) {
this.wolf = wolf;
}
@Override
public void run() {
wolf.run();
}
@Override
public void ho() {
wolf.ho();
}
}
测试类:
public static void main(String[] args) {
Wolf w = new Wolf();
Sheep sa = new SheepAdapter(w);
sa.run();
sa.ho();
}
}
动态地给一个对象添加一些额外的职责。就增加功能来说,Decorator模式相比生成子类更为灵活。
例子:
被装饰的接口:
public interface Cake {
public float cost();
}
接口的实现类:
public class MilkCake implements Cake{
@Override
public float cost() {
return 100f;
}
}
装饰者抽象类:
public abstract class CakeDecorator implements Cake{
}
装饰者的实现类
public class Chocolate extends CakeDecorator{
private Cake cake;
public Chocolate(Cake cake) {
this.cake = cake;
}
@Override
public float cost() {
float chocolatePrice = 25f;
return cake.cost() + chocolatePrice;
}
}
public class Berry extends CakeDecorator {
private Cake cake;
public Berry(Cake cake) {
this.cake = cake;
}
@Override
public float cost() {
float berryPrice = 5f;
return cake.cost() + berryPrice;
}
}
测试类:
public class Test {
public static void main(String[] args) {
MilkCake mc = new MilkCake();//牛奶蛋糕
System.out.println(mc.cost());
Berry b = new Berry(mc);//牛奶草莓蛋糕
System.out.println(b.cost());
Chocolate c = new Chocolate(b);//牛奶草莓巧克力蛋糕
System.out.println("付款:" + c.cost());
}
}
为子系统中的一组接口提供一个一致的界面,Facade模式定义了一个高层接口,这个接口使得这一子系统更加容易使用。
1.当你要为一个复杂子系统提供一个简单接口时。子系统往往因为不断演化而变得越来越 复杂。大多数模式使用时都会产生更多更小的类。这使得子系统更具可重用性,也更容 易对子系统进行定制,但这也给那些不需要定制子系统的用户带来一些使用上的困难。 Facade可以提供一个简单的缺省视图,这一视图对大多数用户来说已经足够,而那些需 要更多的可定制性的用户可以越过facade层。
2.客户程序与抽象类的实现部分之间存在着很大的依赖性。引入facade将这个子系统与客 户以及其他的子系统分离,可以提高子系统的独立性和可移植性。
3.当你需要构建一个层次结构的子系统时,使用facade模式定义子系统中每层的入口点。 如果子系统之间是相互依赖的,你可以让它们仅通过facade进行通讯,从而简化了它们 之间的依赖关系。
例子:
外观类:
public class Facade {
ServiceA sa;
ServiceB sb;
ServiceC sc;
public Facade() {
sa = new ServiceAImpl();
sb = new ServiceBImpl();
sc = new ServiceCImpl();
}
public void methodA() {
sa.methodA();
sb.methodB();
}
public void methodB() {
sb.methodB();
sc.methodC();
}
public void methodC() {
sc.methodC();
sa.methodA();
}
}
接口和接口的实现类:
public interface ServiceA {
void methodA() ;
}
public class ServiceAImpl implements ServiceA{
@Override
public void methodA() {
System.out.println("这是服务A");
}
}
public interface ServiceB {
void methodB() ;
}
public class ServiceBImpl implements ServiceB{
@Override
public void methodB() {
System.out.println("这是服务B");
}
}
public interface ServiceC {
void methodC() ;
}
public class ServiceCImpl implements ServiceC{
@Override
public void methodC() {
System.out.println("这是服务C");
}
}
测试类:
public class Test {
public static void main(String[] args) {
ServiceA sa = new ServiceAImpl();
ServiceB sb = new ServiceBImpl();
sa.methodA();
sb.methodB();
System.out.println("========");
//facade
Facade facade = new Facade();
facade.methodA();
facade.methodB();
facade.methodC();
}
}
运用共享技术有效地支持大量细粒度的对象。
1.一次性实现一个算法的不变的部分,并将可变的行为留给子类来实现。
2.各子类中公共的行为应被提取出来并集中到一个公共父类中以避免代码重复。 首先识别现有代码中的不同之处,并且将不同之处分离为新的操作。 最后,用一个调用这些新的操作的模板方法来替换这些不同的代码。
3.控制子类扩展。
例子;
享元接口:
public interface Flyweight {
void action(int arg);
}
享元接口的实现类:
public class FlyweightImpl implements Flyweight{
@Override
public void action(int arg) {
System.out.println("参数值: " + arg);
}
}
产生精度对象的工厂类:
public class FlyweightFactory {
private static Map<String,Flyweight> flyweightsMap = new HashMap<String,Flyweight>();
public FlyweightFactory(String arg) {
System.out.println("-----------------");
flyweightsMap.put(arg, new FlyweightImpl());
}
public static Flyweight getFlyweight(String key) {
if (flyweightsMap.get(key) == null) {
flyweightsMap.put(key, new FlyweightImpl());
}
return (Flyweight) flyweightsMap.get(key);
}
public static int getSize() {
return flyweightsMap.size();
}
}
测试类:
public class Test {
public static void main(String[] args) {
Flyweight fly1 = FlyweightFactory.getFlyweight("a");
fly1.action(1);
Flyweight fly2 = FlyweightFactory.getFlyweight("a");
System.out.println(fly1 == fly2);
Flyweight fly3 = FlyweightFactory.getFlyweight("c");
fly3.action(3);
Flyweight fly4 = FlyweightFactory.getFlyweight("d");
fly4.action(4);
Flyweight fly5 = FlyweightFactory.getFlyweight("e");
fly5.action(5);
System.out.println(FlyweightFactory.getSize());
}
}
代理模式实现了类与类之间直接调用的解耦,例子:
代理模式主要使用了java的多态,干活的是被代理类,代理类主要的接活
,把活交给幕后的被代理类做,代理类和被代理类实现同一个接口。
被代理类的接口:
public interface Object {
void action();
}
被代理类的接口实现类:
public class ObjectImpl implements Object{
public void action() {
System.out.println("========");
System.out.println("========");
System.out.println("这是被代理的类");
System.out.println("========");
System.out.println("========");
}
}
代理类:
public class ProxyObject implements Object{
Object obj;
public ProxyObject() {
System.out.println("这是代理类");
obj = new ObjectImpl();
}
public void action() {
System.out.println("代理开始");
obj.action();
System.out.println("代理结束");
}
}
测试类:
public class Test {
public static void main(String[] args) {
Object obj = new ProxyObject();
obj.action();
}
}
定义一系列的算法,把它们一个个封装起来,并且使它们可相互替换。本模式使得算法可独立于使用它的客户而变化。
适合场合:
* 1.以不同的格式保存文件
* 2.以不同的算法压缩文件
* 3.以不同的算法截取图形
* 4.以不同的格式输出数据的图形,曲线,框图等
策略接口:
public interface Strategy {
void method();
}
策略接口实现类:
public class StrategyImplA implements Strategy{
public void method() {
System.out.println("这是第一个实现a");
}
}
public class StrategyImplB implements Strategy{
public void method() {
System.out.println("这是第二个实现b");
}
}
public class StrategyImplC implements Strategy{
public void method() {
System.out.println("这是第三个实现c");
}
}
调用类:
public class Context {
Strategy stra;
public Context(Strategy stra) {
this.stra = stra;
}
public void doMethod() {
stra.method();
}
}
测试:
public class Test {
public static void main(String[] args) {
Context ctx = new Context(new StrategyImplA());
ctx.doMethod();
ctx = new Context(new StrategyImplB());
ctx.doMethod();
ctx = new Context(new StrategyImplC());
ctx.doMethod();
}
}
命令模式就是将一组对象的相似行为,进行了抽象,将调用者与被调用者之间进行解耦,提
高了应用的灵活性。命令模式将调用的目标对象的一些异构性给封装起来,通过统一的方式来为调用者提供服务。
适用场景
1、当一个应用程序调用者与多个目标对象之间存在调用关系时,并且目标对象之间的操作很类似的时候。
2、例如当一个目标对象内部的方法调用太复杂,或者内部的方法需要协作才能完成对象的某个特点操作时。
3、有时候调用者调用目标对象后,需要回调一些方法。
例子:
命令接口:
public interface Commond {
public void execute();
}
命令接口实现类:
public class LightOnCommond implements Commond{
private Light light;
public LightOnCommond(Light light) {
this.light = light;
}
@Override
public void execute() {
light.on();
}
}
命令的调用者:
public class Light {
public void on() {
System.out.println("灯亮了");
}
}
public class TurnTvCommond implements Commond {
private Tv tv;
public TurnTvCommond(Tv tv) {
this.tv = tv;
}
@Override
public void execute() {
tv.turn();
}
}
public class Tv {
public void turn() {
System.out.println("调台");
}
}
同时执行的多个命令数组
public class MracoCommond implements Commond{
private Commond[] commonds;
public MracoCommond(Commond...commonds) {
this.commonds = commonds;
}
@Override
public void execute() {
for(Commond cmd : commonds) {
cmd.execute();
}
}
}
命令的包装类,
public class RemoteContro {
private List<Commond> commondList = new ArrayList<Commond>();
public void setCommond(Commond commond) {
commondList.add(commond);
}
public void buttonWasPressed(int index){
commondList.get(index-1).execute();
}
}
public class Test {
public static void main(String[] args) {
Light light = new Light();
LightOnCommond loc = new LightOnCommond(light);
Tv tv = new Tv();
TurnTvCommond ttc = new TurnTvCommond(tv);
MracoCommond mc = new MracoCommond(loc,ttc);
RemoteContro rc = new RemoteContro();
rc.setCommond(ttc);
rc.setCommond(loc);
rc.setCommond(mc);
//rc.buttonWasPressed(3);
//rc.buttonWasPressed(1);
rc.buttonWasPressed(2);
}
}
当输入123不同时,调用的命令不同,实现了多个命令的包装
1.把依赖类(Service)和被依赖类(Dao)全部交给Spring管理
2.依赖类中提供被依赖类的set方法
3.在xml中进行配置
当把一个类交给spring管理是要给出一个无参数的构造方法给spring使用
<bean id="person" class="com.yjw.bean.Person1" factory-method="getPerson1" scope="prototype">
</bean>
scope="prototype"是创建多例,不配置此项,默认单例
或者lazy-init值设置为true
public class Person1 implements Person{
private Person1(String s){
System.out.println(s);
}
public void say() {
System.out.println("00000000000000");
}
public static Person1 getPerson1(){
return new Person1("pppppppppp");
}
}
<bean id="person" class="com.yjw.bean.Person1" factory-method="getPerson1">
public class Test {
public static void main(String[] args) {
ApplicationContext ctx =new ClassPathXmlApplicationContext("applicationContext.xml");
// UserService userservice =(UserService) ctx.getBean("person");
/* User u = new User();
u.setUsername("qq");
u.setPassword("qq");
userservice.save(u);*/
Person person = (Person) ctx.getBean("person");
person.say();
}
}
概述:
定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。
适用性:
1.当一个抽象模型有两个方面,其中一个方面依赖于另一方面。 将这二者封装在独立的对象中以使它们可以各自独立地改变和复用。 2.当对一个对象的改变需要同时改变其它对象,而不知道具体有多少对象有待改变。 3.当一个对象必须通知其它对象,而它又不能假定其它对象是谁。
我们以天气预报的服务为例,安卓和诺基亚购买天气预报的服务,也可以停用服务:
天气预报主体的接口:
public interface Subject {
public void zhuce(Observer observer);
public void remove(Observer observer);
public void tongzhi();
}
天气预报的实现类:
public class WeatherData implements Subject {
private int low;
private int hight;
private String weather;
private List<Observer> list = new ArrayList<Observer>();
public void setData(int low, int hight, String weather) {
this.low = low;
this.hight = hight;
this.weather = weather;
tongzhi();
}
public int getLow() {
return low;
}
public int getHight() {
return hight;
}
public String getWeather() {
return weather;
}
public void zhuce(Observer observer) {
if (!list.contains(observer)) {
list.add(observer);
}
}
public void remove(Observer observer) {
if (list.contains(observer)) {
list.remove(observer);
}
}
public void tongzhi() {
for (Observer o : list) {
o.update(getLow(), getHight(), getWeather());
}
}
}
观察者的接口:
public interface Observer {
void remove();
void update(int low, int hight, String weather);
}
观察者的实现类:
public class Android implements Observer {
private Subject subject;
public Android() {
}
public Android(Subject subject) {
this.subject = subject;
this.subject.zhuce(this);
}
public void update(int low, int hight, String weather) {
System.out.println("android" + low + "" + hight + weather);
}
public void remove() {
subject.remove(this);
}
}
public class Nokia implements Observer{
private Subject subject;
public Nokia(){}
public Nokia(Subject subject){
this.subject = subject;
this.subject.zhuce(this);
}
public void update(int low, int hight, String weather) {
System.out.println("nokia:"+low+"-"+hight+"-"+weather);
}
public void remove(){
subject.remove(this);
}
}
测试类:
public class Test {
public static void main(String[] args) {
WeatherData wd = new WeatherData();
wd.setData(1, 22, "晴朗");
Android a = new Android(wd);
wd.tongzhi();
a.remove();
Nokia n = new Nokia(wd);
n.remove();
wd.tongzhi();
}
}
状态模式
定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。
用性:1.一个对象的行为取决于它的状态,并且它必须在运行时刻根据状态改变它的行为。
2.一个操作中含有庞大的多分支的条件语句,且这些分支依赖于该对象的状态。
这个状态通常用一个或多个枚举常量表示。
通常,有多个操作包含这一相同的条件结构。
State模式将每一个条件分支放入一个独立的类中。
这使得你可以根据对象自身的情况将对象的状态作为一个对象,这一对象可以不依赖于其他对象而独立变化。
状态模式在工作流或游戏等各种系统中有大量使用,甚至是这些系统的核心功能设计,例如
政府OA中,一个批文的状态有多种:未办;正在办理;正在批示;正在审核;已经完成等
各种状态,使用状态机可以封装这个状态的变化规则,从而达到扩充状态时,不必涉及到状
态的使用者。
在网络游戏中,一个游戏活动存在开始;开玩;正在玩;输赢等各种状态,使用状态模式就
可以实现游戏状态的总控,而游戏状态决定了游戏的各个方面,使用状态模式可以对整个游
戏架构功能实现起到决定的主导作用。
状态模式实质:
使用状态模式前,客户端外界需要介入改变状态,而状态改变的实现是琐碎或复杂的。
使用状态模式后,客户端外界可以直接使用事件Event实现,根本不必关心该事件导致如
何状态变化,这些是由状态机等内部实现。
这是一种Event-condition-State,状态模式封装了condition-State部分。
每个状态形成一个子类,每个状态只关心它的下一个可能状态,从而无形中形成了状态转换
的规则。如果新的状态加入,只涉及它的前一个状态修改和定义。
状态转换有几个方法实现:一个在每个状态实现next(),指定下一个状态;还有一种方法,
设定一个StateOwner,在StateOwner设定stateEnter状态进入和stateExit状
态退出行为。
状态从一个方面说明了流程,流程是随时间而改变,状态是截取流程某个时间片。
例子:
操作当前状态类:
public class Context {
private Weather weather;
public void setWeather(Weather weather) {
this.weather = weather;
}
public Weather getWeather() {
return this.weather;
}
public String weatherMessage() {
return weather.getWeather();
}
}
状态接口:
public interface Weather {
String getWeather();
}
状态实现类:
public class Sunshine implements Weather{
public String getWeather() {
return "阳光";
}
}
public class Rain implements Weather{
public String getWeather() {
return "下雨";
}
}
测试类:
public class Test {
public static void main(String[] args) {
Context ctx1 = new Context();
ctx1.setWeather(new Sunshine());
System.out.println(ctx1.weatherMessage());
System.out.println("===============");
ctx1.setWeather(new Rain());
System.out.println(ctx1.weatherMessage());
}
}
例子2:
public class Work {
private State current;
public Work(double hour,boolean finish){
current = new ForenoonState();
this.hour = hour;
this.finish = finish;
}
private double hour;
public double getHour() {
return hour;
}
public State getCurrent() {
return current;
}
public void setCurrent(State current) {
this.current = current;
}
private boolean finish;
public boolean isFinish() {
return finish;
}
public void writeProgram(){
current.writeProgram(this);
}
}
public interface State {
void writeProgram(Work work);
}
public class ForenoonState implements State {
@Override
public void writeProgram(Work work) {
if(work.getHour()<12){
System.out.println("工作时间");
}else {
work.setCurrent(new NoonState());
work.writeProgram();
}
}
}
public class NoonState implements State {
@Override
public void writeProgram(Work work) {
if(work.getHour()<13){
System.out.println("午睡");
}else {
work.setCurrent(new AfterNoonState());
work.writeProgram();
}
}
}
public class AfterNoonState implements State {
@Override
public void writeProgram(Work work) {
if(work.getHour()<17){
System.out.println("工作");
}else {
work.setCurrent(new EveningState());
work.writeProgram();
}
}
}
public class EveningState implements State {
@Override
public void writeProgram(Work work) {
if(work.isFinish()){
work.setCurrent(new RestState());
work.writeProgram();
}else {
if(work.getHour()<21){
System.out.println("加班");
}else {
work.setCurrent(new SleepState());
work.writeProgram();
}
}
}
}
public class SleepState implements State {
@Override
public void writeProgram(Work work) {
System.out.println("睡觉");
}
}
访问者模式主要是将很多操作都在一个接口中声明,在接口的实现类中都要实现这些操作,
在具体的访问者类中规定了需要调用实现类的哪个方法,
例子如下:
访问者接口:
public interface Visitor {
public void visitString(StringElement stringE);
public void visitFloat(FloatElement floatE);
public void visitCollection(Collection<?> collection);
public void visitInt(IntElement inte);
}
访问者接口实现类
public class ConcreteVisitor implements Visitor{
public void visitCollection(Collection<?> collection) {
Iterator<?> iterator = collection.iterator();
while (iterator.hasNext()) {
Object o = iterator.next();
if (o instanceof Visitable) {
((Visitable)o).accept(this);
}
}
}
public void visitFloat(FloatElement floatE) {
System.out.println(floatE.getFe());
}
public void visitString(StringElement stringE) {
System.out.println(stringE.getSe());
}
@Override
public void visitInt(IntElement inte) {
System.out.println(inte.getInts());
}
}
操作类的接口:
public interface Visitable {
public void accept(Visitor visitor);
}
操作类的具体实现类:
public class FloatElement implements Visitable{
private Float fe;
public FloatElement(Float fe) {
this.fe = fe;
}
public Float getFe() {
return this.fe;
}
public void accept(Visitor visitor) {
visitor.visitFloat(this);
}
}
public class IntElement implements Visitable{
private int ints;
public int getInts() {
return ints;
}
public IntElement(int i){
this.ints = i;
}
@Override
public void accept(Visitor visitor) {
visitor.visitInt(this);
}
}
public class StringElement implements Visitable{
private String se;
public StringElement(String se) {
this.se = se;
}
public String getSe() {
return this.se;
}
public void accept(Visitor visitor) {
visitor.visitString(this);
}
}
测试类:
public class Test {
public static void main(String[] args) {
Visitor visitor = new ConcreteVisitor();
Visitable se = new StringElement("abc");
se.accept(visitor);
Visitable fe = new FloatElement(new Float(1.5));
fe.accept(visitor);
System.out.println("===========");
List<Visitable> result = new ArrayList<Visitable>();
result.add(new StringElement("abc"));
result.add(new StringElement("abc"));
result.add(new StringElement("abc"));
result.add(new FloatElement(new Float(1.5)));
result.add(new FloatElement(new Float(1.5)));
result.add(new FloatElement(new Float(1.5)));
visitor.visitCollection(result);
Visitable is = new IntElement(2);
is.accept(visitor);
}
}
概述:
定义一个操作中的算法的骨架,而将一些步骤延迟到子类中。
TemplateMethod使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。
适用性:
1.一次性实现一个算法的不变的部分,并将可变的行为留给子类来实现。
2.各子类中公共的行为应被提取出来并集中到一个公共父类中以避免代码重复。
首先识别现有代码中的不同之处,并且将不同之处分离为新的操作。
最后,用一个调用这些新的操作的模板方法来替换这些不同的代码。
例子如下:模板类:
public abstract class Template {
public abstract void print();
public void update() {
System.out.println("公共的代码");
System.out.println("下面是子类各自实现的代码");
print();
}
}
模板类的子类:
public class TemplateConcrete extends Template{
@Override
public void print() {
System.out.println("这是子类的实现");
}
}
测试类
public class Test {
public static void main(String[] args) {
Template temp = new TemplateConcrete();
temp.update();
}
}
grid.addListener('cellclick', cellclick);
function cellclick(grid, rowIndex, columnIndex, e) {
var record = grid.getStore().getAt(rowIndex);
var fieldName = grid.getColumnModel().getDataIndex(columnIndex);
var data = record.get(fieldName);
if(data==null){ //处理预览
var alias=record.get("Alias");
window.open(url);
//window.location.href="DoIpcammera?dowith=preview&&alias="+alias;
}
}
new Ext.grid.RowNumberer()
var AddtoobarT = new Ext.form.Radio({
name : "istoobar",//后台接受的名称
inputValue : "true",//传后台的值
boxLabel : "有",//页面显示的值
checked : true//默认选择的值
});
var AddtoobarF = new Ext.form.Radio({
name : "istoobar",
inputValue : "false",
boxLabel : "没有"
});
var Addtoobar = new Ext.form.RadioGroup({
name : "toolbar",
fieldLabel : "有无工具栏",
items : [ AddtoobarT, AddtoobarF ],
width : 200
});
职责链模式规定了一个请求,这个请求需要特定的对象去处理,当把这个请求交个一个对象,但是这个对象不负责处理这个请求,可以动态地交给其他对象处理,直到交给对的对象处理,这些对象都有处理请求的机会,只有当请求是该自己负责的时候才处理,否则交给其他对象。
下面以==============
要离职, 人事审批!
请求完毕
===========
要加薪, 项目经理审批!
========
要请假, 项目组长审批!
的规定,写一个职责链模式的例子:
这是所有请求的接口
public interface Request {
void getRequest();
}
请假的请求实现类
public class LeaveRequest implements Request{
@Override
public void getRequest() {
System.out.println("leave");
}
}
离职的请求实现类
public class DimissionRequest implements Request{
@Override
public void getRequest() {
System.out.println("dimission");
}
}
加薪的请求实现类
public class AddMoneyRequest implements Request{
@Override
public void getRequest() {
System.out.println("add money");
}
}
处理请求的接口
public interface RequestHandle {
void handleRequest(Request request);
}
Hr处理离职的请求
public class HRRequestHandle implements RequestHandle{
public void handleRequest(Request request) {
if (request instanceof DimissionRequest) {
System.out.println("要离职, 人事审批!");
}
System.out.println("请求完毕");
}
}
组长处理请假的请求
public class TLRequestHandle implements RequestHandle{
RequestHandle rh;
public TLRequestHandle(RequestHandle rh) {
this.rh = rh;
}
public void handleRequest(Request request) {
if (request instanceof LeaveRequest) {
System.out.println("要请假, 项目组长审批!");
} else {
rh.handleRequest(request);
}
}
}
经理处理加薪的请求
public class PMRequestHandle implements RequestHandle{
RequestHandle rh;
public PMRequestHandle(RequestHandle rh) {
this.rh = rh;
}
public void handleRequest(Request request) {
if (request instanceof AddMoneyRequest) {
System.out.println("要加薪, 项目经理审批!");
} else {
rh.handleRequest(request);
}
}
}
测试类
public class Test {
public static void main(String[] args) {
//先把所有的处理请求的对象组成职责链
RequestHandle hr = new HRRequestHandle();
RequestHandle tl = new TLRequestHandle(hr);//组长
RequestHandle pm = new PMRequestHandle(tl);//经理
Request dimissionRequest = new DimissionRequest();
Request addMoneyRequest = new AddMoneyRequest();
Request leaveRequest = new LeaveRequest();
System.out.println("==============");
//人事处理离职请求
pm.handleRequest(dimissionRequest);
System.out.println("===========");
//经理处理加薪请求
pm.handleRequest(addMoneyRequest);
System.out.println("========");
//项目组长处理请假请求
pm.handleRequest(leaveRequest);
}
}
在使用时要调用最高级的职责调用者,由他去负责往下分配职责
is null是判断某个字段是否是空,为空并不等价于空字符串或者数字0
=null 是判断某个值是否等于null,null=null,和null<>null都是false
select DISTINCT job from emp where deptno=20
select name from user where upper(name) ='TOM' and sal is not null;
upper()函数的作用是把表中的name转换成大写再做比较
求薪金sal列和绩效comm列的和,comm可能是空,
select sal+if(comm is null,0,comm) from emp;
当comm是空时,返回0,不空时返回comm的数值
public class User implements Serializable{
/**
*
*/
private static final long serialVersionUID = 1L;
private String name;
public User(){
System.out.println("===============");
}
public User(String name){
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "user="+this.name;
}
}
<s:property value="new User('name')"/>
public class Test {
public static String NAME = "nametom";
public static String test(){
return "testtom";
}
}
在struts.xml配置文件中加<constant name="struts.ognl.allowStaticMethodAccess" value="true"></constant>
<s:property value="@Test@test()"/>
<s:property value="@Test@NAME"/>
public class UserAction extends ActionSupport{
/**
*
*/
private static final long serialVersionUID = 1L;
public String mm(){
return "mm";
}
}
<s:property value="mm()"/>
public class User implements Serializable{
/**
*
*/
private static final long serialVersionUID = 1L;
private String name;
public User(){
System.out.println("===============");
}
public User(String name){
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "user="+this.name;
}
}
public class UserAction extends ActionSupport{
/**
*
*/
private static final long serialVersionUID = 1L;
private String name;
private User user;
private Cat cat;
@Override
public String execute() throws Exception {
// System.out.println(cat.getFriend().getName());
return ActionSupport.SUCCESS;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
public Cat getCat() {
return cat;
}
public void setCat(Cat cat) {
this.cat = cat;
}
}
<s:property value="user.toString()"/>
public class User implements Serializable{
/**
*
*/
private static final long serialVersionUID = 1L;
private String name;
public User(){
System.out.println("========空的构造方法=必须有======");
}
public User(String name){
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
public class UserAction extends ActionSupport{
/**
*
*/
private static final long serialVersionUID = 1L;
private String name;
private User user;
@Override
public String execute() throws Exception {
System.out.println(user.getName());
return ActionSupport.SUCCESS;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
}
<body>
<s:form action="user/tologin.action" method="post">
<s:textarea name="id"></s:textarea>
<s:password name="user.password"></s:password>
<s:textfield name="user.name" label="ddddd" > </s:textfield>
<s:submit value="提交" method="login"></s:submit>
<s:submit value="打印" method="print"></s:submit>
</s:form>
</body>
验证框架的命名规则是Action类名字-action的bean名字-validation.xml,这个验证文件需要放在需要验证的.class文件同一目录下
例如UserAction-tologin-validation.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE validators PUBLIC
"-//Apache Struts//XWork Validator 1.0.2//EN"
"http://struts.apache.org/dtds/xwork-validator-1.0.2.dtd">
<validators>
<field name="id">
<field-validator type="int">
<param name="min">10</param>
<param name="max">20</param>
<message>必须是整数</message>
</field-validator>
</field>
<field name="user.name">
<field-validator type="requiredstring">
<message>name必须填写</message>
</field-validator>
</field>
</validators>
在struts-xml中的配置
<action name="tologin" class="UserAction" >
<result>/WEB-INF/user/list.jsp</result>
<result name="input">/WEB-INF/user/user.jsp</result>
</action>
<body>
<s:form action="user/tologin.action" method="post">
<s:textarea name="id"></s:textarea>
<s:password name="user.password"></s:password>
<s:textfield name="user.name"></s:textfield>
<s:submit value="提交" method="login"></s:submit>
<s:submit value="打印" method="print"></s:submit>
</s:form>
</body>
<action name="tologin" class="UserAction" >
<result>/WEB-INF/user/list.jsp</result>
</action>
public class UserAction extends ActionSupport{
private static final long serialVersionUID = 1L;
private User user;
private String id;
@Override
public String execute() throws Exception {
return ActionSupport.SUCCESS;
}
public String login(){
return ActionSupport.SUCCESS;
}
public String print(){
System.out.println(user.getName());
System.out.println(user.getPassword());
System.out.println(id);
return ActionSupport.SUCCESS;
}
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
}
<a href="hello?name=1">重定向传参数</a>
<package name="default" namespace="/" extends="struts-default">
<default-action-ref name="hello"></default-action-ref>
<action name="hello" class="UserAction">
<result type="redirect">/index2.jsp?t=${name}</result>
</action>
</package>
public class UserAction extends ActionSupport{
/**
*
*/
private static final long serialVersionUID = 1L;
private String name;
@Override
public String execute() throws Exception {
System.out.println(name);
return ActionSupport.SUCCESS;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
<s:property value="#parameters.t"/>
第一种
public class UserAction extends ActionSupport{
/**
*
*/
private static final long serialVersionUID = 1L;
private String name;
private Map session;
private Map request;
private Map application;
@Override
public String execute() throws Exception {
session = ActionContext.getContext().getSession();
request = (Map) ActionContext.getContext().get("request");
application = ActionContext.getContext().getApplication();
session.put("sk", "sv");
request.put("rk", "rv");
application.put("ak", "av");
System.out.println(name);
return ActionSupport.SUCCESS;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
第二种
public class DepAction extends ActionSupport implements RequestAware,SessionAware,ApplicationAware{
private Map<String, Object> request;
private Map<String, Object> session;
private Map<String, Object> application;
public void setRequest(Map<String, Object> request) {
this.request = request;
}
public void setSession(Map<String, Object> session) {
this.session = session;
}
public void setApplication(Map<String, Object> application) {
this.application = application;
}
}
第三种
public class CarAction implements ServletRequestAware{
private HttpServletRequest request;
private HttpSession session;
private ServletContext application;
public void setServletRequest(HttpServletRequest request) {
this.request = request;
this.session = request.getSession();
this.application = session.getServletContext();
}
}
第四种
public class HomeAction extends ActionSupport{
private HttpServletRequest request;
private HttpSession session;
private ServletContext application;
public HomeAction (){
request = ServletActionContext.getRequest();
session = request.getSession();
application = session.getServletContext();
}
}
摘要: Struts2常用标签总结
一 介绍
1.Struts2的作用
Struts2标签库提供了主题、模板支持,极大地简化了视图页面的编写,而且,struts2的主题、模板都提供了很好的扩展性。实现了更好的代码复用。Struts2允许在页面中使用自定义组件,这完全能满足项目中页面显示复杂,多变的需求。
Struts2的标签库有一个巨大的改进之处,struts2标签库的标签不依赖于任何...
阅读全文
在strut2中所以的值都在值栈中存放,在页面中加入<s:debug></s:debug>标签,就可以点击显示出当前值栈中的所有值,如图

可以通过 <s:property value="name"/>标签得到值栈中的值,value的值是PropertyName,就可以得到对应的value
在action中session,request,application都是Map数据类型的
private Map session;
private Map request;
private Map application;
session = ActionContext.getContext().getSession();
request = (Map) ActionContext.getContext().get("request");
application = ActionContext.getContext().getApplication();
session.put("sk", "sv");
request.put("rk", "rv");
application.put("ak", "av");
想在页面中取到相应的值;
<s:property value="#session.sk"/>
<s:property value="#request.rk"/>
<s:property value="#application.ak"/>
使用<s:debug></s:debug>观看他们都是存放在栈区,#+名称就可以取到值
namespace决定来了action的访问路径,当namespace=“”时,可以接受所有路径的action,namespace=“/”,
或者"/xxx,或者"/xxx/yyy",对应的action访问路径是/index.action,或者/xxx/index.action,或
者/xxx/yyy/index.action.
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort
()+path+"/";
%>
<base href="<%=basePath%>">
在使用namespace时容易出现路径问题,在会出现路径问题的jsp页面中加上base标签,就不会了。
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
public class Test {
public static void main(String[] args) {
Calendar calendar = Calendar.getInstance();
calendar.setFirstDayOfWeek(Calendar.MONDAY);
calendar.add(Calendar.DATE, -7);
calendar.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
Date sTime = calendar.getTime();
calendar.set(Calendar.DAY_OF_WEEK, Calendar.SUNDAY);
Date eTime = calendar.getTime();
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
String s = sdf.format(sTime) + " 00:00:00";
String e = sdf.format(eTime) + " 23:59:59";
System.out.println(s);
System.out.println(e);
}
}
摘要: 在struts2中的拦截器的定义是先定义一个类实现Interceptor接口,重写intercept方法。下面是实现登录验证的拦截器。 <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts C...
阅读全文
Typeof()返回值有6中可能:number,string,boolean,object,function,undefined
Prompt(“请输入名称”)返回字符
eval(“”)可以把“”中的字符串执行
在java中继承的构造方法的规则:
1. 子类的构造的过程中必须调用其父类的构造方法。
2. 子类可以在自己的构造方法中使用super(argument—list)调用父类的构造方法。
3. 使用this(argument—list)调用自己的另外的构造方法。
4. 如果调用super,必须卸载子类构造方法的第一行。
5. 如果子类的构造方法中没有显示调用父类工作服,系统默认调用父类无参数的构造方法。
6. 如果子类构造方法中没有显示调用父类的构造方法,而父类中又没有无参数的构造方法,编译出错。
哈希编码:每个对象都有一个独一无二的哈希编码,通过这个哈希编码可以找到这个对象。
多态中动态绑定规则;1.有继承,2.有重写(子类重写父类中的方法),3.父类引用指向子类对象。
Public void getId(final int i){}表示i在此方法中不同被修改
<!--?启动时删数据库中的表,然后创建,退出时不删除数据表
<property?name="hibernate.hbm2ddl.auto">create</property>-->
<!--?启动时删数据库中的表,然后创建,退出时自动删除所有表
<property?name="hibernate.hbm2ddl.auto">create-drop</property>-->
<!--?自动修改,如果表结构与实体类不一致,那么就修改表使它们一致,数据会保留
<property?name="hibernate.hbm2ddl.auto">update</property>-->
<!--?自动校验,如果表结构与实体类不一致,那么不做任何操作,报错
<property?name="hibernate.hbm2ddl.auto">validate</property>-->
public class ReadSql {
public static void readsql(String filePath) throws Exception{
String encoding = "gbk";
File file = new File(filePath);
if(file.isFile()&&file.exists()){
InputStreamReader reader = new InputStreamReader(new FileInputStream(file),encoding);
BufferedReader bufferedReader = new BufferedReader(reader);
String line = null;
while ((line = bufferedReader.readLine())!=null) {
System.out.println(line.toString());
}
reader.close();
}
}
public static void main(String[] args) throws Exception {
System.out.println("=================================================");
ReadSql.readsql("c:/rr.txt");
System.out.println("=================================================");
}
}
阿里云服务平台注册相当于申请到了一台服务器主机,想运行java web项目很简单,安装jdk,tomcat,数据库,把编译好的项目放在tomcat中,启动tomcat,在外网直接访问阿里云主机ip和端口,项目名称,就可以了
在网络编程中,先启动service,再启动clent。
1.tcp
服务端
public class Service {
public static void main(String[] args) throws Exception {
ServerSocket ss = new ServerSocket(6666);
System.out.println("等待");
while (true) {
Socket socket =ss.accept();
InputStream is = socket.getInputStream();
DataInputStream dataInputStream = new DataInputStream(is);
System.out.println(dataInputStream.readUTF());
dataInputStream.close();
socket.close();
}
}
}
客户端
public class CientSocket {
public static void main(String[] args) throws Exception {
Socket socket = new Socket("127.0.0.1",6666);
OutputStream outputStream = socket.getOutputStream();
DataOutputStream dataOutputStream = new DataOutputStream(outputStream);
dataOutputStream.writeUTF("333333333");
dataOutputStream.flush();
dataOutputStream.close();
socket.close();
}
}
udp通信,是不区分客户端和服务端的
public class Service {
public static void main(String[] args) throws Exception {
byte buf[] = new byte[1024];
DatagramPacket dPacket = new DatagramPacket(buf, buf.length);
DatagramSocket dSocket = new DatagramSocket(5678);
while (true) {
dSocket.receive(dPacket);
System.out.println(new String(buf,0,dPacket.getLength()));
}
}
}
public class UdpClient {
public static void main(String[] args) throws Exception{
while (true) {
byte[] buf = (new String("hello")).getBytes();
DatagramPacket dpPacket = new DatagramPacket(buf, buf.length, new InetSocketAddress("127.0.0.1", 5678));
//自己占用9999端口
DatagramSocket dSocket = new DatagramSocket(9999);
dSocket.send(dpPacket);
dSocket.close();
}
}
}
当我们去启动一个 WEB 项目的时候, 容器(包括 JBoss, Tomcat 等)首先会去读项目的 web.xml 配置文件里面的信息,
当这一步骤没有出错并且完成之后, 项目才能正常的被启动起来。
1> 首先是, 容器会先读 <context-param></context-param> 节点, 并创建一个 ServletContext 实例, 以节点的 name 作为键, value 作为值,
存储到上下文环境中。
2> 接着, 容器会去读 <listener></listener> 节点, 根据配置的 class 类路径来创建监听。
3> 接着, 容器去读 <filter></filter> 节点, 根据指定的类路径来实例化过滤器。
以上都是在 WEB 项目还没有完全启动起来的时候就已经完成了的工作。如果系统中有用到 Servlet, 则 Servlet 是在第一次发起请求的时候被实例化的,
且一般不会被容器销毁, 它可以服务于多个用户的请求。所以, Servlet 的初始化都要比上面提到的那几个要迟。
总的来说, web.xml 的加载顺序是: context-param --> listener --> filter --> servlet
其中, 如果 web.xml 中出现了相同的节点, 则是按照在配置文件中出现的先后顺序来加载的。
下面引入一个小列子来说明:
<?xml version="1.0" encoding="UTF-8"?>
<listener>
<listener-class>net.yeah.fancydeepin.listener.AppStartListener</listener-class>
</listener>
<!-- 为了更好的说明, 特意将 context-param 放在 listener 后面 -->
<context-param>
<param-name>technology</param-name>
<param-value>java,javascript,ajax,css,html</param-value>
</context-param>
<filter>
<filter-name>ReDespatcherFilter</filter-name>
<filter-class>net.yeah.fancydeepin.filter.ReDespatcherFilter</filter-class>
<init-param>
<param-name>it</param-name>
<param-value>android, python, c</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>ReDespatcherFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<filter>
<filter-name>ReDespatcherFilter2</filter-name>
<filter-class>net.yeah.fancydeepin.filter.ReDespatcherFilter2</filter-class>
<init-param>
<param-name>mail</param-name>
<param-value>fancydeepin@yeah.net</param-value>
</init-param>
</filter>
</web-app>
package net.yeah.fancydeepin.listener;
import java.util.Arrays;
import java.util.List;
import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
public class AppStartListener implements ServletContextListener{
public void contextInitialized(ServletContextEvent contextEvent) {
System.out.println("********************************************");
ServletContext context = contextEvent.getServletContext();
List<String> params = Arrays.asList(context.getInitParameter("technology").split(","));
for(String param : params){
System.out.print(param + "\t");
}
System.out.println("\n********************************************");
}
public void contextDestroyed(ServletContextEvent contextEvent) {
}
}
package net.yeah.fancydeepin.filter;
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
public class ReDespatcherFilter implements Filter {
public void init(FilterConfig filterConfig) throws ServletException {
System.out.println("============================================");
System.out.println(filterConfig.getInitParameter("it"));
System.out.println("============================================");
}
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException,ServletException{
chain.doFilter(request, response);
}
public void destroy() {
}
}
package net.yeah.fancydeepin.filter;
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
public class ReDespatcherFilter2 implements Filter {
public void init(FilterConfig filterConfig) throws ServletException {
System.out.println("++++++++++++++++++++++++++++++++++++++++++++");
System.out.println(filterConfig.getInitParameter("mail"));
System.out.println("++++++++++++++++++++++++++++++++++++++++++++");
}
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException,ServletException{
chain.doFilter(request, response);
}
public void destroy() {
}
}
后台启动输出结果:

在 java 中, 常见的 Context 有很多,
像: ServletContext, ActionContext, ServletActionContext, ApplicationContext, PageContext, SessionContext ...
那么, Context 究竟是什么东西呢? 直译是上下文、环境的意思。比如像: "今天我收到了一束花, 男朋友送的!" 又或者 "今天我收到了一束花, 送花的人送错了的!"
同样是收到一束花, 在不同的上下文环境中表达的意义是不一样的。
同样的, Context 其实也是一样, 它离不开所在的上下文环境, 否则就是断章取义了。
另外, 在网络上也有些人把 Context 看成是一些公用信息或者把它看做是一个容器的, 个人觉得这种解释稍好。
接下来说说 ServletContext, ActionContext, ServletActionContext。
1> ServletContext
一个 WEB 运用程序只有一个 ServletContext 实例, 它是在容器(包括 JBoss, Tomcat 等)完全启动 WEB 项目之前被创建, 生命周期伴随整个 WEB 运用。
当在编写一个 Servlet 类的时候, 首先是要去继承一个抽象类 HttpServlet, 然后可以直接通过 getServletContext() 方法来获得 ServletContext 对象。
这是因为 HttpServlet 类中实现了 ServletConfig 接口, 而 ServletConfig 接口中维护了一个 ServletContext 的对象的引用。
利用 ServletContext 能够获得 WEB 运用的配置信息, 实现在多个 Servlet 之间共享数据等。
eg:
<?xml version="1.0" encoding="UTF-8"?>
<context-param>
<param-name>url</param-name>
<param-value>jdbc:oracle:thin:@localhost:1521:ORC</param-value>
</context-param>
<context-param>
<param-name>username</param-name>
<param-value>scott</param-value>
</context-param>
<context-param>
<param-name>password</param-name>
<param-value>tigger</param-value>
</context-param>
<servlet>
<servlet-name>ConnectionServlet</servlet-name>
<servlet-class>net.yeah.fancydeepin.servlet.ConnectionServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>ConnectionServlet</servlet-name>
<url-pattern>/ConnectionServlet.action</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>PrepareConnectionServlet</servlet-name>
<servlet-class>net.yeah.fancydeepin.servlet.PrepareConnectionServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>PrepareConnectionServlet</servlet-name>
<url-pattern>/PrepareConnectionServlet.action</url-pattern>
</servlet-mapping>
</web-app>
package net.yeah.fancydeepin.servlet;
import java.io.IOException;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class PrepareConnectionServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
public void init() throws ServletException {
ServletContext context = getServletContext();
String url = context.getInitParameter("url");
String username = context.getInitParameter("username");
String password = context.getInitParameter("password");
context.setAttribute("url", url);
context.setAttribute("username", username);
context.setAttribute("password", password);
}
protected void doGet(HttpServletRequest request,HttpServletResponse response)throws ServletException,IOException{
doPost(request, response);
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.sendRedirect("ConnectionServlet.action");
}
}
package net.yeah.fancydeepin.servlet;
import java.io.IOException;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServlet;
public class ConnectionServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
public void service(ServletRequest request, ServletResponse response) throws ServletException, IOException {
ServletContext context = getServletContext();
System.out.println("***************************************");
System.out.println("URL: " + context.getAttribute("url"));
System.out.println("Username: " + context.getAttribute("username"));
System.out.println("Password: " + context.getAttribute("password"));
System.out.println("***************************************");
super.service(request, response);
}
}
当访问 PrepareConnectionServlet.action 时, 后台打印输出:
***********************************************
URL: jdbc:oracle:thin:@localhost:1521:ORC
Username: scott
Password: tigger
***********************************************
2> ActionContext
ActionContext 是当前 Action 执行时的上下文环境, ActionContext 中维护了一些与当前 Action 相关的对象的引用,
如: Parameters (参数), Session (会话), ValueStack (值栈), Locale (本地化信息) 等。
在 Struts1 时期, Struts1 的 Action 与 Servlet API 和 JSP 技术的耦合度都很紧密, 属于一个侵入式框架:
public ActionForward execute(ActionMapping mapping,ActionForm form,HttpServletRequest request,HttpServletResponse response){
// TODO Auto-generated method stub
return null;
}
到了 Struts2 时期, Struts2 的体系结构与 Struts1 之间存在很大的不同。Struts2 在 Struts1 的基础上与 WebWork 进行了整合, 成为了一个全新的框架。
在 Struts2 里面, 则是通过 WebWork 来将与 Servlet 相关的数据信息转换成了与 Servlet API 无关的对象, 即 ActionContext 对象。
这样就使得了业务逻辑控制器能够与 Servlet API 分离开来。另外, 由于 Struts2 的 Action 是每一次用户请求都产生一个新的实例, 因此,
ActionContext 不存在线程安全问题, 可以放心使用。
package net.yeah.fancydeepin.action;
import java.util.Map;
import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.util.ValueStack;
public class ContextAction extends ActionSupport {
private static final long serialVersionUID = 1L;
private String username;
private String password;
public String execute(){
ActionContext context = ActionContext.getContext();
ValueStack value = context.getValueStack();
value.set("username", username);
value.set("password", password);
Map<String, Object> session = context.getSession();
session.put("url", "http://www.blogjava.net/fancydeepin");
return SUCCESS;
}
public void setUsername(String username) {
this.username = username;
}
public void setPassword(String password) {
this.password = password;
}
}
<s:property value="username"/><BR>
<s:property value="password"/><BR>
<s:property value="#session.url"/><BR>
当访问 context.action 并传给相应的参数的时候, 在浏览器中会输出相应的信息。
留意到上面 Struts2 的 Action 中并有没添加属性的 getting 方法, 而是手动的将参数值放到值栈(ValueStack)中的, 否则页面是得不到参数来输出的。
3> ServletActionContext
首先, ServletActionContext 是 ActionContext 的一个子类。ServletActionContext 从名字上来看, 意味着它与 Servlet API 紧密耦合。
ServletActionContext 的构造子是私有的, 主要是提供了一些静态的方法, 可以用来获取: ActionContext, ActionMapping, PageContext,
HttpServletRequest, HttpServletResponse, ServletContext, ValueStack, HttpSession 对象的引用。
public String execute(){
//或 implements ServletRequestAware
HttpServletRequest request = ServletActionContext.getRequest();
//或 implements ServletResponseAware
HttpServletResponse response = ServletActionContext.getResponse();
//或 implements SessionAware
HttpSession session = request.getSession();
//或 implements ServletContextAware
ServletContext context = ServletActionContext.getServletContext();
return SUCCESS;
}
public static int method(int n){
if(n==1){
return 1;
}else {
return n*method(n-1);
}
}
public static long fab(int i){
if(i==1||i==2){
return 1;
}else {
return fab(i-1)+fab(i-2);
}
}
1.先把编辑好的web文件放在c盘下,比如项目名是hello
2.打开cmd,进入hello中,c:\hello>
3.输入jar cvf hello.war . ,就可以在hello文件夹中找到hello.war
输入jar -cvf hello.jar *.*;
DATE_FORMAT() 函数用于以不同的格式显示日期/时间数据。
语法是
date 参数是合法的日期。format 规定日期/时间的输出格式。

下面的脚本使用 DATE_FORMAT() 函数来显示不同的格式。我们使用 NOW() 来获得当前的日期/时间:
DATE_FORMAT(NOW(),'%b %d %Y %h:%i %p') DATE_FORMAT(NOW(),'%m-%d-%Y') DATE_FORMAT(NOW(),'%d %b %y') DATE_FORMAT(NOW(),'%d %b %Y %T:%f')
结果类似:
Dec 29 2008 11:45 PM 12-29-2008 29 Dec 08 29 Dec 2008 16:25:46.635
当数据库中有个字段time,数据格式是
2013-03-25 14:35:20
按年查询:
DATE_FORMAT(timetext,'%Y')=‘2013’
按年排序
DATE_FORMAT(timetext,'%Y')
按月查询
DATE_FORMAT(timetext,'%m')='03
'
这个问题是说,你不能在对一个List进行遍历的时候将其中的元素删除掉
解决办法是,你可以先将要删除的元素用另一个list装起来,等遍历结束再remove掉
可以这样写
List delList = new ArrayList();//用来装需要删除的元素
for(Information ia:list)
if(ia.getId()==k){
n++;
delList.add(ia);
}
list.removeAll(delList);//遍历完成后执行删除
package com.test;
/**
* 动态生成随机字符数组
*
*
*/
public class ShortMessageCodeUntil
{
/**
* 随机生成4位数字字符数组
*
* @return rands
*/
public static char[] generateCheckCode()
{
String chars = "0123456789";
char[] rands = new char[4];
for (int i = 0; i < 4; i++)
{
int rand = (int) (Math.random() * 10);
rands[i] = chars.charAt(rand);
}
return rands;
}
/**
* 随机生成6位数字字符数组
*
* @return rands
*/
public static char[] generateCheckPass()
{
String chars = "0123456789";
char[] rands = new char[6];
for (int i = 0; i < 6; i++)
{
int rand = (int) (Math.random() * 10);
rands[i] = chars.charAt(rand);
}
return rands;
}
public static void main(String[] args) {
ShortMessageCodeUntil sm = new ShortMessageCodeUntil();
System.out.println(sm.generateCheckCode());
System.out.println(sm.generateCheckPass());
}
}
<div><a href="javascript:void(0)" class="aa" rel="<%=k %>">点击</a></div>
<script type="text/javascript">
$(document).ready(function(){
$(".aa").click(function(){
var id = $(this).attr("rel");
$.get('<%=basePath%>wenshi/setDaPeng', {
p :id
}, function(r,s) {
});
});
});
</script>
Builder模式定义: 将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示.
Builder模式是一步一步创建一个复杂的对象,它允许用户可以只通过指定复杂对象的类型和内容就可以构建它们.
用户不知道内部的具体构建细节.Builder模式是非常类似抽象工厂模式,细微的区别大概只有在反复使用中才能体会到.
为何使用? 是为了将构建复杂对象的过程和它的部件解耦.注意: 是解耦过程和部件.
因为一个复杂的对象,不但有很多大量组成部分,如汽车,有很多部件:车轮方向盘 发动机还有各种小零件等等,
部件很多,但远不止这些,如何将这些部件装配成一辆汽车,这个装配过程也很复杂(需要很好的组装技术),Builder模式就是为了将部件和组装过程分开.
如何使用? 首先假设一个复杂对象是由多个部件组成的,Builder模式是把复杂对象的创建和部件的创建分别开来,分别用Builder类和Director类来表示.
首先,需要一个接口,它定义如何创建复杂对象的各个部件:
public interface Builder {
//创建部件A 比如创建汽车车轮
void buildPartA();
//创建部件B 比如创建汽车方向盘
void buildPartB();
//创建部件C 比如创建汽车发动机
void buildPartC();
//返回最后组装成品结果 (返回最后装配好的汽车)
//成品的组装过程不在这里进行,而是转移到下面的Director类中进行. //从而实现了解耦过程和部件
Product getResult();
}
用Director构建最后的复杂对象,而在上面Builder接口中封装的是如何创建一个个部件(复杂对象是由这些部件组成的),也就是说Director的内容是如何将部件最后组装成成品:
public class Director {
private Builder builder;
public Director( Builder builder ) {
this.builder = builder;
} // 将部件partA partB partC最后组成复杂对象 //这里是将车轮方向盘和发动机组装成汽车的过程
public void construct() {
builder.buildPartA();
builder.buildPartB();
builder.buildPartC();
}
}
Builder的具体实现ConcreteBuilder: 通过具体完成接口Builder来构建或装配产品的部件;
定义并明确它所要创建的是什么具体东西; 提供一个可以重新获取产品的接口:
public class ConcreteBuilder implements Builder {
Part partA, partB, partC; public void buildPartA() {
//这里是具体如何构建partA的代码 };
public void buildPartB() {
//这里是具体如何构建partB的代码 };
public void buildPartC() {
//这里是具体如何构建partB的代码 };
public Product getResult() { //返回最后组装成品结果 };
复杂对象:产品Product:
public interface Product { }
复杂对象的部件:
public interface Part { }
我们看看如何调用Builder模式:
ConcreteBuilder builder = new ConcreteBuilder();
Director director = new Director( builder );
director.construct();
Product product = builder.getResult();
}
Builder模式的应用在Java实际使用中,我们经常用到"池"(Pool)的概念,当资源提供者无法提供足够的资源,并且这些资源需要被很多用户反复共享时,就需要使用池.
"池"实际是一段内存,当池中有一些复杂的资源的"断肢"(比如数据库的连接池,也许有时一个连接会中断),如果循环再利用这些"断肢",将提高内存使用效率,提高池的性能.修改Builder模式中Director类使之能诊断"断肢"断在哪个部件上,再修复这个部件.
单态定义: Singleton模式主要作用是保证在Java应用程序中,一个类Class只有一个实例存在。
在很多操作中,比如建立目录 数据库连接都需要这样的单线程操作。
还有, singleton能够被状态化; 这样,多个单态类在一起就可以作为一个状态仓库一样向外提供服务,比如,你要论坛中的帖子计数器,每次浏览一次需要计数,单态类能否保持住这个计数,并且能synchronize的安全自动加1,如果你要把这个数字永久保存到数据库,你可以在不修改单态接口的情况下方便的做到。
另外方面,Singleton也能够被无状态化。提供工具性质的功能, Singleton模式就为我们提供了这样实现的可能。使用Singleton的好处还在于可以节省内存,因为它限制了实例的个数,有利于Java垃圾回收(garbage collection)。我们常常看到工厂模式中类装入器(class loader)中也用Singleton模式实现的,因为被装入的类实际也属于资源。
public class Singleton {
private Singleton(){}
//在自己内部定义自己一个实例,是不是很奇怪? //注意这是private 只供内部调用
private static Singleton instance = new Singleton();
//这里提供了一个供外部访问本class的静态方法,可以直接访问
public static Singleton getInstance() {
return instance;
}
}
第二种形式:
public class Singleton {
private Singleton(){}
private static Singleton instance = null;
public static synchronized Singleton getInstance() {
//这个方法比上面有所改进,不用每次都进行生成对象,只是第一次 //使用时生成实例,提高了效率!
if (instance==null)
instance=new Singleton();
return instance;
}
}
使用Singleton.getInstance()可以访问单态类。
上面第二中形式是lazy initialization,也就是说第一次调用时初始Singleton,以后就不用再生成了。
注意到lazy initialization形式中的synchronized,这个synchronized很重要,如果没有synchronized,那么使用getInstance()是有可能得到多个Singleton
实例。
一般认为第一种形式要更加安全些。
工厂模式定义:提供创建对象的接口
为什么工厂模式是如此常用?因为工厂模式就相当于创建实例对象的new,我们经常要根据类Class生成实例对象,如A a=new A() 工厂模式也是用来创建实例对象的,所以以后new时就要多个心眼,是否可以考虑实用工厂模式,虽然这样做,可能多做一些工作,但会给你系统带来更大的可扩展性和尽量少的修改量。
我们以类Sample为例, 如果我们要创建Sample的实例对象:
Sample sample=new Sample();
可是,实际情况是,通常我们都要在创建sample实例时做点初始化的工作,比如赋值查询数据库等。
首先,我们想到的是,可以使用Sample的构造函数,这样生成实例就写成:
Sample sample=new Sample(参数);
但是,如果创建sample实例时所做的初始化工作不是象赋值这样简单的事,可能是很长一段代码,如果也写入构造函数中,那你的代码很难看了(就需要Refactor重整)。
为什么说代码很难看,初学者可能没有这种感觉,我们分析如下,初始化工作如果是很长一段代码,说明要做的工作很多,将很多工作装入一个方法中,相当于将很多鸡蛋放在一个篮子里,是很危险的,这也是有背于Java面向对象的原则,面向对象的封装(Encapsulation)
和分派(Delegation)告诉我们,尽量将长的代码分派“切割”成每段,将每段再“封装”起来(减少段和段之间偶合联系性),这样,就会将风险分散,以后如果需要修改,只要更改每段,不会再发生牵一动百的事情。
在本例中,首先,我们需要将创建实例的工作与使用实例的工作分开, 也就是说,让创建实例所需要的大量初始化工作从Sample的构造函数中分离出去。
这时我们就需要Factory工厂模式来生成对象了,不能再用上面简单new Sample(参数)。还有,如果Sample有个继承如MySample, 按照面向接口编程,我们需要将Sample抽象成一个接口.现在Sample是接口,有两个子类MySample 和HisSample .我们要实例化他们时,如下:
Sample mysample=new MySample(); Sample hissample=new HisSample();
随着项目的深入,Sample可能还会"生出很多儿子出来", 那么我们要对这些儿子一个个实例化,更糟糕的是,可能还要对以前的代码进行修改:加入后来生出儿子的实例.这在传统程序中是无法避免的.
但如果你一开始就有意识使用了工厂模式,这些麻烦就没有了.
工厂方法你会建立一个专门生产Sample实例的工厂:
public class Factory{
public static Sample creator(int which){
//getClass 产生Sample 一般可使用动态类装载装入类。 if (which==1) return new SampleA(); else if (which==2)
return new SampleB();
}
}
那么在你的程序中,如果要实例化Sample时.就使用
Sample sampleA=Factory.creator(1);
这样,在整个就不涉及到Sample的具体子类,达到封装效果,也就减少错误修改的机会
使用工厂方法要注意几个角色,首先你要定义产品接口,如上面的Sample,产品接口下有Sample接口的实现类,如SampleA,其次要有一个factory类,用来生成产品Sample,
进一步稍微复杂一点,就是在工厂类上进行拓展,工厂类也有继承它的实现类concreteFactory了。
抽象工厂 工厂模式中有: 工厂方法(Factory Method) 抽象工厂(Abstract Factory).
这两个模式区别在于需要创建对象的复杂程度上。如果我们创建对象的方法变得复杂了,如上面工厂方法中是创建一个对象Sample,如果我们还有新的产品接口Sample2.
这里假设:Sample有两个concrete类SampleA和SamleB,而Sample2也有两个concrete类Sample2A和SampleB2
那么,我们就将上例中Factory变成抽象类,将共同部分封装在抽象类中,不同部分使用子类实现,下面就是将上例中的Factory拓展成抽象工厂:
public abstract class Factory{
public abstract Sample creator();
public abstract Sample2 creator(String name);
}
public class SimpleFactory extends Factory{
public Sample creator(){ ......... return new SampleA }
public Sample2 creator(String name){ ......... return new Sample2A }
}
public class BombFactory extends Factory{
public Sample creator(){ ...... return new SampleB }
public Sample2 creator(String name){ ...... return new Sample2B }
}
从上面看到两个工厂各自生产出一套Sample和Sample2,也许你会疑问,为什么我不可以使用两个工厂方法来分别生产Sample和Sample2?
抽象工厂还有另外一个关键要点,是因为 SimpleFactory内,生产Sample和生产Sample2的方法之间有一定联系,所以才要将这两个方法捆绑在一个类中,这个工厂类有其本身特征,也许制造过程是统一的,比如:制造工艺比较简单,所以名称叫SimpleFactory。
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312" />
<title></title>
<!-- 引入jQuery -->
<script src="../scripts/jquery-1.3.1.js" type="text/javascript"></script>
<script type="text/javascript" >
//<![CDATA[
$(function(){
var $div_li =$("div.tab_menu ul li");
$div_li.click(function(){
$(this).addClass("selected") //当前<li>元素高亮
.siblings().removeClass("selected"); //去掉其它同辈<li>元素的高亮
var index = $div_li.index(this); // 获取当前点击的<li>元素 在 全部li元素中的索引。
$("div.tab_box > div") //选取子节点。不选取子节点的话,会引起错误。如果里面还有div
.eq(index).show() //显示 <li>元素对应的<div>元素
.siblings().hide(); //隐藏其它几个同辈的<div>元素
}).hover(function(){
$(this).addClass("hover");
},function(){
$(this).removeClass("hover");
})
})
//]]>
</script>
</head>
<body>
<div class="tab">
<div class="tab_menu">
<ul>
<li class="selected">时事</li>
<li>体育</li>
<li>娱乐</li>
</ul>
</div>
<div class="tab_box">
<div>时事</div>
<div class="hide">体育</div>
<div class="hide">娱乐</div>
</div>
</div>
</body>
</html>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title></title>
<!-- 引入jQuery -->
<script src="../scripts/jquery-1.3.1.js" type="text/javascript"></script>
<script type="text/javascript">
$(function(){
$("span").click(function(){
var thisEle = $("#para").css("font-size");
var textFontSize = parseFloat(thisEle , 10);
var unit = thisEle.slice(-2); //获取单位
var cName = $(this).attr("class");
if(cName == "bigger"){
if( textFontSize <= 22 ){
textFontSize += 2;
}
}else if(cName == "smaller"){
if( textFontSize >= 12 ){
textFontSize -= 2;
}
}
$("#para").css("font-size", textFontSize + unit);
});
});
</script>
</head>
<body>
<div class="msg">
<div class="msg_caption">
<span class="bigger" >放大</span>
<span class="smaller" >缩小</span>
</div>
<div>
<p id="para">
This is some text. This is some text. This is some text. This is some text. This
is some text. This is some text. This is some text. This is some text. This is some
text. This is some text. This is some text. This is some text. This is some text.
This is some text. This is some text. This is some text. This is some text. This
is some text. This is some text.
</p>
</div>
</div>
</body>
</html>
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<script src="../scripts/jquery-1.3.1.js" type="text/javascript"></script>
<script type="text/javascript">
$(function(){
$("#filterName").keyup(function(){
$("table tbody tr")
.hide()
.filter(":contains('"+( $(this).val() )+"')")
.show();
}).keyup();
})
</script>
</head>
<body>
<div>
<br/>
筛选:
<input id="filterName" />
<br/>
</div>
<table>
<thead>
<tr><th>姓名</th><th>性别</th><th>暂住地</th></tr>
</thead>
<tbody>
<tr><td>张山</td><td>男</td><td>浙江宁波</td></tr>
<tr><td>李四</td><td>女</td><td>浙江杭州</td></tr>
<tr><td>王五</td><td>男</td><td>湖南长沙</td></tr>
<tr><td>找六</td><td>男</td><td>浙江温州</td></tr>
<tr><td>Rain</td><td>男</td><td>浙江杭州</td></tr>
<tr><td>MAXMAN</td><td>女</td><td>浙江杭州</td></tr>
<tr><td>王六</td><td>男</td><td>浙江杭州</td></tr>
<tr><td>李字</td><td>女</td><td>浙江杭州</td></tr>
<tr><td>李四</td><td>男</td><td>湖南长沙</td></tr>
</tbody>
</table>
</body>
</html>
<html>
<head>
<script src="../scripts/jquery-1.3.1.js" type="text/javascript"></script>
<script type="text/javascript">
$(function(){
$('tr.parent').click(function(){ // 获取所谓的父行
$(this)
.toggleClass("selected") // 添加/删除高亮
.siblings('.child_'+this.id).toggle(); // 隐藏/显示所谓的子行
}).click();
})
</script>
</head>
<body>
<table>
<thead>
<tr><th>姓名</th><th>性别</th><th>暂住地</th></tr>
</thead>
<tbody>
<tr class="parent" id="row_01"><td colspan="3">前台设计组</td></tr>
<tr class="child_row_01"><td>张山</td><td>男</td><td>浙江宁波</td></tr>
<tr class="child_row_01"><td>李四</td><td>女</td><td>浙江杭州</td></tr>
<tr class="parent" id="row_02"><td colspan="3">前台开发组</td></tr>
<tr class="child_row_02"><td>王五</td><td>男</td><td>湖南长沙</td></tr>
<tr class="child_row_02"><td>找六</td><td>男</td><td>浙江温州</td></tr>
<tr class="parent" id="row_03"><td colspan="3">后台开发组</td></tr>
<tr class="child_row_03"><td>Rain</td><td>男</td><td>浙江杭州</td></tr>
<tr class="child_row_03"><td>MAXMAN</td><td>女</td><td>浙江杭州</td></tr>
</tbody>
</table>
</body>
</html>
<html>
<head>
<script src="../scripts/jquery-1.3.1.js" type="text/javascript"></script>
<script type="text/javascript">
$(function(){
$("tbody>tr:odd").addClass("odd"); //先排除第一行,然后给奇数行添加样式
$("tbody>tr:even").addClass("even"); //先排除第一行,然后给偶数行添加样式
$('tbody>tr').click(function() {
if ($(this).hasClass('selected')) {
$(this)
.removeClass('selected')
.find(':checkbox').attr('checked',false);
}else{
$(this)
.addClass('selected')
.find(':checkbox').attr('checked',true);
}
});
// 如果复选框默认情况下是选择的,则高色.
// $('table :checkbox:checked').parent().parent().addClass('selected');
//简化:
$('table :checkbox:checked').parents("tr").addClass('selected');
//$('tbody>tr:has(:checked)').addClass('selected');
})
</script>
</head>
<body>
<table>
<thead>
<tr><th> </th><th>姓名</th><th>性别</th><th>暂住地</th></tr>
</thead>
<tbody>
<tr><td><input type="checkbox" name="choice" value=""/></td>
<td>张山</td><td>男</td><td>浙江宁波</td></tr>
<tr><td><input type="checkbox" name="choice" value="" /></td>
<td>李四</td><td>女</td><td>浙江杭州</td></tr>
<tr><td><input type="checkbox" name="choice" value="" checked='checked' /></td>
<td>王五</td><td>男</td><td>湖南长沙</td></tr>
<tr><td><input type="checkbox" name="choice" value="" /></td>
<td>找六</td><td>男</td><td>浙江温州</td></tr>
<tr><td><input type="checkbox" name="choice" value="" /></td>
<td>Rain</td><td>男</td><td>浙江杭州</td></tr>
<tr><td><input type="checkbox" name="choice" value="" /></td>
<td>MAXMAN</td><td>女</td><td>浙江杭州</td></tr>
</tbody>
</table>
</body>
</html>
<html>
<head>
<script src="../scripts/jquery-1.3.1.js" type="text/javascript"></script>
<script type="text/javascript">
$(function(){
$("tbody>tr:odd").addClass("odd");
$("tbody>tr:even").addClass("even");
$('tbody>tr').click(function() {
//判断当前是否选中
var hasSelected=$(this).hasClass('selected');
//如果选中,则移出selected类,否则就加上selected类
$(this)[hasSelected?"removeClass":"addClass"]('selected')
//查找内部的checkbox,设置对应的属性。
.find(':checkbox').attr('checked',!hasSelected);
});
// 如果复选框默认情况下是选择的,则高色.
$('tbody>tr:has(:checked)').addClass('selected');
})
</script>
</head>
<body>
<table>
<thead>
<tr><th> </th><th>姓名</th><th>性别</th><th>暂住地</th></tr>
</thead>
<tbody>
<tr><td><input type="checkbox" name="choice" value=""/></td>
<td>张山</td><td>男</td><td>浙江宁波</td></tr>
<tr><td><input type="checkbox" name="choice" value="" /></td>
<td>李四</td><td>女</td><td>浙江杭州</td></tr>
<tr><td><input type="checkbox" name="choice" value="" checked='checked' /></td>
<td>王五</td><td>男</td><td>湖南长沙</td></tr>
<tr><td><input type="checkbox" name="choice" value="" /></td>
<td>找六</td><td>男</td><td>浙江温州</td></tr>
<tr><td><input type="checkbox" name="choice" value="" /></td>
<td>Rain</td><td>男</td><td>浙江杭州</td></tr>
<tr><td><input type="checkbox" name="choice" value="" /></td>
<td>MAXMAN</td><td>女</td><td>浙江杭州</td></tr>
</tbody>
</table>
</body>
</html>
<html>
<head>
<script src="../scripts/jquery-1.3.1.js" type="text/javascript"></script>
<script type="text/javascript">
$(function(){
$("tbody>tr:odd").addClass("odd"); //先排除第一行,然后给奇数行添加样式
$("tbody>tr:even").addClass("even"); //先排除第一行,然后给偶数行添加样式
$('tbody>tr').click(function() {
$(this)
.addClass('selected')
.siblings().removeClass('selected')
.end()
.find(':radio').attr('checked',true);
});
// 如果单选框默认情况下是选择的,则高色.
// $('table :radio:checked').parent().parent().addClass('selected');
//简化:
$('table :radio:checked').parents("tr").addClass('selected');
//再简化:
//$('tbody>tr:has(:checked)').addClass('selected');
})
</script>
</head>
<body>
<table>
<thead>
<tr><th> </th><th>姓名</th><th>性别</th><th>暂住地</th></tr>
</thead>
<tbody>
<tr><td><input type="radio" name="choice" value=""/></td>
<td>张山</td><td>男</td><td>浙江宁波</td></tr>
<tr><td><input type="radio" name="choice" value="" /></td>
<td>李四</td><td>女</td><td>浙江杭州</td></tr>
<tr><td><input type="radio" name="choice" value="" checked='checked' /></td>
<td>王五</td><td>男</td><td>湖南长沙</td></tr>
<tr><td><input type="radio" name="choice" value="" /></td>
<td>找六</td><td>男</td><td>浙江温州</td></tr>
<tr><td><input type="radio" name="choice" value="" /></td>
<td>Rain</td><td>男</td><td>浙江杭州</td></tr>
<tr><td><input type="radio" name="choice" value="" /></td>
<td>MAXMAN</td><td>女</td><td>浙江杭州</td></tr>
</tbody>
</table>
</body>
</html>
<html>
<head>
<script src="../scripts/jquery-1.3.1.js" type="text/javascript"></script>
<script type="text/javascript">
$(function(){
//如果是必填的,则加红星标识.
$("form :input.required").each(function(){
var $required = $("<strong class='high'> *</strong>"); //创建元素
$(this).parent().append($required); //然后将它追加到文档中
});
//文本框失去焦点后
$('form :input').blur(function(){
var $parent = $(this).parent();
$parent.find(".formtips").remove();
//验证用户名
if( $(this).is('#username') ){
if( this.value=="" || this.value.length < 6 ){
var errorMsg = '请输入至少6位的用户名.';
$parent.append('<span class="formtips onError">'+errorMsg+'</span>');
}else{
var okMsg = '输入正确.';
$parent.append('<span class="formtips onSuccess">'+okMsg+'</span>');
}
}
//验证邮件
if( $(this).is('#email') ){
if( this.value=="" || ( this.value!="" && !/.+@.+\.[a-zA-Z]{2,4}$/.test(this.value) ) ){
var errorMsg = '请输入正确的E-Mail地址.';
$parent.append('<span class="formtips onError">'+errorMsg+'</span>');
}else{
var okMsg = '输入正确.';
$parent.append('<span class="formtips onSuccess">'+okMsg+'</span>');
}
}
}).keyup(function(){
$(this).triggerHandler("blur");
}).focus(function(){
$(this).triggerHandler("blur");
});//end blur
//提交,最终验证。
$('#send').click(function(){
$("form :input.required").trigger('blur');
var numError = $('form .onError').length;
if(numError){
return false;
}
alert("注册成功,密码已发到你的邮箱,请查收.");
});
//重置
$('#res').click(function(){
$(".formtips").remove();
});
})
</script>
</head>
<body>
<form method="post" action="">
<div class="int">
<label for="username">用户名:</label>
<input type="text" id="username" class="required" />
</div>
<div class="int">
<label for="email">邮箱:</label>
<input type="text" id="email" class="required" />
</div>
<div class="int">
<label for="personinfo">个人资料:</label>
<input type="text" id="personinfo" />
</div>
<div class="sub">
<input type="submit" value="提交" id="send"/><input type="reset" id="res"/>
</div>
</form>
</body>
</html>
<html>
<head>
<style type="text/css">
* { margin:0; padding:0; }
div.centent {
float:left;
text-align: center;
margin: 10px;
}
span {
display:block;
margin:2px 2px;
padding:4px 10px;
background:#898989;
cursor:pointer;
font-size:12px;
color:white;
}
</style>
<script src="../scripts/jquery-1.3.1.js" type="text/javascript"></script>
<script type="text/javascript">
$(function(){
//移到右边
$('#add').click(function() {
//获取选中的选项,删除并追加给对方
$('#select1 option:selected').appendTo('#select2');
});
//移到左边
$('#remove').click(function() {
$('#select2 option:selected').appendTo('#select1');
});
//全部移到右边
$('#add_all').click(function() {
//获取全部的选项,删除并追加给对方
$('#select1 option').appendTo('#select2');
});
//全部移到左边
$('#remove_all').click(function() {
$('#select2 option').appendTo('#select1');
});
//双击选项
$('#select1').dblclick(function(){ //绑定双击事件
//获取全部的选项,删除并追加给对方
$("option:selected",this).appendTo('#select2'); //追加给对方
});
//双击选项
$('#select2').dblclick(function(){
$("option:selected",this).appendTo('#select1');
});
$('#findall').click(function(){
var len= $('#select2 option').length;
for(var i=0;i<len;i++){
//$('#select2').get(i).value;
alert($('#select2 option')[i].value);
}
});
});
</script>
</head>
<body>
<div class="centent">
<select multiple="multiple" id="select1" style="width:100px;height:160px;">
<option value="1">选项1</option>
<option value="2">选项2</option>
<option value="3">选项3</option>
<option value="4">选项4</option>
<option value="5">选项5</option>
<option value="6">选项6</option>
<option value="7">选项7</option>
</select>
<div>
<span id="add" >选中添加到右边>></span>
<span id="add_all" >全部添加到右边>></span>
</div>
</div>
<div class="centent">
<select multiple="multiple" id="select2" style="width: 100px;height:160px;">
<option value="8">选项8</option>
</select>
<div>
<span id="remove"><<选中删除到左边</span>
<span id="remove_all"><<全部删除到左边</span>
<span id="findall"><<选中的所有值</span>
</div>
</div>
</body>
</html>
File f = new File("c://a.txt");
BufferedInputStream bis =new BufferedInputStream(new FileInputStream(f));
byte[] buffer = new byte[1024];
response.setContentType("application/octet-stream");
//定义下载文件的名字
String a = new String(z.getZiname().getBytes("utf-8"),"iso8859-1");
response.setHeader("Content-Disposition", "attachment; filename=\"" + a+"c://a.txt".substring("c://a.txt".lastIndexOf(".")) + "\"");
OutputStream os = response.getOutputStream();
int len = -1;
while((len=bis.read(buffer))!=-1){
os.write(buffer, 0, len);
}
os.flush();
os.close();
bis.close();
复选框 按钮
<html>
<head>
<script src="../scripts/jquery-1.3.1.js" type="text/javascript"></script>
<script type="text/javascript">
$(function(){
//全选
$("#CheckedAll").click(function(){
$('[name=items]:checkbox').attr('checked', true);
});
//全不选
$("#CheckedNo").click(function(){
$('[type=checkbox]:checkbox').attr('checked', false);
});
//反选
$("#CheckedRev").click(function(){
$('[name=items]:checkbox').each(function(){
//此处用JQ写法颇显啰嗦。体现不出JQ飘逸的感觉。
//$(this).attr("checked", !$(this).attr("checked"));
//直接使用JS原生代码,简单实用
this.checked=!this.checked;
});
});
//输出值
$("#send").click(function(){
var str="你选中的是:\r\n";
$('[name=items]:checkbox:checked').each(function(){
str+=$(this).val()+"\r\n";
})
alert(str);
});
})
</script>
</head>
<body>
<form method="post" action="">
你爱好的运动是?
<br/>
<input type="checkbox" name="items" value="足球"/>足球
<input type="checkbox" name="items" value="篮球"/>篮球
<input type="checkbox" name="items" value="羽毛球"/>羽毛球
<input type="checkbox" name="items" value="乒乓球"/>乒乓球
<br/>
<input type="button" id="CheckedAll" value="全 选"/>
<input type="button" id="CheckedNo" value="全不选"/>
<input type="button" id="CheckedRev" value="反 选"/>
<input type="button" id="send" value="提 交"/>
</form>
</body>
</html>
复选框
<html>
<head>
<script src="../scripts/jquery-1.3.1.js" type="text/javascript"></script>
<script>
$(function(){
//全选
$("#CheckedAll").click(function(){
if(this.checked){ //如果当前点击的多选框被选中
$('input[type=checkbox][name=items]').attr("checked", true );
}else{
$('input[type=checkbox][name=items]').attr("checked", false );
}
});
$('input[type=checkbox][name=items]').click(function(){
var flag=true;
$('input[type=checkbox][name=items]').each(function(){
if(!this.checked){
flag = false;
}
});
if( flag ){
$('#CheckedAll').attr('checked', true );
}else{
$('#CheckedAll').attr('checked', false );
}
});
//输出值
$("#send").click(function(){
var str="你选中的是:\r\n";
$('input[type=checkbox][name=items]:checked').each(function(){
str+=$(this).val()+"\r\n";
})
alert(str);
});
})
</script>
</head>
<body>
<form>
你爱好的运动是?<input type="checkbox" id="CheckedAll" />全选/全不选<br/>
<input type="checkbox" name="items" value="足球"/>足球
<input type="checkbox" name="items" value="篮球"/>篮球
<input type="checkbox" name="items" value="羽毛球"/>羽毛球
<input type="checkbox" name="items" value="乒乓球"/>乒乓球<br/>
<input type="button" id="send" value="提 交"/>
</form>
</body>
</html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<script src="../scripts/jquery-1.3.1.js" type="text/javascript"></script>
<script type="text/javascript">
$(function(){
//全选
$("#CheckedAll").click(function(){
//所有checkbox跟着全选的checkbox走。
$('[name=items]:checkbox').attr("checked", this.checked );
});
$('[name=items]:checkbox').click(function(){
//定义一个临时变量,避免重复使用同一个选择器选择页面中的元素,提升程序效率。
var $tmp=$('[name=items]:checkbox');
//用filter方法筛选出选中的复选框。并直接给CheckedAll赋值。
$('#CheckedAll').attr('checked',$tmp.length==$tmp.filter(':checked').length);
/*
//一行做过多的事情需要写更多注释。复杂选择器还可能影响效率。因此不推荐如下写法。
$('#CheckedAll').attr('checked',!$('[name=items]:checkbox').filter(':not(:checked)').length);
*/
});
//输出值
$("#send").click(function(){
var str="你选中的是:\r\n";
$('[name=items]:checkbox:checked').each(function(){
str+=$(this).val()+"\r\n";
})
alert(str);
});
});
</script>
</head>
<body>
<form method="post" action="">
你爱好的运动是?<input type="checkbox" id="CheckedAll" />全选/全不选<br/>
<input type="checkbox" name="items" value="足球"/>足球
<input type="checkbox" name="items" value="篮球"/>篮球
<input type="checkbox" name="items" value="羽毛球"/>羽毛球
<input type="checkbox" name="items" value="乒乓球"/>乒乓球<br/>
<input type="button" id="send" value="提 交"/>
</form>
</body>
</html>
<html>
<head>
<style type="text/css">
body{
font:normal 12px/17px Arial;
}
div{
padding:2px;
}
input, textarea {
width: 12em;
border: 1px solid #888;
}
.focus {
border: 1px solid #f00;
background: #fcc;
}
</style>
<!-- 引入jQuery -->
<script src="../scripts/jquery-1.3.1.js" type="text/javascript"></script>
<script type="text/javascript">
$(function(){
$(":input").focus(function(){
$(this).addClass("focus");
if($(this).val() ==this.defaultValue){
$(this).val("");
}
}).blur(function(){
$(this).removeClass("focus");
if ($(this).val() == '') {
$(this).val(this.defaultValue);
}
});
})
</script>
</head>
<body>
<form action="" method="post" id="regForm">
<fieldset>
<legend>个人基本信息</legend>
<div>
<label for="username">名称:</label>
<input id="username" type="text" value="名称" />
</div>
<div>
<label for="pass">密码:</label>
<input id="pass" type="password" value="密码" />
</div>
<div>
<label for="msg">详细信息:</label>
<textarea id="msg" rows="2" cols="20">详细信息</textarea>
</div>
</fieldset>
</form>
</body>
</html>
先要导入jxl需要的jar包,然后在触发导出excel时传入集合对象,例如:
public class ToExcel {
public static void excel(List<WenShi> l,HttpServletResponse response) {
ServletOutputStream out = null;
WritableWorkbook wwb = null;
try {
// 导出Excel路径
Date d = new Date();
String s = new SimpleDateFormat("yyyyMMddHHmmss").format(d);
response.setCharacterEncoding("utf-8");
response.reset();
response.setContentType("application/vnd.ms-excel;charset=utf-8");
response.setHeader("Content-Disposition", "attachment;filename="
+ new String("历史数据.xls".getBytes(),"iso-8859-1"));
out = response.getOutputStream();
WritableSheet ws = null;
wwb = Workbook.createWorkbook(out);
ws = wwb.createSheet("sheet1", 0);
// 文字样式
WritableFont wf = new WritableFont(WritableFont.TIMES, 10,
WritableFont.BOLD, false);
WritableCellFormat wcff = new WritableCellFormat(wf);
// 标题
// 第一列第1行(0,0)
Label label1 = new Label(0, 0, "编号", wcff);
// 第一列第2行(0,1)
Label label2 = new Label(1, 0, "环境温度", wcff);
// 第一列第3行(0,2)
Label label3 = new Label(2, 0, "环境湿度", wcff);
Label label4 = new Label(3, 0, "光照强度", wcff);
Label label5 = new Label(4, 0, "土壤温度", wcff);
Label label6 = new Label(5, 0, "土壤湿度", wcff);
Label label7 = new Label(6, 0, "co2浓度", wcff);
// 第一列第4行(0,3)
Label label8 = new Label(7, 0, "时间", wcff);
// 第一列第5行(0,4)
Label label9 = new Label(8, 0, "星期几", wcff);
ws.addCell(label1);
ws.addCell(label2);
ws.addCell(label3);
ws.addCell(label4);
ws.addCell(label5);
ws.addCell(label6);
ws.addCell(label7);
ws.addCell(label8);
ws.addCell(label9);
for (int i = 0; i < l.size(); i++) {
Label l1 = new Label(0, i + 1, l.get(i).getStr("node"));
Label l2 = new Label(1, i + 1, l.get(i).getStr("wen"));
Label l3 = new Label(2, i + 1, l.get(i).getStr("shi"));
Label l4 = new Label(3, i + 1, l.get(i).getStr("sun"));
Label l5 = new Label(4, i + 1, l.get(i).getStr("tuwen"));
Label l6 = new Label(5, i + 1, l.get(i).getStr("tushi"));
Label l7 = new Label(6, i + 1, l.get(i).getStr("co"));
Label l8 = new Label(7, i + 1, l.get(i)
.getTimestamp("timetext").toString());
Label l9 = new Label(8, i + 1, l.get(i).getStr("week"));
ws.addCell(l1);
ws.addCell(l2);
ws.addCell(l3);
ws.addCell(l4);
ws.addCell(l5);
ws.addCell(l6);
ws.addCell(l7);
ws.addCell(l8);
ws.addCell(l9);
}
wwb.write();
} catch (Exception e) {
e.printStackTrace();
}finally{
try {
wwb.close();
} catch (WriteException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
onblur 事件 发生在窗口失去焦点的时候。应用于:window 对象
onchange 事件 发生在文本输入区的内容被更改,然 后焦点从文本输入区
移走之后。捕捉此事件主要用于实时检测输入的有效性,或者立刻改变文
档内容。应 用于:P assword 对象;S elect 对象;T ext 对象;T extarea 对
象
onclick 事件 发生在对象被单击的时候。单击是指鼠标停留在对象上,
按下鼠标键,没有移动鼠标而放开鼠标键这一个完整的过程。一个普通按
钮对象(Button)通常会有 onclick 事件处理程序,因为这种对象根本
不能从用户那里得到任何信息,没 有 onclick 事件处理程序就等于废柴。
按钮上添加 onclick 事件处理程序,可以模拟“另一个提交按钮”,方
法是:在事件处理程序中更改表单的 action, target, encoding, method
等一个或几个属性,然后调用表单的 submit() 方法。在 Link 对象的
onclick 事件处理程序中返回 false 值(return false),能阻止浏览
器打开此连接。即 ,如 果有一个这样的连接:< a href="http://www.a.com"
onclick="return false">Go!</a>,那么无论用户怎样点击,都不会去到
www.a.com 网站,除 非用户禁止浏览器运行 JavaScript。应 用于:B utton
对象;Checkbox 对象;Image 对象;Link 对象;Radio 对象;Reset 对
象;Submit 对象
onerror 事件 发生在错误发生的时候。它的事件处理程序通常就叫做
“错误处理程序”(Error Handler),用来处理错误。上边已经介绍过,
要忽略一切错误,就使用:
function ignoreError() {
return true;
}
window.onerror = ignoreError;
应用于:window 对象
onfocus 事件 发生在窗口得到焦点的时候。应用于:window 对象
onload 事件 发生在文档全部下载完毕的时候。全 部下载完毕意味着不但
HTML 文件,而且包含的图片,插件,控件,小程序等全部内容都下载完
毕。本 事件是 window 的事件,但 是在 HTML 中指定事件处理程序的时候,
我们是把它写在<body>标记中的。应用于:window 对象
onmousedown 事件 发生在用户把鼠标放在对象上按下鼠标键的时候。参
考 onmouseup 事件。应用于:Button 对象;Link 对象
onmouseout 事件 发生在鼠标离开对象的时候。参 考 onmouseover 事件。
应用于:Link 对象
onmouseover 事件 发生在鼠标进入对象范围的时候。这个事件和
onmouseout 事件,再加上图片的预读,就可以做到当鼠标移到图像连接
上,图像更改的效果了。有时我们看到,在指向一个连接时,状态栏上不
显示地址,而显示其它的资料,看起来这些资料是可以随时更改的。它们
是这样做出来的:
<a href="..." onmouseover="window.status='Click Me Please!';
return true;" onmouseout="window.status=''; return true;">
应用于:Link 对象
onmouseup 事件 发生在用户把鼠标放在对象上鼠标键被按下的情况下,
放开鼠标键的时候。如果按下鼠标键的时候,鼠标并不在放开鼠标的对象
上,则本事件不会发生。应用于:Button 对象;Link 对象
onreset 事件 发生在表单的“重置”按钮被单击(按下并放开)的时候。
通过在事件处理程序中返回 false 值(return false)可以阻止表单重
置。应用于:Form 对象
onresize 事件 发生在窗口被调整大小的时候。应用于:window 对象
onsubmit 事件 发生在表单的“提交”按钮被单击( 按下并放开)的 时候。
可以使用该事件来验证表单的有效性。通 过在事件处理程序中返回 false
值(return false)可以阻止表单提交。应用于:Form 对象
onunload 事件 发生在用户退出文档(或者关闭窗口,或者到另一个页面
去)的时候。与 onload 一样,要写在 HTML 中就写到<body>标记里。
有的 Web Masters 用这个方法来弹出“调查表单”,以“强迫”来者填
写;有的就弹出广告窗口,唆使来者点击连接。我觉得这种
“onunload="open..."”的方法很不好,有 时甚至会因为弹出太多窗口而
导致资源缺乏。有 什么对来者说就应该在网页上说完,不 对吗? 应用于:
window 对象
Document 文档对象是JavaScript 中window 和frames 对象的一个属性,是显示
于窗口或框架内的一个文档。描述当前窗口或指定窗口对象的文档。它包含了文
档从<head>到</body>的内容。
用法:document (当前窗口) 或 <窗口对象>.document (指定窗口)
属性:
document.title //设置文档标题等价于HTML 的<title>标签
document.bgColor //设置页面背景色
document.fgColor //设置前景色(文本颜色)
document.linkColor //未点击过的链接颜色
document.alinkColor //激活链接(焦点在此链接上)的颜色
document.vlinkColor //已点击过的链接颜色
document.URL //设置URL 属性从而在同一窗口打开另一网页
document.fileCreatedDate //文件建立日期,只读属性
document.fileModifiedDate //文件修改日期,只读属性
document.fileSize //文件大小,只读属性
document.cookie //设置和读出cookie
document.charset //设置字符集 简体中文:gb2312
cookie 关于 cookie 请参看“使用框架和 Cookies”一章。
lastModified 当前文档的最后修改日期,是一个 Date 对象。
referrer 如果当前文档是通过点击连接打开的,则 referrer 返回原来
的 URL。
title 指<head>标记里用<title>...</title>定义的文字。在 Netscape
里本属性不接受赋值。
fgColor 指<body>标记的 text 属性所表示的文本颜色。
bgColor 指<body>标记的 bgcolor 属性所表示的背景颜色。
linkColor 指<body>标记的 link 属性所表示的连接颜色。
alinkColor 指<body>标记的 alink 属性所表示的活动连接颜色。
vlinkColor 指<body>标记的 vlink 属性所表示的已访问连接颜色。
方法:
open() 打开文档以便 JavaScript 能向文档的当前位置(指插入
JavaScript 的位置)写入数据。通常不需要用这个方法,在需要的时候
JavaScript 自动调用。
write(); writeln() 向文档写入数据,所写入的会当成标准文档 HTML
来处理。writeln() 与 write() 的不同点在于,writeln() 在写入数据
以后会加一个换行。这个换行只是在 HTML 中换行,具体情况能不能够是
显示出来的文字换行,要看插入 JavaScript 的位置而定。如在<pre>标
记中插入,这个换行也会体现在文档中。
clear() 清空当前文档。
close() 关闭文档,停止写入数据。如果用了 write[ln]() 或 clear()
方法,就一定要用 close() 方法来保证所做的更改能够显示出来。如果
文档还没有完全读取,也就是说,JavaScript 是插在文档中的,那就不
必使用该方法。
location 地址对象 它描述的是某一个窗口对象所打开的地址。要 表示当前窗口
的地址,只需要使用“location”就行了;若要表示某一个窗口的地址,就使用
“<窗口对象>.location”。先 前写了一片用window.location.href实现刷新另
个框架页面 ,特此我看了一下locaiton 的详细用法,对此有点改进,具体如
下:
注意:属于不同协议或不同主机的两个地址之间不能互相引用对方的 location
对象,这是出于安全性的需要。例如,当前窗口打开的是“www.a.com”下面的
某一页,另外一个窗口(对象名为:bWindow)打开的是“www.b.com”的网页。
如果在当前窗口使用“bWindow.location”,就会出错:“没有权限”。这个错
误是不能用错误处理程序(Event Handler,参阅 onerror 事件)来接收处理的。
第一、简单介绍一下location 属性、用法以及相关示例:
Location
包含了关于当前 URL 的信息。location 对象描述了与一个给定的 Window 对象
关联的完整 URL。location 对象的每个属性都描述了 URL 的不同特性。
通常情况下,一 个 URL 会有下面的格式:协 议//主机:端口/路径名称#哈希标识?
搜索条件
例如:url 这
些部分是满足下列需求的:
“协议”是 URL 的起始部分,直到包含到第一个冒号。
“主机”描述了主机和域名,或者一个网络主机的 IP 地址。
“端口”描述了服务器用于通讯的通讯端口。
路径名称描述了 URL 的路径方面的信息。
“哈希标识”描述了 URL 中的锚名称,包括哈希掩码(#)。此属性只应用
于 HTTP 的 URL。
“搜索条件”描述了该 URL 中的任何查询信息,包括问号。此属性只应
用于 HTTP 的 URL。“搜索条件”字符串包含变量和值的配对;每对之间
由一个“&”连接。
属性概览
protocol 返回地址的协议,取值为 'http:','https:','file:' 等等。
hostname 返回地址的主机名,例如,一个“
http://www.microsoft.com/china/”的地址,location.hostname ==
'www.microsoft.com'。
· port 返回地址的端口号,一般 http 的端口号是 '80'。
· host 返回主机名和端口号,如:'www.a.com:8080'。
· pathname 返回路径名,如“http://www.a.com/b/c.html”,
location.pathname == 'b/c.html'。
· hash 返回“#”以及以后的内容,如“
http://www.a.com/b/c.html#chapter4”,location.hash ==
'#chapter4';如果地址里没有“#”,则返回空字符串。
· search 返回“?”以及以后的内容,如“
http://www.a.com/b/c.asp?selection=3&jumpto=4”,l ocation.search
== '?selection=3&jumpto=4';如果地址里没有“?”,则返回空字符串。
href 返回以上全部内容,也就是说,返回整个地址。在浏览器的地址栏
上怎么显示它就怎么返回。如果想一个窗口对象打开某地址,可以使用
“location.href = '...'”,也可以直接用“location = '...'”来达
到此目的。
方法概览
reload() 相当于按浏览器上的“刷新”(IE)或“Reload”(Netscape)
键。
replace() 打开一个 URL,并取代历史对象中当前位置的地址。用这个方
法打开一个 URL 后,按 下浏览器的“后退”键将不能返回到刚才的页面。
location 之页面跳转js 如下:
//简单跳转
function gotoPage(url) {
// eg. var url =
"newsview.html?catalogid="+catalogID+"&pageid="+pageid;
window.location = url;
}
// 对location 用法的升级,为单个页面传递参数
function goto_catalog(iCat) {
if(iCat<=0) {
top.location = "../index.aspx"; // top 出去
} else {
window.location = "../newsCat.aspx?catid="+iCat;
}
}
对指定框架进行跳转页面,二种方法皆可用
function goto_iframe(url) {
parent.mainFrame.location = "../index.aspx"; //
// parent.document.getElementById("mainFrame").src =
"../index.aspx";// use dom to change page // 同时我增加了dom 的写法
}
// 对指定框架进行跳转页面,因为
parent.iframename.location="../index.aspx"; 方法不能实行,主要是
"parent.iframename" 中的iframename在js 中被默认为节点,而 不能把传递过
来的参数转换过来,所以用dom 实现了该传递二个参数的框架跳转页面,希望那
位仁兄不吝赐教!
function goto_iframe(iframename,url) {
parent.document.getElementById(iframename).src = "../index.aspx";//
use dom to change page by iframeName
//}
// 回到首页
function gohome() {
top.location = "/index.aspx";
}
JavaScript 中的History 历史对象包含了用户已浏览的 URL 的信息,是指历史
对象指浏览器的浏览历史。鉴于安全性的需要,该对象收到很多限制,现在只剩
下下列属性和方法。History 历史对象有length 这个属性,列出历史的项数。
JavaScript 所能管到的历史被限制在用浏览器的“前进”“后退”键可以去到
的范围。本属性返回的是“前进”和“后退”两个按键之下包含的地址数的和。
History 历史对象并有以下方法
back() 后退,跟按下“后退”键是等效的。
forward() 前进,跟按下“前进”键是等效的。
go() 用法:history.go(x);在历史的范围内去到指定的一个地址。如果
x < 0,则后退 x 个地址,如果 x > 0,则前进 x 个地址,如果 x == 0,
则刷新现在打开的网页。history.go(0) 跟 location.reload() 是等效
的。
Window是JavaScript 中最大的对象,它描述的是一个浏览器窗口。一般要引用它的
属性和方法时,不需要用“window.xxx”这种形式,而直接使用“xxx”。一个
框架页面也是一个窗口。
Window 窗口对象有如下属性:
name 窗口的名称,由 打开它的连接( <a target="...">)或 框架页( <frame
name="...">)或某一个窗口调用的 open() 方法(见下)决定。一般我
们不会用这个属性。
status 指窗口下方的“状态栏”所显示的内容。通过对 status 赋值,
可以改变状态栏的显示。
opener 用法:window.opener;返回打开本窗口的窗口对象。注意:返回
的是一个窗口对象。如果窗口不是由其他窗口打开的,在 Netscape 中这
个属性返回 null;在 IE 中返回“未定义”( undefined)。u ndefined 在
一定程度上等于 null。注意:undefined 不是 JavaScript 常数,如果
你企图使用“undefined”,那就真的返回“未定义”了。
self 指窗口本身,它返回的对象跟 window 对象是一模一样的。最常用
的是“self.close()”,放在<a>标记中:“<a
href="javascript:self.close()">关闭窗口</a>”。
parent 返回窗口所属的框架页对象。
top 返回占据整个浏览器窗口的最顶端的框架页对象。
history 历史对象,
location 地址对象,
document 文档对象,
Window 窗口对象有如下方法:
第一个方法是open() 打开一个窗口。
用法:
open(<URL 字符串>, <窗口名称字符串>, <参数字符串>);
说明:
<URL 字符串>:描述所打开的窗口打开哪一个网页。如果留空(''),则
不打开任意网页。
<窗口名称字符串>:描述被打开的窗口的名称(window.name),可以使
用'_top'、'_blank'等内建名称。这里的名称跟“<a href="..."
target="...">”里的“target”属性是一样的。
<参数字符串>:描 述被打开的窗口的样貌。如 果只需要打开一个普通窗口,
该字符串留空(''),如果要指定样貌,就在字符串里写上一到多个参数,
参数之间用逗号隔开。
例:打开一个 400 x 100 的干净的窗口:
open('','_blank','width=400,height=100,menubar=no,toolbar=no,
location=no,directories=no,status=no, scrollbars=yes,resizable=yes')
open()的参数
top=# 窗口顶部离开屏幕顶部的像素数
left=# 窗口左端离开屏幕左端的像素数
width=# 窗口的宽度
height=# 窗口的高度
menubar=... 窗口有没有菜单,取值yes 或no
toolbar=... 窗口有没有工具条,取值yes 或 no
location=... 窗口有没有地址栏,取值yes 或no
directories=... 窗口有没有连接区,取值yes 或no
scrollbars=... 窗口有没有滚动条,取值yes 或no
status=... 窗口有没有状态栏,取值yes 或no
resizable=... 窗口给不给调整大小,取值yes 或no
注意:open() 方法有返回值,返回的就是它打开的窗口对象。比如
var newWindow = open('','_blank');
这样把一个新窗口赋值到“newWindow”变量中,以 后通过“newWindow”变量就
可以控制窗口了。
close() 关闭一个已打开的窗口。
用法:
window.close()
或
self.close()
主要作用是关闭本窗口;
<窗口对象>.close():关闭指定的窗口。注意如果该窗口有状态栏,调用该方法
后浏览器会警告:“网页正在试图关闭窗口,是否关闭?”然后等待用户选择是
否;如果没有状态栏,调用该方法将直接关闭窗口。
另外Window 窗口对象还有如下方法
blur() 使焦点从窗口移走,窗口变为“非活动窗口”。
focus() 是窗口获得焦点,变为“活动窗口”。不过在 Windows 98,该
方法只能使窗口的标题栏和任务栏上的相应按钮闪烁,提 示用户该窗口正
在试图获得焦点。
scrollTo() 用法:&e1;<窗口对象>.&e3;scrollTo(x, y);使窗口滚动,使文档
从左上角数起的(x, y)点滚动到窗口的左上角。
scrollBy() 用法:&e1;<窗口对象>.&e3;scrollBy(deltaX, deltaY);使窗口向
右滚动 deltaX 像素,向下滚动 deltaY 像素。如果取负值,则向相反的
方向滚动。
resizeTo() 用法:&e1;<窗口对象>.&e3;resizeTo(width, height);使窗口调
整大小到宽 width 像素,高 height 像素。
resizeBy() 用法:&e1;<窗口对象>.&e3;resizeBy(deltaWidth, deltaHeight);
使窗口调整大小,宽增大 deltaWidth 像素,高增大 deltaHeight 像素。
如果取负值,则减少。
alert() 用法:alert(<字符串>);弹出一个只包含“确定”按钮的对话
框,显示<字符串>的内容,整个文档的读取、Script 的运行都会暂停,
直到用户按下“确定”。
confirm() 用法:c onfirm(<字符串>);弹 出一个包含“确定”和“取消”
按钮的对话框,显示<字符串>的内容,要求用户做出选择,整个文档的读
取、Script 的运行都会暂停。如果用户按下“确定”,则返回 true 值,
如果按下“取消”,则返回 false 值。
prompt() 用法:prompt(<字符串>[, <初始值>]);弹出一个包含“确
认”“取消”和一个文本框的对话框,显示<字符串>的内容,要求用户在
文本框输入一些数据,整个文档的读取、Script 的运行都会暂停。如果
用户按下“确认”,则 返回文本框里已有的内容,如 果用户按下“取消”,
则返回 null 值。如果指定<初始值>,则文本框里会有默认值。
Window 窗口对象有如下事件:
window.onload;发生在文档全部下载完毕的时候。全部下载完毕意味着不但
HTML 文件,而且包含的图片,插件,控件,小程序等全部内容都下载完毕。本
事件是 window 的事件,但是在 HTML 中指定事件处理程序的时候,我们是把它
写在<body>标记中的。
window.onunload;发生在用户退出文档(或者关闭窗口,或者到另一个页面去)
的时候。与 onload 一样,要写在 HTML 中就写到<body>标记里。
window.onresize;发生在窗口被调整大小的时候。
window.onblur;发生在窗口失去焦点的时候。
window.onfocus;发生在窗口得到焦点的时候。
window.onerror;发生在错误发生的时候。它的事件处理程序通常就叫做
“错误处理程序”(Error Handler),用来处理错误。上边已经介绍过,
要忽略一切错误,就使用:
function ignoreError() {
return true;
}
window.onerror = ignoreError;
navigator 浏览器对象,包含了正在使用的 Navigator 的版本信息。反映了当
前使用的浏览器的资料。JavaScript 客户端运行时刻引擎自动创建 navigator
对象。
包括一下几大属性:
· appCodeName 返回浏览器的“码名”(?),流行的 IE 和 NN 都返回
'Mozilla'。
下面的例子显示了 appCodeName 属性的值:
document.write("navigator.appCodeName 的值是" +
navigator.appCodeName)
· appName 返回浏览器名。I E 返回 'Microsoft Internet Explorer',N N 返
回 'Netscape'。
下面的例子显示了 appName 属性的值:
document.write("navigator.appName 的值是 " + navigator.appName)
· appVersion 返回浏览器版本,包括了大版本号、小版本号、语言、操作
平台等信息。
· language 语言
· mimeType 以数组表示所支持的MIME 类型
· platform 返回浏览器的操作平台,对于 Windows 9x 上的浏览器,返回
'Win32'(大小写可能有差异)。
· userAgent 返回以上全部信息。例如,IE5.01 返回 'Mozilla/4.0
(compatible; MSIE 5.01; Windows 98)'。
· plugins 以数组表示已安装的外挂程序
· javaEnabled() 返回一个布尔值,代表当前浏览器允许不允许 Java。
以下有很多“g/set[UTC]XXX”这样的方法,它表示既有“getXXX”方法,又有
“setXXX”方法。“get”是获得某个数值,而“set”是设定某个数值。如果带
有“UTC”字母,则表示获得/设定的数值是基于 UTC 时间的,没有则表示基于
本地时间或浏览期默认时间的。
如无说明,方法的使用格式为:“<对象>.<方法>”,下同。
g/set[UTC]FullYear() 返回/设置年份,用四位数表示。如果使用
“x.set[UTC]FullYear(99)”,则年份被设定为 0099 年。
g/set[UTC]Year()返回/设置年份,用两位数表示。设定的时候浏览器自动加上
“19”开头,故使用“x.set[UTC]Year(00)”把年份设定为 1900 年。
g/set[UTC]Month()返回/设置月份。
g/set[UTC]Date()返回/设置日期。
g/set[UTC]Day()返回/设置星期,0 表示星期天。
g/set[UTC]Hours()返回/设置小时数,24 小时制。
g/set[UTC]Minutes()返回/设置分钟数。
g/set[UTC]Seconds()返回/设置秒钟数。
g/set[UTC]Milliseconds()返回/设置毫秒数。
g/setTime() 返回/设置时间,该 时间就是日期对象的内部处理方法:从 1970 年
1 月 1 日零时正开始计算到日期对象所指的日期的毫秒数。如果要使某日期对
象所指的时间推迟 1 小时,就用:“x.setTime(x.getTime() + 60 * 60 *
1000);”(一小时 60 分,一分 60 秒,一秒 1000 毫秒)。
getTimezoneOffset() 返回日期对象采用的时区与格林威治时间所差的分钟数。
在格林威治东方的市区,该值为负,例如:中国时区(GMT+0800)返回“-480”。
toString() 返回一个字符串,描述日期对象所指的日期。这个字符串的格式类
似于:“Fri Jul 21 15:43:46 UTC+0800 2000”。
toLocaleString() 返回一个字符串,描述日期对象所指的日期,用本地时间表
示格式。如:“2000-07-21 15:43:46”。
toGMTString() 返回一个字符串,描述日期对象所指的日期,用 GMT 格式。
toUTCString() 返回一个字符串,描述日期对象所指的日期,用 UTC 格式。
parse() 用法:Date.parse(<日期对象>);返回该日期对象的内部表达方式。
Math “数学”对象,提供对数据的数学计算。下面所提到的属性和方法,大家在使用的时候记住用“Math.<名>”这种格式。
属性
E 返回常数 e (2.718281828...)。
LN2 返回 2 的自然对数 (ln 2)。
LN10 返回 10 的自然对数 (ln 10)。
LOG2E 返回以 2 为低的 e 的对数 (log2e)。
LOG10E 返回以 10 为低的 e 的对数 (log10e)。
PI 返回π(3.1415926535...)。
SQRT1_2 返回 1/2 的平方根。
SQRT2 返回 2 的平方根。
方法
abs(x) 返回 x 的绝对值。
acos(x) 返回 x 的反余弦值(余弦值等于 x 的角度),用弧度表示。
asin(x) 返回 x 的反正弦值。
atan(x) 返回 x 的反正切值。
atan2(x, y) 返回复平面内点(x, y)对应的复数的幅角,用 弧度表示,其 值在 -π
到 π 之间。
ceil(x) 返回大于等于 x 的最小整数。
cos(x) 返回 x 的余弦。
exp(x) 返回 e 的 x 次幂 (ex)。
floor(x) 返回小于等于 x 的最大整数。
log(x) 返回 x 的自然对数 (ln x)。
max(a, b) 返回 a, b 中较大的数。
min(a, b) 返回 a, b 中较小的数。
pow(n, m) 返回 n 的 m 次幂 (nm)。
random() 返回大于 0 小于 1 的一个随机数。
round(x) 返回 x 四舍五入后的值。
sin(x) 返回 x 的正弦。
sqrt(x) 返回 x 的平方根。
tan(x) 返回 x 的正切。
Date 日期对象。这个对象可以储存任意一个日期,从 0001 年到 9999 年,并
且可以精确到毫秒数( 1/1000 秒)。在 内部,日 期对象是一个整数,它 是从 1970
年 1 月 1 日零时正开始计算到日期对象所指的日期的毫秒数。如 果所指日期比
1970 年早,则它是一个负数。所有日期时间,如果不指定时区,都采用“UTC”
(世界时)时区,它与“GMT”(格林威治时间)在数值上是一样的。
定义一个日期对象:
var d = new Date;
这个方法使 d 成为日期对象,并且已有初始值:当前时间。如果要自定初始值,
可以用:
var d = new Date(99, 10, 1); //99 年 10 月 1 日
var d = new Date('Oct 1, 1999'); //99 年 10 月 1 日
toString() 用法:<数值变量>.toString();返回:字符串形式的数值。如:若
a == 123;则 a.toString() == '123'。
String 字符串对象。声明一个字符串对象最简单、快捷、有效、常用的方法就
是直接赋值。
length 用法:<字符串对象>.length;返回该字符串的长度。
charAt() 用法:<字符串对象>.charAt(<位置>);返回该字符串位于第<位置>
位的单个字符。注 意:字 符串中的一个字符是第 0 位的,第 二个才是第 1 位的,
最后一个字符是第 length - 1 位的。
charCodeAt() 用法:<字符串对象>.charCodeAt(<位置>);返回该字符串位于第
<位置>位的单个字符的 ASCII 码。
fromCharCode() 用法:String.fromCharCode(a, b, c...);返回一个字符串,
该字符串每个字符的 ASCII 码由 a, b, c... 等来确定。
indexOf() 用法:<字符串对象>.indexOf(<另一个字符串对象>[, <起始位置
>]);该方法从<字符串对象>中查找<另一个字符串对象>(如果给出<起始位置>
就忽略之前的位置),如果找到了,就返回它的位置,没有找到就返回“-1”。
所有的“位置”都是从零开始的。
lastIndexOf() 用法:<字符串对象>.lastIndexOf(<另一个字符串对象>[, <起
始位置>]);跟 indexOf() 相似,不过是从后边开始找。
split() 用法:<字符串对象>.split(<分隔符字符>);返回一个数组,该数组是
从<字符串对象>中分离开来的,<分隔符字符>决定了分离的地方,它本身不会包
含在所返回的数组中。例 如:' 1&2&345&678'.split('&')返回数组:1 ,2,345,678。
关于数组,我们等一下就讨论。
substring() 用法:<字符串对象>.substring(<始>[, <终>]);返回原字符串的
子字符串,该字符串是原字符串从<始>位置到<终>位置的前一位置的一段。<终>
- <始> = 返回字符串的长度(length)。如果没有指定<终>或指定得超过字符
串长度,则子字符串从<始>位置一直取到原字符串尾。如果所指定的位置不能返
回字符串,则返回空字符串。
substr() 用法:<字符串对象>.substr(<始>[, <长>]);返回原字符串的子字符
串,该字符串是原字符串从<始>位置开始,长度为<长>的一段。如果没有指定<
长>或指定得超过字符串长度,则子字符串从<始>位置一直取到原字符串尾。如
果所指定的位置不能返回字符串,则返回空字符串。
toLowerCase() 用法:<字符串对象>.toLowerCase();返回把原字符串所有大写
字母都变成小写的字符串。
toUpperCase() 用法:<字符串对象>.toUpperCase();返回把原字符串所有小写
字母都变成大写的字符串。
Array 数组对象。数组对象是一个对象的集合,里边的对象可以是不同类型的。
数组的每一个成员对象都有一个“下标”,用来表示它在数组中的位置(既然是
“位置”,就也是从零开始的啦)。
数组的定义方法:
var <数组名> = new Array();
这样就定义了一个空数组。以后要添加数组元素,就用:
<数组名>[<下标>] = ...;
注意这里的方括号不是“可以省略”的意思,数 组的下标表示方法就是用方括号
括起来。
如果想在定义数组的时候直接初始化数据,请用:
var <数组名> = new Array(<元素1>, <元素 2>, <元素3>...);
例如,var myArray = new Array(1, 4.5, 'Hi'); 定义了一个数组 myArray,
里边的元素是:myArray[0] == 1; myArray[1] == 4.5; myArray[2] == 'Hi'。
但是,如果元素列表中只有一个元素,而这个元素又是一个正整数的话,这将定
义一个包含<正整数>个空元素的数组。
注意:JavaScript 只有一维数组!千万不要用“Array(3,4)”这种愚蠢的方法
来定义 4 x 5 的二维数组,或者用“myArray[2,3]”这种方法来返回“二维数
组”中的元素。任意“myArray[...,3]”这种形式的调用其实只返回了
“myArray[3]”。要使用多维数组,请用这种虚拟法:
var myArray = new Array(new Array(), new Array(), new Array(), ...);
其实这是一个一维数组,里边的每一个元素又是一个数组。调用这个“二维数
组”的元素时:myArray[2][3] = ...;
属性
length 用法:<数组对象>.length;返回:数组的长度,即数组里有多少个元素。
它等于数组里最后一个元素的下标加一。所以,想添加一个元素,只需要:
myArray[myArray.length] = ...。
方法
join() 用法:<数组对象>.join(<分隔符>);返回一个字符串,该字符串把数组
中的各个元素串起来,用<分隔符>置于元素与元素之间。这个方法不影响数组原
本的内容。
reverse() 用法:<数组对象>.reverse();使数组中的元素顺序反过来。如果对
数组[1, 2, 3]使用这个方法,它将使数组变成:[3, 2, 1]。
slice() 用法:<数组对象>.slice(<始>[, <终>]);返回一个数组,该数组是原
数组的子集,始于<始>,终于<终>。如果不给出<终>,则子集一直取到原数组的
结尾。
sort() 用法:<数组对象>.sort([<方法函数>]);使数组中的元素按照一定的顺
序排列。如果不指定<方法函数>,则按字母顺序排列。在这种情况下,80 是比 9
排得前的。如果指定<方法函数>,则按<方法函数>所指定的排序方法排序。<方
法函数>比较难讲述,这里只将一些有用的<方法函数>介绍给大家。
按升序排列数字:
function sortMethod(a, b) {
return a - b;
}
myArray.sort(sortMethod);
按降序排列数字:把上面的“a - b”该成“b - a”。
添加css样式
<html>
<head>
<style>
.over{
color:red;
background:#888;
}
</style>
<script src="../../scripts/jquery-1.3.1.js" type="text/javascript"></script>
<script type="text/javascript">
$(function(){
$("div").bind("mouseover mouseout", function(){
$(this).toggleClass("over");
});
})
</script>
</head>
<body>
<div style="width:100px;height:50px;">滑入.</div>
</body>
</html>
根据事件类型
<html>
<head>
<script src="../../scripts/jquery-1.3.1.js" type="text/javascript"></script>
<script type="text/javascript">
$(function(){
$("div").bind("click.plugin",function(){
$("body").append("<p>click事件</p>");
});
$("div").bind("mouseover.plugin", function(){
$("body").append("<p>mouseover事件</p>");
});
$("div").bind("dblclick", function(){
$("body").append("<p>dblclick事件</p>");
});
$("button").click(function() {
$("div").unbind(".plugin");
})
})
</script>
</head>
<body>
<div style="width:100px;height:50px;background:#888;color:white;">test.</div>
<button >根据命名空间,删除事件</button>
</body>
</html>
相同事件名称,不同命名空间执行方法
<html>
<head>
<script src="../../scripts/jquery-1.3.1.js" type="text/javascript"></script>
<script type="text/javascript">
$(function(){
$("div").bind("click",function(){
$("body").append("<p>click事件</p>");
});
$("div").bind("click.plugin", function(){
$("body").append("<p>click.plugin事件</p>");
});
$("button").click(function() {
$("div").trigger("click!"); // 注意click后面的感叹号
});
})
</script>
</head>
<body>
<div style="width:100px;height:50px;background:#888;color:white;">test.</div>
<button >根据命名空间,触发事件</button>
</body>
</html>
<html>
<head>
<style type="text/css">
*{margin:0;padding:0;}
body { font-size: 13px; line-height: 130%; padding: 60px; }
p {width:200px;background:#888;color:white;height:16px;}
</style>
<script src="../../scripts/jquery-1.3.1.js" type="text/javascript"></script>
<script type="text/javascript">
$(function(){
$('#btn').bind("myClick", function(){
$('#test').append("<p>我的自定义事件.</p>");
});
$('#btn').click(function(){
$(this).trigger("myClick");
}).trigger("myClick");
})
</script>
</head>
<body>
<button id="btn">点击我</button>
<div id="test"></div>
</body>
</html>
<html>
<title></title>
<style type="text/css">
*{margin:0;padding:0;}
body { font-size: 13px; line-height: 130%; padding: 60px; }
p {width:200px;background:#888;color:white;height:16px;}
</style>
<script src="../../scripts/jquery-1.3.1.js" type="text/javascript"></script>
<script type="text/javascript">
$(function(){
$('#old').bind("click", function(){
$("input").trigger("focus");
});
$('#new').bind("click", function(){
$("input").triggerHandler("focus");
});
$("input").focus(function(){
$("body").append("<p>focus.</p>");
})
})
</script>
</head>
<body>
<button id="old">trigger</button>
<button id="new">triggerHandler</button>
<input />
</body>
</html>
<html>
<head>
<style type="text/css">
*{margin:0;padding:0;}
body { font-size: 13px; line-height: 130%; padding: 60px; }
p {width:200px;background:#888;color:white;height:16px;}
</style>
<script src="../../scripts/jquery-1.3.1.js" type="text/javascript"></script>
<script type="text/javascript">
$(function(){
$('#btn').bind("click", function(){
$('#test').append("<p>我的绑定函数1</p>");
}).bind("click", function(){
$('#test').append("<p>我的绑定函数2</p>");
}).bind("click", function(){
$('#test').append("<p>我的绑定函数3</p>");
});
$('#delAll').click(function(){
$('#btn').unbind("click");
});
$('#delTwo').click(function(){
$('#btn').unbind("click",myFun2);
});
})
</script>
</head>
<body>
<button id="btn">点击我</button>
<div id="test"></div>
<button id="delAll">删除所有事件</button>
<button id="delTwo">删除第二个事件</button>
</body>
</html>
<html>
<head>
<style type="text/css">
*{margin:0;padding:0;}
body { font-size: 13px; line-height: 130%; padding: 60px; }
p {width:200px;background:#888;color:white;height:16px;}
</style>
<script src="../../scripts/jquery-1.3.1.js" type="text/javascript"></script>
<script type="text/javascript">
$(function(){
$('#btn').one("click", function(){
$('#test').append("<p>我的绑定函数1</p>");
}).one("click", function(){
$('#test').append("<p>我的绑定函数2</p>");
}).one("click", function(){
$('#test').append("<p>我的绑定函数3</p>");
});
})
</script>
</head>
<body>
<button id="btn">点击我</button>
<div id="test"></div>
</body>
</html>
<html>
<head>
<script src="../../scripts/jquery-1.3.1.js" type="text/javascript"></script>
<script>
$(function(){
$("a").click(function(event) {
alert(event.type);//获取事件类型
alert(event.target.href);//获取触发事件的<a>元素的href属性值
alert("Current mouse position: " + event.pageX + ", " + event.pageY );//获取鼠标当前相对于页面的坐标
alert(e.which) // 1 = 鼠标左键 left; 2 = 鼠标中键; 3 = 鼠标右键
return false;//阻止链接跳转
});
})
</script>
</head>
<body>
<a href='http://google.com'>click me .</a>
</body>
</html>
<html>
<head>
<script src="../../scripts/jquery-1.3.1.js" type="text/javascript"></script>
<script type="text/javascript">
$(function(){
$("#sub").bind("click",function(event){
var username = $("#username").val(); //获取元素的值
if(username==""){ //判断值是否为空
$("#msg").html("<p>文本框的值不能为空.</p>"); //提示信息
event.preventDefault(); //阻止默认行为 ( 表单提交 )或者return false;
}
})
})
</script>
</head>
<body>
<form action="test.html">
用户名:<input type="text" id="username" />
<br/>
<input type="submit" value="提交" id="sub"/>
</form>
<div id="msg"></div>
</body>
</html>
<html>
<head>
<style type="text/css">
*{margin:0;padding:0;}
body { font-size: 13px; line-height: 130%; padding: 60px; }
#content { width: 220px; border: 1px solid #0050D0;background: #96E555 }
span { width: 200px; margin: 10px; background: #666666; cursor: pointer;color:white;display:block;}
p {width:200px;background:#888;color:white;height:16px;}
</style>
<script src="../../scripts/jquery-1.3.1.js" type="text/javascript"></script>
<script type="text/javascript">
$(function(){
// 为span元素绑定click事件
$('span').bind("click",function(event){
var txt = $('#msg').html() + "<p>内层span元素被点击.<p/>";
$('#msg').html(txt);
event.stopPropagation(); // 阻止事件冒泡或者return false;
});
// 为div元素绑定click事件
$('#content').bind("click",function(event){
var txt = $('#msg').html() + "<p>外层div元素被点击.<p/>";
$('#msg').html(txt);
event.stopPropagation(); // 阻止事件冒泡或者return false;
});
// 为body元素绑定click事件
$("body").bind("click",function(){
var txt = $('#msg').html() + "<p>body元素被点击.<p/>";
$('#msg').html(txt);
});
})
</script>
</head>
<body>
<div id="content">
外层div元素
<span>内层span元素</span>
外层div元素
</div>
<div id="msg"></div>
</body>
</html>
<html>
<head>
<script src="../../scripts/jquery-1.3.1.js" type="text/javascript"></script>
<script type="text/javascript">
$(function(){
$("#panel h5.head").hover(function(){//鼠标移动事件
$(this).next().show();
},function(){
$(this).next().hide();
})
})
</script>
</head>
<body>
<div id="panel">
<h5 class="head">什么是jQuery?</h5>
<div class="content">
jQuery是继Prototype之后又一个优秀的JavaScript库,它是一个由 John Resig 创建于2006年1月的开源项目。jQuery凭借简洁的语法和
跨平台的兼容性,极大地简化了JavaScript开发人员遍历HTML文档、操作DOM、处理事件、执行动画和开发Ajax。它独特而又优雅的代码风格改变了
JavaScript程序员的设计思路和编写程序的方式。
</div>
</div>
</body>
</html>
<html>
<head>
<script src="../../scripts/jquery-1.3.1.js" type="text/javascript"></script>
<style type="text/css">
.highlight{ background:#FF3300; }
</style>
<script type="text/javascript">
$(function(){
$("#panel h5.head").toggle(function(){//鼠标点击事件
$(this).addClass("highlight");
$(this).next().show();
},function(){
$(this).removeClass("highlight");
$(this).next().hide();
});
})
</script>
</head>
<body>
<div id="panel">
<h5 class="head">什么是jQuery?</h5>
<div class="content">
jQuery是继Prototype之后又一个优秀的JavaScript库,它是一个由 John Resig 创建于2006年1月的开源项目。jQuery凭借简洁的语法和
跨平台的兼容性,极大地简化了JavaScript开发人员遍历HTML文档、操作DOM、处理事件、执行动画和开发Ajax。它独特而又优雅的代码风格改变了
JavaScript程序员的设计思路和编写程序的方式。
</div>
</div>
</body>
</html>
<head>
<script src="../../scripts/jquery-1.3.1.js" type="text/javascript"></script>
<script type="text/javascript">
$(function(){
$("#panel h5.head").bind("click",function(){
var $content = $(this).next();
if($content.is(":visible")){
$content.hide();
}else{
$content.show();
}
})
})
</script>
</head>
<body>
<div id="panel">
<h5 class="head">什么是jQuery?</h5>
<div class="content">
jQuery是继Prototype之后又一个优秀的JavaScript库,它是一个由 John Resig 创建于2006年1月的开源项目。jQuery凭借简洁的语法和
跨平台的兼容性,极大地简化了JavaScript开发人员遍历HTML文档、操作DOM、处理事件、执行动画和开发Ajax。它独特而又优雅的代码风格改变了
JavaScript程序员的设计思路和编写程序的方式。
</div>
</div>
</body>
</html>
<html >
<head>
<script src="../../scripts/jquery-1.3.1.js" type="text/javascript"></script>
<script type="text/javascript">
$(function(){
$("#panel h5.head").bind("mouseover",function(){
$(this).next().show();
});
$("#panel h5.head").bind("mouseout",function(){
$(this).next().hide();
})
})
</script>
</head>
<body>
<div id="panel">
<h5 class="head">什么是jQuery?</h5>
<div class="content">
jQuery是继Prototype之后又一个优秀的JavaScript库,它是一个由 John Resig 创建于2006年1月的开源项目。jQuery凭借简洁的语法和
跨平台的兼容性,极大地简化了JavaScript开发人员遍历HTML文档、操作DOM、处理事件、执行动画和开发Ajax。它独特而又优雅的代码风格改变了
JavaScript程序员的设计思路和编写程序的方式。
</div>
</div>
</body>
</html>
<html>
<head>
<script src="../../scripts/jquery-1.3.1.js" type="text/javascript"></script>
<script type="text/javascript">
$(function(){
$("#panel h5.head").mouseover(function(){
$(this).next().show();
});
$("#panel h5.head").mouseout(function(){
$(this).next().hide();
})
})
</script>
</head>
<body>
<div id="panel">
<h5 class="head">什么是jQuery?</h5>
<div class="content">
jQuery是继Prototype之后又一个优秀的JavaScript库,它是一个由 John Resig 创建于2006年1月的开源项目。jQuery凭借简洁的语法和
跨平台的兼容性,极大地简化了JavaScript开发人员遍历HTML文档、操作DOM、处理事件、执行动画和开发Ajax。它独特而又优雅的代码风格改变了
JavaScript程序员的设计思路和编写程序的方式。
</div>
</div>
</body>
</html>
<head>
<script src="../../scripts/jquery-1.3.1.js" type="text/javascript"></script>
<script type="text/javascript">
var startTime = new Date().getTime();
$(document).ready(function(){
test1();
})
function test1(){
var endTime2 = new Date().getTime();
var a = endTime2 - startTime;
$("<div>jQuery的ready() : "+a+" ms</div>").appendTo("body");
}
function test2(){
var endTime1 = new Date().getTime();
var b = endTime1 - startTime;
$("<p>JavaScript的window.onload : "+b+" ms</p>").appendTo("body");
}
</script>
</head>
<body onload="test2();">
<img src="demo.jpg" style="width:200px;height:200px;"/>
</body>
</html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<script src="../scripts/jquery-1.3.1.js" type="text/javascript"></script>
<script type="text/javascript">
$(document).ready(function(){
//重置表单元素
$(":reset").click(function(){
setTimeout(function() {
countChecked();
$("select").change();
},0);
});
//对表单内 可用input 赋值操作.
$('#btn1').click(function(){
$("#form1 input:enabled").val("这里变化了!");
return false;
})
//对表单内 不可用input 赋值操作.
$('#btn2').click(function(){
$("#form1 input:disabled").val("这里变化了!");
return false;
})
//使用:checked选择器,来操作多选框.
$(":checkbox").click(countChecked);
function countChecked() {
var n = $("input:checked").length;
$("div").eq(0).html("<strong>有"+n+" 个被选中!</strong>");
}
countChecked();//进入页面就调用.
//使用:selected选择器,来操作下拉列表.
$("select").change(function () {
var str = "";
$("select :selected").each(function () {
str += $(this).text() + ",";
});
$("div").eq(1).html("<strong>你选中的是:"+str+"</strong>");
}).trigger('change');
// trigger('change') 在这里的意思是:
// select加载后,马上执行onchange.
// 也可以用.change()代替.
});
</script>
</head>
<body>
<h3> 表单对象属性过滤选择器.</h3>
<form id="form1" action="#">
<button type="reset">重置所有表单元素</button>
<br /><br />
<button id="btn1">对表单内 可用input 赋值操作.</button>
<button id="btn2">对表单内 不可用input 赋值操作.</button><br /><br />
可用元素:<input name="add" value="可用文本框"/> <br/>
不可用元素:<input name="email" disabled="disabled" value="不可用文本框"/><br/>
可用元素: <input name="che" value="可用文本框" /><br/>
不可用元素:<input name="name" disabled="disabled" value="不可用文本框"/><br/>
<br/>
多选框:<br/>
<input type="checkbox" name="newsletter" checked="checked" value="test1" />test1
<input type="checkbox" name="newsletter" value="test2" />test2
<input type="checkbox" name="newsletter" value="test3" />test3
<input type="checkbox" name="newsletter" checked="checked" value="test4" />test4
<input type="checkbox" name="newsletter" value="test5" />test5
<div></div>
<br/><br/>
下拉列表1:<br/>
<select name="test" multiple="multiple" style="height:100px">
<option>浙江</option>
<option selected="selected">湖南</option>
<option>北京</option>
<option selected="selected">天津</option>
<option>广州</option>
<option>湖北</option>
</select>
<br/><br/>
下拉列表2:<br/>
<select name="test2" >
<option>浙江</option>
<option>湖南</option>
<option selected="selected">北京</option>
<option>天津</option>
<option>广州</option>
<option>湖北</option>
</select>
<br/><br/>
<div></div>
</form>
</body>
</html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<script src="../scripts/jquery-1.3.1.js" type="text/javascript"></script>
<script type="text/javascript">
$(document).ready(function(){
var $alltext = $("#form1 :text");
var $allpassword= $("#form1 :password");
var $allradio= $("#form1 :radio");
var $allcheckbox= $("#form1 :checkbox");
var $allsubmit= $("#form1 :submit");
var $allimage= $("#form1 :image");
var $allreset= $("#form1 :reset");
var $allbutton= $("#form1 :button"); // <input type=button /> 和 <button ></button>都可以匹配
var $allfile= $("#form1 :file");
var $allhidden= $("#form1 :hidden"); // <input type="hidden" />和<div style="display:none">test</div>都可以匹配.
var $allselect = $("#form1 select");
var $alltextarea = $("#form1 textarea");
var $AllInputs = $("#form1 :input");
var $inputs = $("#form1 input");
$("div").append(" 有" + $alltext.length + " 个( :text 元素)<br/>")
.append(" 有" + $allpassword.length + " 个( :password 元素)<br/>")
.append(" 有" + $allradio.length + " 个( :radio 元素)<br/>")
.append(" 有" + $allcheckbox.length + " 个( :checkbox 元素)<br/>")
.append(" 有" + $allsubmit.length + " 个( :submit 元素)<br/>")
.append(" 有" + $allimage.length + " 个( :image 元素)<br/>")
.append(" 有" + $allreset.length + " 个( :reset 元素)<br/>")
.append(" 有" + $allbutton.length + " 个( :button 元素)<br/>")
.append(" 有" + $allfile.length + " 个( :file 元素)<br/>")
.append(" 有" + $allhidden.length + " 个( :hidden 元素)<br/>")
.append(" 有" + $allselect.length + " 个( select 元素)<br/>")
.append(" 有" + $alltextarea.length + " 个( textarea 元素)<br/>")
.append(" 表单有 " + $inputs.length + " 个(input)元素。<br/>")
.append(" 总共有 " + $AllInputs.length + " 个(:input)元素。<br/>")
.css("color", "red")
$("form").submit(function () { return false; }); // return false;不能提交.
});
</script>
</head>
<body>
<form id="form1" action="#">
<input type="button" value="Button"/><br/>
<input type="checkbox" name="c"/>1<input type="checkbox" name="c"/>2<input type="checkbox" name="c"/>3<br/>
<input type="file" /><br/>
<input type="hidden" /><div style="display:none">test</div><br/>
<input type="image" /><br/>
<input type="password" /><br/>
<input type="radio" name="a"/>1<input type="radio" name="a"/>2<br/>
<input type="reset" /><br/>
<input type="submit" value="提交"/><br/>
<input type="text" /><br/>
<select><option>Option</option></select><br/>
<textarea rows="5" cols="20"></textarea><br/>
<button>Button</button><br/>
</form>
<div></div>
</body>
</html>
//选取每个父元素下的第2个子元素
$('#btn1').click(function(){
$('div.one :nth-child(2)').css("background","#bbffaa");
})
//选取每个父元素下的第一个子元素
$('#btn2').click(function(){
$('div.one :first-child').css("background","#bbffaa");
})
//选取每个父元素下的最后一个子元素
$('#btn3').click(function(){
$('div.one :last-child').css("background","#bbffaa");
})
//如果父元素下的仅仅只有一个子元素,那么选中这个子元素
$('#btn4').click(function(){
$('div.one :only-child').css("background","#bbffaa");
})
//选取含有 属性title 的div元素.
$('#btn1').click(function(){
$('div[title]').css("background","#bbffaa");
})
//选取 属性title值等于 test 的div元素.
$('#btn2').click(function(){
$('div[title=test]').css("background","#bbffaa");
})
//选取 属性title值不等于 test 的div元素.
$('#btn3').click(function(){
$('div[title!=test]').css("background","#bbffaa");
})
//选取 属性title值 以 te 开始 的div元素.
$('#btn4').click(function(){
$('div[title^=te]').css("background","#bbffaa");
})
//选取 属性title值 以 est 结束 的div元素.
$('#btn5').click(function(){
$("div[title$=est]").css("background","#bbffaa");
})
//选取 属性title值 含有 es 的div元素.
$('#btn6').click(function(){
$("div[title*=es]").css("background","#bbffaa");
})
//组合属性选择器,首先选取有属性id的div元素,然后在结果中 选取属性title值 含有 es 的元素.
$('#btn7').click(function(){
$("div[id][title*=es]").css("background","#bbffaa");
})
$('#reset').click(function(){
window.location.reload();
})
//给id为mover的元素添加动画.
function animateIt() {
$("#mover").slideToggle("slow", animateIt);
}
animateIt();
//选取所有不可见的元素.包括<input type="hidden"/>.
$('#btn_hidden').click(function(){
alert( "不可见的元素有:"+$('body :hidden').length +"个!\n"+
"其中不可见的div元素有:"+$('div:hidden').length+"个!\n"+
"其中文本隐藏域有:"+$('input:hidden').length+"个!");
$('div:hidden').show(3000).css("background","#bbffaa");
})
//选取所有可见的元素.
$('#btn_visible').click(function(){
$('div:visible').css("background","#FF6500");
})
//选取含有文本"di"的div元素.
$('#btn1').click(function(){
$('div:contains(di)').css("background","#bbffaa");
})
//选取不包含子元素(或者文本元素)的div空元素.
$('#btn2').click(function(){
$('div:empty').css("background","#bbffaa");
})
//选取含有class为mini元素 的div元素.
$('#btn3').click(function(){
$('div:has(.mini)').css("background","#bbffaa");
})
//选取含有子元素(或者文本元素)的div元素.
$('#btn4').click(function(){
$('div:parent').css("background","#bbffaa");
})
//选择第一个div元素.
$('#btn1').click(function(){
$('div:first').css("background","#bfa");
})
//选择最后一个div元素.
$('#btn2').click(function(){
$('div:last').css("background","#bfa");
})
//选择class不为one的 所有div元素.
$('#btn3').click(function(){
$('div:not(.one)').css("background","#bfa");
})
//选择 索引值为偶数 的div元素。
$('#btn4').click(function(){
$('div:even').css("background","#bfa");
})
//选择 索引值为奇数 的div元素。
$('#btn5').click(function(){
$('div:odd').css("background","#bfa");
})
//选择 索引等于 3 的元素
$('#btn6').click(function(){
$('div:eq(3)').css("background","#bfa");
})
//选择 索引大于 3 的元素
$('#btn7').click(function(){
$('div:gt(3)').css("background","#bfa");
})
//选择 索引小于 3 的元素
$('#btn8').click(function(){
$('div:lt(3)').css("background","#bfa");
})
//选择 所有的标题元素.比如h1, h2, h3等等...
$('#btn9').click(function(){
$(':header').css("background","#bfa");
})
//选择 当前正在执行动画的所有元素.
$('#btn10').click(function(){
$(':animated').css("background","#bfa");
});
//选择 body内的所有div元素.
$('#btn1').click(function(){
$('body div').css("background","#bbffaa");
})
//在body内的选择 元素名是div 的子元素.
$('#btn2').click(function(){
$('body > div').css("background","#bbffaa");
})
//选择 所有class为one 的下一个div元素.
$('#btn3').click(function(){
$('.one + div').css("background","#bbffaa");
})
//选择 id为two的元素后面的所有div兄弟元素.
$('#btn4').click(function(){
$('#two ~ div').css("background","#bbffaa");
})
//选择 id为 one 的元素
$('#btn1').click(function(){
$('#one').css("background","#bfa");
});
//选择 class 为 mini 的所有元素
$('#btn2').click(function(){
$('.mini').css("background","#bfa");
});
//选择 元素名是 div 的所有元素
$('#btn3').click(function(){
$('div').css("background","#bfa");
});
//选择 所有的元素
$('#btn4').click(function(){
$('*').css("background","#bfa");
});
//选择 所有的span元素和id为two的div元素
$('#btn5').click(function(){
$('span,#two').css("background","#bfa");
});
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<script src="../../scripts/jquery-1.3.1.js" type="text/javascript"></script>
<script type="text/javascript">
$(function(){
var x = 10;
var y = 20;
$("a.tooltip").mouseover(function(e){
this.myTitle = this.title;
this.title = "";
var tooltip = "<div id='tooltip'>"+ this.myTitle +"<\/div>"; //创建 div 元素
$("body").append(tooltip); //把它追加到文档中
$("#tooltip")
.css({
"top": (e.pageY+y) + "px",
"left": (e.pageX+x) + "px"
}).show("fast"); //设置x坐标和y坐标,并且显示
}).mouseout(function(){
this.title = this.myTitle;
$("#tooltip").remove(); //移除
}).mousemove(function(e){
$("#tooltip")
.css({
"top": (e.pageY+y) + "px",
"left": (e.pageX+x) + "px"
});
});
})
</script>
<style type="text/css">
body{
margin:0;
padding:40px;
background:#fff;
font:80% Arial, Helvetica, sans-serif;
color:#555;
line-height:180%;
}
p{
clear:both;
margin:0;
padding:.5em 0;
}
/* tooltip */
#tooltip{
position:absolute;
border:1px solid #333;
background:#f7f5d1;
padding:1px;
color:#333;
display:none;
}
</style>
</head>
<body>
<p><a href="#" class="tooltip" title="这是我的超链接提示1.">提示1.</a></p>
<p><a href="#" class="tooltip" title="这是我的超链接提示2.">提示2.</a></p>
<p><a href="#" title="这是自带提示1.">自带提示1.</a></p>
<p><a href="#" title="这是自带提示2.">自带提示2.</a> </p>
</body>
</html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<script src="../../scripts/jquery-1.3.1.js" type="text/javascript"></script>
<script type="text/javascript">
$(function(){
var $body = $("body").children();
var $p = $("p").children();
var $ul = $("ul").children();
alert( $body.length ); // <body>元素下有2个子元素
alert( $p.length ); // <p>元素下有0个子元素
alert( $ul.length ); // <p>元素下有3个子元素
for(var i=0;i< $ul.length;i++){
alert( $ul[i].innerHTML );
}
});
</script>
</head>
<body>
<p title="选择你最喜欢的水果." >你最喜欢的水果是?</p>
<ul>
<li title='苹果'>苹果</li>
<li title='橘子'>橘子</li>
<li title='菠萝'>菠萝</li>
</ul>
</body>
</html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<script src="../../scripts/jquery-1.3.1.js" type="text/javascript"></script>
<script type="text/javascript">
$(function(){
var $p1 = $("p").next();
alert( $p1.html() ); // 紧邻<p>元素后的同辈元素
var $ul = $("ul").prev();
alert( $ul.html() ); // 紧邻<ul>元素前的同辈元素
var $p2 = $("p").siblings();
alert( $p2.html() ); // 紧邻<p>元素的唯一同辈元素
});
</script>
</head>
<body>
<p title="选择你最喜欢的水果." >你最喜欢的水果是?</p>
<ul>
<li title='苹果'>苹果</li>
<li title='橘子'>橘子</li>
<li title='菠萝'>菠萝</li>
</ul>
</body>
</html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<script src="../../scripts/jquery-1.3.1.js" type="text/javascript"></script>
<script type="text/javascript">
$(function(){
$(document).bind("click", function (e) {
$(e.target).closest("li").css("color","red");
})
});
</script>
</head>
<body>
<p title="选择你最喜欢的水果." >你最喜欢的水果是?</p>
<ul>
<li title='苹果'>苹果</li>
<li title='橘子'>橘子</li>
<li title='菠萝'>菠萝</li>
</ul>
</body>
</html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<style type="text/css">
.test{
font-weight:bold;
color : red;
}
.add{
font-style:italic;
}
</style>
<!-- 引入jQuery -->
<script src="../../scripts/jquery-1.3.1.js" type="text/javascript"></script>
<script type="text/javascript">
$(function(){
//获取<p>元素的HTML代码
$("input:eq(0)").click(function(){
alert( $("p").html() );
});
//获取<p>元素的文本
$("input:eq(1)").click(function(){
alert( $("p").text() );
});
//设置<p>元素的HTML代码
$("input:eq(2)").click(function(){
$("p").html("<strong>你最喜欢的水果是?</strong>");
});
//设置<p>元素的文本
$("input:eq(3)").click(function(){
$("p").text("你最喜欢的水果是?");
});
//设置<p>元素的文本
$("input:eq(4)").click(function(){
$("p").text("<strong>你最喜欢的水果是?</strong>");
});
//获取按钮的value值
$("input:eq(5)").click(function(){
alert( $(this).val() );
});
//设置按钮的value值
$("input:eq(6)").click(function(){
$(this).val("我被点击了!");
});
});
</script>
</head>
<body>
<input type="button" value="获取<p>元素的HTML代码"/>
<input type="button" value="获取<p>元素的文本"/>
<input type="button" value="设置<p>元素的HTML代码"/>
<input type="button" value="设置<p>元素的文本"/>
<input type="button" value="设置<p>元素的文本(带HTML)"/>
<input type="button" value="获取按钮的value值"/>
<input type="button" value="设置按钮的value值"/>
<p title="选择你最喜欢的水果." ><strong>你最喜欢的水果是?</strong></p>
<ul>
<li title='苹果'>苹果</li>
<li title='橘子'>橘子</li>
<li title='菠萝'>菠萝</li>
</ul>
</body>
</html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<script src="../../scripts/jquery-1.3.1.js" type="text/javascript"></script>
<script type="text/javascript">
$(function(){
$("#address").focus(function(){ // 地址框获得鼠标焦点
var txt_value = $(this).val(); // 得到当前文本框的值
if(txt_value==this.defaultValue){
$(this).val(""); // 如果符合条件,则清空文本框内容
}
});
$("#address").blur(function(){ // 地址框失去鼠标焦点
var txt_value = $(this).val(); // 得到当前文本框的值
if(txt_value==""){
$(this).val(this.defaultValue);// 如果符合条件,则设置内容
}
})
$("#password").focus(function(){
var txt_value = $(this).val();
if(txt_value==this.defaultValue){
$(this).val("");
}
});
$("#password").blur(function(){
var txt_value = $(this).val();
if(txt_value==""){
$(this).val(this.defaultValue);
}
})
});
</script>
</head>
<body>
<input type="text" id="address" value="请输入邮箱地址"/> <br/><br/>
<input type="text" id="password" value="请输入邮箱密码"/> <br/><br/>
<input type="button" value="登陆"/>
</body>
</html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<style type="text/css">
.test{
font-weight:bold;
color : red;
}
.add{
font-style:italic;
}
</style>
<script src="../../scripts/jquery-1.3.1.js" type="text/javascript"></script>
<script type="text/javascript">
$(function(){
//设置单选下拉框选中
$("input:eq(0)").click(function(){
$("#single option").removeAttr("selected"); //移除属性selected
$("#single option:eq(1)").attr("selected",true); //设置属性selected
});
//设置多选下拉框选中
$("input:eq(1)").click(function(){
$("#multiple option").removeAttr("selected"); //移除属性selected
$("#multiple option:eq(2)").attr("selected",true);//设置属性selected
$("#multiple option:eq(3)").attr("selected",true);//设置属性selected
});
//设置单选框和多选框选中
$("input:eq(2)").click(function(){
$(":checkbox").removeAttr("checked"); //移除属性checked
$(":radio").removeAttr("checked"); //移除属性checked
$("[value=check2]:checkbox").attr("checked",true);//设置属性checked
$("[value=check3]:checkbox").attr("checked",true);//设置属性checked
$("[value=radio2]:radio").attr("checked",true);//设置属性checked
});
});
</script>
</head>
<body>
<input type="button" value="设置单选下拉框选中"/>
<input type="button" value="设置多选下拉框选中"/>
<input type="button" value="设置单选框和多选框选中"/>
<br/><br/>
<select id="single">
<option>选择1号</option>
<option>选择2号</option>
<option>选择3号</option>
</select>
<select id="multiple" multiple="multiple" style="height:120px;">
<option selected="selected">选择1号</option>
<option>选择2号</option>
<option>选择3号</option>
<option>选择4号</option>
<option selected="selected">选择5号</option>
</select>
<br/><br/>
<input type="checkbox" value="check1"/> 多选1
<input type="checkbox" value="check2"/> 多选2
<input type="checkbox" value="check3"/> 多选3
<input type="checkbox" value="check4"/> 多选4
<br/>
<input type="radio" value="radio1" name="a"/> 单选1
<input type="radio" value="radio2" name="a"/> 单选2
<input type="radio" value="radio3" name="a"/> 单选3
</body>
</html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<style type="text/css">
.high{
font-weight:bold; /* 粗体字 */
color : red; /* 字体颜色设置红色*/
}
.another{
font-style:italic;
color:blue;
}
</style>
<!-- 引入jQuery -->
<script src="../../scripts/jquery-1.3.1.js" type="text/javascript"></script>
<script type="text/javascript">
$(function(){
//获取样式
$("input:eq(0)").click(function(){
alert( $("p").attr("class") );
});
//设置样式
$("input:eq(1)").click(function(){
$("p").attr("class","high");
});
//追加样式
$("input:eq(2)").click(function(){
$("p").addClass("another");
});
//删除全部样式
$("input:eq(3)").click(function(){
$("p").removeClass();
});
//删除指定样式
$("input:eq(4)").click(function(){
$("p").removeClass("high");
});
//重复切换样式
$("input:eq(5)").click(function(){
$("p").toggleClass("another");
});
//判断元素是否含有某样式
$("input:eq(6)").click(function(){
alert( $("p").hasClass("another") )
alert( $("p").is(".another") )
});
});
</script>
</head>
<body>
<input type="button" value="输出class类"/>
<input type="button" value="设置class类"/>
<input type="button" value="追加class类"/>
<input type="button" value="删除全部class类"/>
<input type="button" value="删除指定class类"/>
<input type="button" value="重复切换class类"/>
<input type="button" value="判断元素是否含有某个class类"/>
<p class="myClass" title="选择你最喜欢的水果." >你最喜欢的水果是?</p>
<ul>
<li title='苹果'>苹果</li>
<li title='橘子'>橘子</li>
<li title='菠萝'>菠萝</li>
</ul>
</body>
</html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<style type="text/css">
.test{
font-weight:bold;
color : red;
}
.add{
font-style:italic;
}
</style>
<script src="../../scripts/jquery-1.3.1.js" type="text/javascript"></script>
<script type="text/javascript">
$(function(){
//获取<p>元素的color
$("input:eq(0)").click(function(){
alert( $("p").css("color") );
});
//设置<p>元素的color
$("input:eq(1)").click(function(){
$("p").css("color","red")
});
//设置<p>元素的fontSize和backgroundColor
$("input:eq(2)").click(function(){
$("p").css({"fontSize":"30px" ,"backgroundColor":"#888888"})
});
//获取<p>元素的高度
$("input:eq(3)").click(function(){
alert( $("p").height() );
});
//获取<p>元素的宽度
$("input:eq(4)").click(function(){
alert( $("p").width() );
});
//获取<p>元素的高度
$("input:eq(5)").click(function(){
$("p").height("100px");
});
//获取<p>元素的宽度
$("input:eq(6)").click(function(){
$("p").width("400px");
});
//获取<p>元素的的左边距和上边距
$("input:eq(7)").click(function(){
var offset = $("p").offset();
var left = offset.left;
var top = offset.top;
alert("left:"+left+";top:"+top);
});
});
</script>
</head>
<body>
<input type="button" value="获取<p>元素的color"/>
<input type="button" value="设置<p>元素的color"/>
<input type="button" value="设置<p>元素的fontSize和backgroundColor"/>
<input type="button" value="获取<p>元素的高度"/>
<input type="button" value="获取<p>元素的宽度"/>
<input type="button" value="设置<p>元素的高度"/>
<input type="button" value="设置<p>元素的宽度"/>
<input type="button" value="获取<p>元素的的左边距和上边距"/>
<p title="选择你最喜欢的水果."><strong>你最喜欢的水果是?</strong></p>
<ul>
<li title='苹果'>苹果</li>
<li title='橘子'>橘子</li>
<li title='菠萝'>菠萝</li>
</ul>
</body>
</html>
替换节点
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<script src="../../scripts/jquery-1.3.1.js" type="text/javascript"></script>
<script type="text/javascript">
$(function(){
$("p").replaceWith("<strong>你最不喜欢的水果是?</strong>");
// 同样的实现: $("<strong>你最不喜欢的水果是?</strong>").replaceAll("p");
});
</script>
</head>
<body>
<p title="选择你最喜欢的水果." >你最喜欢的水果是?</p>
<ul>
<li title='苹果'>苹果</li>
<li title='橘子'>橘子</li>
<li title='菠萝'>菠萝</li>
</ul>
</body>
</html>
属性操作
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<script src="../../scripts/jquery-1.3.1.js" type="text/javascript"></script>
<script type="text/javascript">
$(function(){
//设置<p>元素的属性'title'
$("input:eq(0)").click(function(){
$("p").attr("title","选择你最喜欢的水果.");
});
//获取<p>元素的属性'title'
$("input:eq(1)").click(function(){
alert( $("p").attr("title") );
});
//删除<p>元素的属性'title'
$("input:eq(2)").click(function(){
$("p").removeAttr("title");
});
});
</script>
</head>
<body>
<input type="button" value="设置<p>元素的属性'title'"/>
<input type="button" value="获取<p>元素的属性'title'"/>
<input type="button" value="删除<p>元素的属性'title'"/>
<p title="选择你最喜欢的水果." >你最喜欢的水果是?</p>
<ul>
<li title='苹果'>苹果</li>
<li title='橘子'>橘子</li>
<li title='菠萝'>菠萝</li>
</ul>
</body>
</html>
删除节点
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<script src="../../scripts/jquery-1.3.1.js" type="text/javascript"></script>
<script type="text/javascript">
$(function(){
var $li = $("ul li:eq(1)").remove(); // 获取第二个<li>元素节点后,将它从网页中删除。
$li.appendTo("ul"); // 把刚才删除的又重新添加到<ul>元素里
//所以,删除只是从网页中删除,在jQuery对象中,这个元素还是存在的,我们可以重新获取它
$("ul li").remove("li[title!=菠萝]"); //把<li>元素中属性title不等于"菠萝"的<li>元素删除
$("ul li:eq(1)").empty(); // 找到第二个<li>元素节点后,清空此元素里的内容
});
</script>
</head>
<body>
<p title="选择你最喜欢的水果." >你最喜欢的水果是?</p>
<ul>
<li title='苹果'>苹果</li>
<li title='橘子'>橘子</li>
<li title='菠萝'>菠萝</li>
</ul>
</body>
</html>
复制节点
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<script src="../../scripts/jquery-1.3.1.js" type="text/javascript"></script>
<script type="text/javascript">
$(function(){
$("ul li").click(function(){
$(this).clone(true).appendTo("ul"); //
//注意参数true可以复制自己,并且他的副本也有同样功能。
})
});
</script>
</head>
<body>
<p title="选择你最喜欢的水果." >你最喜欢的水果是?</p>
<ul>
<li title='苹果'>苹果</li>
<li title='橘子'>橘子</li>
<li title='菠萝'>菠萝</li>
</ul>
</body>
</html>
插入节点
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<script src="../../scripts/jquery-1.3.1.js" type="text/javascript"></script>
<script type="text/javascript">
$(function(){
var $li_1 = $("<li title='香蕉'>香蕉</li>"); // 创建第一个<li>元素
var $li_2 = $("<li title='雪梨'>雪梨</li>"); // 创建第二个<li>元素
var $li_3 = $("<li title='其它'>其它</li>"); // 创建第三个<li>元素
var $parent = $("ul"); // 获取<ul>节点,即<li>的父节点
var $two_li = $("ul li:eq(1)"); // 获取<ul>节点中第二个<li>元素节点
$parent.append($li_1); // append方法将创建的第一个<li>元素添加到父元素的最后面
$parent.prepend($li_2); // prepend方法将创建的第二个<li>元素添加到父元素里的最前面
$li_3.insertAfter($two_li); // insertAfter方法将创建的第三个<li>元素元素插入到获取的<li>之后
});
</script>
</head>
<body>
<p title="选择你最喜欢的水果." >你最喜欢的水果是?</p>
<ul>
<li title='苹果'>苹果</li>
<li title='橘子'>橘子</li>
<li title='菠萝'>菠萝</li>
</ul>
</body>
</html>
移动节点
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<script src="../../scripts/jquery-1.3.1.js" type="text/javascript"></script>
<script type="text/javascript">
$(function(){
var $one_li = $("ul li:eq(1)"); // 获取<ul>节点中第二个<li>元素节点
var $two_li = $("ul li:eq(2)"); // 获取<ul>节点中第三个<li>元素节点
$two_li.insertBefore($one_li); //移动节点
});
</script>
</head>
<body>
<p title="选择你最喜欢的水果." >你最喜欢的水果是?</p>
<ul>
<li title='苹果'>苹果</li>
<li title='橘子'>橘子</li>
<li title='菠萝'>菠萝</li>
</ul>
</body>
</html>
得到元素的值
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<script src="../../scripts/jquery-1.3.1.js" type="text/javascript"></script>
<script type="text/javascript">
$(function(){
var $para = $("p"); // 获取<p>节点
var $li = $("ul li:eq(1)"); // 获取第二个<li>元素节点
var p_txt = $para.attr("title"); // 输出<p>元素节点属性title
var ul_txt = $li.attr("title"); // 获取<ul>里的第二个<li>元素节点的属性title
var li_txt = $li.text(); // 输出第二个<li>元素节点的text
alert(p_txt);
alert(ul_txt);
alert(li_txt);
});
</script>
</head>
<body>
<p title="选择你最喜欢的水果." >你最喜欢的水果是?</p>
<ul>
<li title='苹果'>苹果</li>
<li title='橘子'>橘子</li>
<li title='菠萝'>菠萝</li>
</ul>
</body>
</html>
创建节点
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>3-2-3</title>
<!-- 引入jQuery -->
<script src="../../scripts/jquery-1.3.1.js" type="text/javascript"></script>
<script type="text/javascript">
$(function(){
var $li_1 = $("<li title='香蕉'>香蕉</li>"); //创建一个<li>元素
//包括元素节点,文本节点和属性节点
//其中title='香蕉' 就是创建的属性节点
var $li_2 = $("<li title='雪梨'>雪梨</li>"); //创建一个<li>元素
//包括元素节点,文本节点和属性节点
//其中title='雪梨' 就是创建的属性节点
var $parent = $("ul"); // 获取<ul>节点。<li>的父节点
$parent.append($li_1); // 添加到<ul>节点中,使之能在网页中显示
$parent.append($li_2); // 等价于:$parent.append($li_1).append($li_2);
});
</script>
</head>
<body>
<p title="选择你最喜欢的水果." >你最喜欢的水果是?</p>
<ul>
<li title='苹果'>苹果</li>
<li title='橘子'>橘子</li>
<li title='菠萝'>菠萝</li>
</ul>
</body>
</html>
1.在lib中加入相应的dwr.jar包
2.在web.xml中加入以下代码:
<servlet>
<servlet-name>dwr-invoker</servlet-name>
<servlet-class>
org.directwebremoting.servlet.DwrServlet
</servlet-class>
<init-param>
<param-name>debug</param-name>
<param-value>true</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>dwr-invoker</servlet-name>
<url-pattern>/dwr/*</url-pattern>
</servlet-mapping>
3.在web-inf目录下新建dwr.xml文件,加入一个简单的配置:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE dwr PUBLIC "-//GetAhead Limited//DTD Direct Web Remoting 2.0//EN" "http://www.getahead.ltd.uk/dwr/dwr20.dtd">
<dwr>
<allow>
<create creator="new" javascript="service">
<param name="class" value="helloWorld.Service"/>
</create>
</allow>
</dwr>
4.新建一个servlet类,
public class Service {
public String sayHello(String yourName){
return yourName;
}
}
5.新建一个jsp页面如下:
<html>
<head>
<title>My JSP 'index.jsp' starting page</title>
<script type='text/javascript' src='/dwr2/dwr/interface/service.js'></script>
<script type='text/javascript' src='/dwr2/dwr/engine.js'></script>
<script type='text/javascript' src='/dwr2/dwr/util.js'></script>
<script type="text/javascript">
function firstdwr(){
service.sayHello("yangjunwei",callback);
}
function callback(d){
alert(d);
}
</script>
</head>
<body>
<input type="button" onclick="firstdwr()"/>
</body>
</html>
当点击按钮时,就会弹出yangjunwei,这就完成了一个简单的dwrajax交互
public class HttpRequestDeviceUtils {
/**Wap网关Via头信息中特有的描述信息*/
private static String mobileGateWayHeaders[]=new String[]{
"ZXWAP",//中兴提供的wap网关的via信息,例如:Via=ZXWAP GateWayZTE Technologies,
"chinamobile.com",//中国移动的诺基亚wap网关,例如:Via=WTP/1.1 GDSZ-PB-GW003-WAP07.gd.chinamobile.com (Nokia WAP Gateway 4.1 CD1/ECD13_D/4.1.04)
"monternet.com",//移动梦网的网关,例如:Via=WTP/1.1 BJBJ-PS-WAP1-GW08.bj1.monternet.com. (Nokia WAP Gateway 4.1 CD1/ECD13_E/4.1.05)
"infoX",//华为提供的wap网关,例如:Via=HTTP/1.1 GDGZ-PS-GW011-WAP2 (infoX-WISG Huawei Technologies),或Via=infoX WAP Gateway V300R001 Huawei Technologies
"XMS 724Solutions HTG",//国外电信运营商的wap网关,不知道是哪一家
"wap.lizongbo.com",//自己测试时模拟的头信息
"Bytemobile",//貌似是一个给移动互联网提供解决方案提高网络运行效率的,例如:Via=1.1 Bytemobile OSN WebProxy/5.1
};
/**电脑上的IE或Firefox浏览器等的User-Agent关键词*/
private static String[] pcHeaders=new String[]{
"Windows 98",
"Windows ME",
"Windows 2000",
"Windows XP",
"Windows NT",
"Ubuntu"
};
/**手机浏览器的User-Agent里的关键词*/
private static String[] mobileUserAgents=new String[]{
"Nokia",//诺基亚,有山寨机也写这个的,总还算是手机,Mozilla/5.0 (Nokia5800 XpressMusic)UC AppleWebkit(like Gecko) Safari/530
"SAMSUNG",//三星手机 SAMSUNG-GT-B7722/1.0+SHP/VPP/R5+Dolfin/1.5+Nextreaming+SMM-MMS/1.2.0+profile/MIDP-2.1+configuration/CLDC-1.1
"MIDP-2",//j2me2.0,Mozilla/5.0 (SymbianOS/9.3; U; Series60/3.2 NokiaE75-1 /110.48.125 Profile/MIDP-2.1 Configuration/CLDC-1.1 ) AppleWebKit/413 (KHTML like Gecko) Safari/413
"CLDC1.1",//M600/MIDP2.0/CLDC1.1/Screen-240X320
"SymbianOS",//塞班系统的,
"MAUI",//MTK山寨机默认ua
"UNTRUSTED/1.0",//疑似山寨机的ua,基本可以确定还是手机
"Windows CE",//Windows CE,Mozilla/4.0 (compatible; MSIE 6.0; Windows CE; IEMobile 7.11)
"iPhone",//iPhone是否也转wap?不管它,先区分出来再说。Mozilla/5.0 (iPhone; U; CPU iPhone OS 4_1 like Mac OS X; zh-cn) AppleWebKit/532.9 (KHTML like Gecko) Mobile/8B117
"iPad",//iPad的ua,Mozilla/5.0 (iPad; U; CPU OS 3_2 like Mac OS X; zh-cn) AppleWebKit/531.21.10 (KHTML like Gecko) Version/4.0.4 Mobile/7B367 Safari/531.21.10
"Android",//Android是否也转wap?Mozilla/5.0 (Linux; U; Android 2.1-update1; zh-cn; XT800 Build/TITA_M2_16.22.7) AppleWebKit/530.17 (KHTML like Gecko) Version/4.0 Mobile Safari/530.17
"BlackBerry",//BlackBerry8310/2.7.0.106-4.5.0.182
"UCWEB",//ucweb是否只给wap页面? Nokia5800 XpressMusic/UCWEB7.5.0.66/50/999
"ucweb",//小写的ucweb貌似是uc的代理服务器Mozilla/6.0 (compatible; MSIE 6.0;) Opera ucweb-squid
"BREW",//很奇怪的ua,例如:REW-Applet/0x20068888 (BREW/3.1.5.20; DeviceId: 40105; Lang: zhcn) ucweb-squid
"J2ME",//很奇怪的ua,只有J2ME四个字母
"YULONG",//宇龙手机,YULONG-CoolpadN68/10.14 IPANEL/2.0 CTC/1.0
"YuLong",//还是宇龙
"COOLPAD",//宇龙酷派YL-COOLPADS100/08.10.S100 POLARIS/2.9 CTC/1.0
"TIANYU",//天语手机TIANYU-KTOUCH/V209/MIDP2.0/CLDC1.1/Screen-240X320
"TY-",//天语,TY-F6229/701116_6215_V0230 JUPITOR/2.2 CTC/1.0
"K-Touch",//还是天语K-Touch_N2200_CMCC/TBG110022_1223_V0801 MTK/6223 Release/30.07.2008 Browser/WAP2.0
"Haier",//海尔手机,Haier-HG-M217_CMCC/3.0 Release/12.1.2007 Browser/WAP2.0
"DOPOD",//多普达手机
"Lenovo",// 联想手机,Lenovo-P650WG/S100 LMP/LML Release/2010.02.22 Profile/MIDP2.0 Configuration/CLDC1.1
"LENOVO",// 联想手机,比如:LENOVO-P780/176A
"HUAQIN",//华勤手机
"AIGO-",//爱国者居然也出过手机,AIGO-800C/2.04 TMSS-BROWSER/1.0.0 CTC/1.0
"CTC/1.0",//含义不明
"CTC/2.0",//含义不明
"CMCC",//移动定制手机,K-Touch_N2200_CMCC/TBG110022_1223_V0801 MTK/6223 Release/30.07.2008 Browser/WAP2.0
"DAXIAN",//大显手机DAXIAN X180 UP.Browser/6.2.3.2(GUI) MMP/2.0
"MOT-",//摩托罗拉,MOT-MOTOROKRE6/1.0 LinuxOS/2.4.20 Release/8.4.2006 Browser/Opera8.00 Profile/MIDP2.0 Configuration/CLDC1.1 Software/R533_G_11.10.54R
"SonyEricsson",// 索爱手机,SonyEricssonP990i/R100 Mozilla/4.0 (compatible; MSIE 6.0; Symbian OS; 405) Opera 8.65 [zh-CN]
"GIONEE",//金立手机
"HTC",//HTC手机
"ZTE",//中兴手机,ZTE-A211/P109A2V1.0.0/WAP2.0 Profile
"HUAWEI",//华为手机,
"webOS",//palm手机,Mozilla/5.0 (webOS/1.4.5; U; zh-CN) AppleWebKit/532.2 (KHTML like Gecko) Version/1.0 Safari/532.2 Pre/1.0
"GoBrowser",//3g GoBrowser.User-Agent=Nokia5230/GoBrowser/2.0.290 Safari
"IEMobile",//Windows CE手机自带浏览器,
"WAP2.0"//支持wap 2.0的
};
/**
* 根据当前请求的特征,判断该请求是否来自手机终端,主要检测特殊的头信息,以及user-Agent这个header
* @param request http请求
* @return 如果命中手机特征规则,则返回对应的特征字符串
*/
public static boolean isMobileDevice(HttpServletRequest request){
boolean b = false;
boolean pcFlag = false;
boolean mobileFlag = false;
String via = request.getHeader("Via");
String userAgent = request.getHeader("user-agent");
for (int i = 0; via!=null && !via.trim().equals("") && i < mobileGateWayHeaders.length; i++) {
if(via.contains(mobileGateWayHeaders[i])){
mobileFlag = true;
break;
}
}
for (int i = 0;!mobileFlag && userAgent!=null && !userAgent.trim().equals("") && i < mobileUserAgents.length; i++) {
if(userAgent.contains(mobileUserAgents[i])){
mobileFlag = true;
break;
}
}
for (int i = 0; userAgent!=null && !userAgent.trim().equals("") && i < pcHeaders.length; i++) {
if(userAgent.contains(pcHeaders[i])){
pcFlag = true;
break;
}
}
if(mobileFlag==true && pcFlag==false){
b=true;
}
return b;//false pc true shouji
}
}
可以写一个类继承Handler类,拦截所有的请求,得到url,根据请求头的信息判断出是手机访问还是电脑访问,根据需求跳转到不同的页面或者方法中
<html>
<head>
<script>
function hello(){
alert("hello");
}
function byee(){
alert("bye");
}
function show(){
var v = document.myform.inname.value;
var p = document.myform.pwd.value;
alert(v+p);
}
function valia(f){
var v = document.myform.inname.value;
var p = document.myform.pwd.value;
return true;
}
</script>
</head>
<body onload="hello()" onUnLoad="byee()" >
<form action="dd" name="myform" onsubmit="return valia(this) ">
<input type="text" name="inname" />
<input type="text" name="pwd" />
<input type="submit" />
</form>
</body>
</html>
判断应该属于程序部分的处理,不属于
前端的范畴,是靠判断请求头信息(HTTP_USER_AGENT)进行判断的。
步骤是:1.
首先需要安装三个Firefox插件:wmlbrowser、XHTML Mobile Profile、User Agent Switcher;(我称它们为“伪娘三贱客”)
2.
安装好后需要设置 User Agent Switcher ,点击菜单 工具 → Default User Agent → User Agent Switcher → Options → New→New User Agent... ,Description是你给它的一个称呼,比如小三,凹凸曼等等。关键的部分是User Agent里面的东西(这里是请求头主要的信息,程序会根据这个请求头进行判断你是否是手持设备),这里就需要把我们想要模拟的手持设备的信息填入了。
3.
添加好后一路确定,回到浏览器界面。工具 →default user agent →选择你自己添加的那个 →在浏览器地址输入你想要访问的地址即可。
十分大方这里你会看到几个选项,Default User Agent (浏览器默认的信息),Internet Explorer (可以模拟ie6,7,8的头信息),Search Robots (模拟谷歌,雅虎,msn的蜘蛛),iphone 3.0 (默认存在的一个)
4.
下面列出几个比较常见手机的User Agent:(如果想要查询更多的手机user agent 信息的话,
去看这里,
还有这里)
iPhone3:
Mozilla/5.0 (iPhone; U; CPU iPhone OS 3_0 like Mac OS X; en-us) AppleWebKit/528.18 (KHTML, like Gecko) Version/4.0 Mobile/7A341 Safari/528.16
Android:
Mozilla/5.0 (Linux; U; Android 2.2; en-us; Nexus One Build/FRF91) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1
诺基亚N95:
Mozilla/5.0 (SymbianOS/9.2; U; Series60/3.1 NokiaN95/30.0.015; Profile MIDP-2.0 Configuration/CLDC-1.1) AppleWebKit/413 (KHTML, like Gecko) Safari/413
诺基亚N97:
Mozilla/5.0 (SymbianOS/9.4; Series60/5.0 NokiaN97-1/20.0.019; Profile/MIDP-2.1 Configuration/CLDC-1.1) AppleWebKit/525 (KHTML, like Gecko) BrowserNG/7.1.18124
package pc;
import javax.servlet.http.HttpServletRequest;
public class HttpRequestDeviceUtils {
/**Wap网关Via头信息中特有的描述信息*/
private static String mobileGateWayHeaders[]=new String[]{
"ZXWAP",//中兴提供的wap网关的via信息,例如:Via=ZXWAP GateWayZTE Technologies,
"chinamobile.com",//中国移动的诺基亚wap网关,例如:Via=WTP/1.1 GDSZ-PB-GW003-WAP07.gd.chinamobile.com (Nokia WAP Gateway 4.1 CD1/ECD13_D/4.1.04)
"monternet.com",//移动梦网的网关,例如:Via=WTP/1.1 BJBJ-PS-WAP1-GW08.bj1.monternet.com. (Nokia WAP Gateway 4.1 CD1/ECD13_E/4.1.05)
"infoX",//华为提供的wap网关,例如:Via=HTTP/1.1 GDGZ-PS-GW011-WAP2 (infoX-WISG Huawei Technologies),或Via=infoX WAP Gateway V300R001 Huawei Technologies
"XMS 724Solutions HTG",//国外电信运营商的wap网关,不知道是哪一家
"wap.lizongbo.com",//自己测试时模拟的头信息
"Bytemobile",//貌似是一个给移动互联网提供解决方案提高网络运行效率的,例如:Via=1.1 Bytemobile OSN WebProxy/5.1
};
/**电脑上的IE或Firefox浏览器等的User-Agent关键词*/
private static String[] pcHeaders=new String[]{
"Windows 98",
"Windows ME",
"Windows 2000",
"Windows XP",
"Windows NT",
"Ubuntu"
};
/**手机浏览器的User-Agent里的关键词*/
private static String[] mobileUserAgents=new String[]{
"Nokia",//诺基亚,有山寨机也写这个的,总还算是手机,Mozilla/5.0 (Nokia5800 XpressMusic)UC AppleWebkit(like Gecko) Safari/530
"SAMSUNG",//三星手机 SAMSUNG-GT-B7722/1.0+SHP/VPP/R5+Dolfin/1.5+Nextreaming+SMM-MMS/1.2.0+profile/MIDP-2.1+configuration/CLDC-1.1
"MIDP-2",//j2me2.0,Mozilla/5.0 (SymbianOS/9.3; U; Series60/3.2 NokiaE75-1 /110.48.125 Profile/MIDP-2.1 Configuration/CLDC-1.1 ) AppleWebKit/413 (KHTML like Gecko) Safari/413
"CLDC1.1",//M600/MIDP2.0/CLDC1.1/Screen-240X320
"SymbianOS",//塞班系统的,
"MAUI",//MTK山寨机默认ua
"UNTRUSTED/1.0",//疑似山寨机的ua,基本可以确定还是手机
"Windows CE",//Windows CE,Mozilla/4.0 (compatible; MSIE 6.0; Windows CE; IEMobile 7.11)
"iPhone",//iPhone是否也转wap?不管它,先区分出来再说。Mozilla/5.0 (iPhone; U; CPU iPhone OS 4_1 like Mac OS X; zh-cn) AppleWebKit/532.9 (KHTML like Gecko) Mobile/8B117
"iPad",//iPad的ua,Mozilla/5.0 (iPad; U; CPU OS 3_2 like Mac OS X; zh-cn) AppleWebKit/531.21.10 (KHTML like Gecko) Version/4.0.4 Mobile/7B367 Safari/531.21.10
"Android",//Android是否也转wap?Mozilla/5.0 (Linux; U; Android 2.1-update1; zh-cn; XT800 Build/TITA_M2_16.22.7) AppleWebKit/530.17 (KHTML like Gecko) Version/4.0 Mobile Safari/530.17
"BlackBerry",//BlackBerry8310/2.7.0.106-4.5.0.182
"UCWEB",//ucweb是否只给wap页面? Nokia5800 XpressMusic/UCWEB7.5.0.66/50/999
"ucweb",//小写的ucweb貌似是uc的代理服务器Mozilla/6.0 (compatible; MSIE 6.0;) Opera ucweb-squid
"BREW",//很奇怪的ua,例如:REW-Applet/0x20068888 (BREW/3.1.5.20; DeviceId: 40105; Lang: zhcn) ucweb-squid
"J2ME",//很奇怪的ua,只有J2ME四个字母
"YULONG",//宇龙手机,YULONG-CoolpadN68/10.14 IPANEL/2.0 CTC/1.0
"YuLong",//还是宇龙
"COOLPAD",//宇龙酷派YL-COOLPADS100/08.10.S100 POLARIS/2.9 CTC/1.0
"TIANYU",//天语手机TIANYU-KTOUCH/V209/MIDP2.0/CLDC1.1/Screen-240X320
"TY-",//天语,TY-F6229/701116_6215_V0230 JUPITOR/2.2 CTC/1.0
"K-Touch",//还是天语K-Touch_N2200_CMCC/TBG110022_1223_V0801 MTK/6223 Release/30.07.2008 Browser/WAP2.0
"Haier",//海尔手机,Haier-HG-M217_CMCC/3.0 Release/12.1.2007 Browser/WAP2.0
"DOPOD",//多普达手机
"Lenovo",// 联想手机,Lenovo-P650WG/S100 LMP/LML Release/2010.02.22 Profile/MIDP2.0 Configuration/CLDC1.1
"LENOVO",// 联想手机,比如:LENOVO-P780/176A
"HUAQIN",//华勤手机
"AIGO-",//爱国者居然也出过手机,AIGO-800C/2.04 TMSS-BROWSER/1.0.0 CTC/1.0
"CTC/1.0",//含义不明
"CTC/2.0",//含义不明
"CMCC",//移动定制手机,K-Touch_N2200_CMCC/TBG110022_1223_V0801 MTK/6223 Release/30.07.2008 Browser/WAP2.0
"DAXIAN",//大显手机DAXIAN X180 UP.Browser/6.2.3.2(GUI) MMP/2.0
"MOT-",//摩托罗拉,MOT-MOTOROKRE6/1.0 LinuxOS/2.4.20 Release/8.4.2006 Browser/Opera8.00 Profile/MIDP2.0 Configuration/CLDC1.1 Software/R533_G_11.10.54R
"SonyEricsson",// 索爱手机,SonyEricssonP990i/R100 Mozilla/4.0 (compatible; MSIE 6.0; Symbian OS; 405) Opera 8.65 [zh-CN]
"GIONEE",//金立手机
"HTC",//HTC手机
"ZTE",//中兴手机,ZTE-A211/P109A2V1.0.0/WAP2.0 Profile
"HUAWEI",//华为手机,
"webOS",//palm手机,Mozilla/5.0 (webOS/1.4.5; U; zh-CN) AppleWebKit/532.2 (KHTML like Gecko) Version/1.0 Safari/532.2 Pre/1.0
"GoBrowser",//3g GoBrowser.User-Agent=Nokia5230/GoBrowser/2.0.290 Safari
"IEMobile",//Windows CE手机自带浏览器,
"WAP2.0"//支持wap 2.0的
};
/**
* 根据当前请求的特征,判断该请求是否来自手机终端,主要检测特殊的头信息,以及user-Agent这个header
* @param request http请求
* @return 如果命中手机特征规则,则返回对应的特征字符串
*/
public static boolean isMobileDevice(HttpServletRequest request){
boolean b = false;
boolean pcFlag = false;
boolean mobileFlag = false;
String via = request.getHeader("Via");
String userAgent = request.getHeader("user-agent");
for (int i = 0; via!=null && !via.trim().equals("") && i < mobileGateWayHeaders.length; i++) {
if(via.contains(mobileGateWayHeaders[i])){
mobileFlag = true;
break;
}
}
for (int i = 0;!mobileFlag && userAgent!=null && !userAgent.trim().equals("") && i < mobileUserAgents.length; i++) {
if(userAgent.contains(mobileUserAgents[i])){
mobileFlag = true;
break;
}
}
for (int i = 0; userAgent!=null && !userAgent.trim().equals("") && i < pcHeaders.length; i++) {
if(userAgent.contains(pcHeaders[i])){
pcFlag = true;
break;
}
}
if(mobileFlag==true && pcFlag==false){
b=true;
}
return b;//false pc true shouji
}
}
public static List<String> getWeekDay(String strDate) {
List<String> list = new ArrayList<String>();//第几周,周几
String nReturn = null;
Calendar c = Calendar.getInstance(); // 实例化一个Calendar对象
c.clear(); // 清空Calendar
c.set(Integer.parseInt(strDate.substring(0, 4)), Integer
.parseInt(strDate.substring(5, 7)) - 1, Integer
.parseInt(strDate.substring(8, 10))); // 设置这个日期的内容
System.out.println("------------" + c.get(Calendar.YEAR) + "年" + (c.get(Calendar.MONTH) + 1) + "月"+(c.get(Calendar.DATE))+"日的天数和周数-------------");
System.out.println("天数:" + c.getActualMaximum(Calendar.DAY_OF_MONTH));
System.out.println("周数:" + c.getActualMaximum(Calendar.WEEK_OF_MONTH));
System.out.println("第几周:"+c.get(Calendar.DAY_OF_WEEK_IN_MONTH));
switch (c.get(Calendar.DAY_OF_WEEK)) {
case 1:
nReturn = "7";
break;
case 2:
nReturn = "1";
break;
case 3:
nReturn = "2";
break;
case 4:
nReturn = "3";
break;
case 5:
nReturn = "4";
break;
case 6:
nReturn = "5";
break;
case 7:
nReturn = "6";
break;
default:
nReturn = null;
break;
}
list.add(String.valueOf(c.get(Calendar.DAY_OF_WEEK_IN_MONTH)));
list.add(nReturn);
return list;
}
先要在exporting.js中修改导出图片的url是本地的服务器地址
String type = getPara("type");//getRequest().getParameter("type");
String svg =getPara("svg");// getRequest().getParameter("svg");
String filename = getPara("filename");//getRequest().getParameter("filename");
ServletOutputStream out1 = null;
try {
//getRequest().setCharacterEncoding("utf-8");
System.out.println(type);
System.out.println(svg);
System.out.println(filename);
filename = filename==null?"chart":filename;
out1 = getResponse().getOutputStream();
if (null != type && null != svg) {
svg = svg.replaceAll(":rect", "rect");
String ext = "";
Transcoder t = null;
if (type.equals("image/png")) {
ext = "png";
t = new PNGTranscoder();
} else if (type.equals("image/jpeg")) {
ext = "jpg";
t = new JPEGTranscoder();
} else if(type.equals("image/svg+xml")) {
ext = "svg";
}else if(type.equals("application/pdf")){
t = new PDFTranscoder();
ext = "pdf";
}
getResponse().addHeader("Content-Disposition", "attachment; filename="+ filename + "."+ext);
getResponse().addHeader("Content-Type", type);
if (null != t) {
TranscoderInput input = new TranscoderInput(new StringReader(svg));
TranscoderOutput output = new TranscoderOutput(out1);
try {
t.transcode(input, output);
} catch (TranscoderException e) {
out1.print("Problem transcoding stream. See the web logs for more details.");
e.printStackTrace();
}
} else if (ext.equals("svg")) {
// out.print(svg);
OutputStreamWriter writer = new OutputStreamWriter(out1, "UTF-8");
writer.append(svg);
writer.flush();
writer.close();
} /*else
out.print("Invalid type: " + type);*/
} else {
//getResponse().addHeader("Content-Type", "text/html");
// out.println("Usage:\n\tParameter [svg]: The DOM Element to be converted." +
// "\n\tParameter [type]: The destination MIME type for the elment to be transcoded.");
}
} catch (Exception e) {
e.printStackTrace();
}finally{
try {
out1.flush();
getResponse().flushBuffer();
out1.close();
} catch (Exception e2) {
}
}
需要的jar包:
Ext.namespace('Ext.ux');
Ext.ux.EmRealtimeDisplayPanel = function(treeNode, panelId, config) {
this.treeNode = treeNode;
this.panelId = panelId;
var temhum = new Ext.form.ComboBox({
name : 'temhunm',
fieldLabel : '状态',
allowBlank : false,
blankText : '请选择温湿度',
editable : false,
triggerAction : 'all',//all表示把下拉框列表框的列表值全部显示出来
store : new Ext.data.ArrayStore({
fields : [ 'name', 'value' ],
data : [ [ '温度', '1' ], [ '湿度', '2' ] ]
}),
mode : 'local',
displayField : 'name',
valueField : 'value',
width : 60
});
var storenode = new Ext.data.JsonStore({ //读配置文件
autoLoad:true,
url : path+"/wenshi/getnode",
root : "options",
fields : [ {
name : 'name'
}]
});
var node = new Ext.form.ComboBox({
fieldLabel : '节点',
allowBlank : false,
blankText : '请选择节点',
editable : false,
triggerAction : 'all',
store : storenode,
mode : 'local',
displayField : 'name',
valueField : 'name',
width : 60
});
var dataArr = new Array();
var store = new Ext.data.ArrayStore({
fields: ['data', 'time'],
data: dataArr
});
var varNodeId = '';//节点的id值
var taskStart = false;
//定时器里面的参数配置
var task = {
run: function(){
gridStore.load({
params: {
'nodeid' : varNodeId,
'tem' :th
},
callback:function(r){
if(!(typeof(r[0])==='undefined')) {
dataArr.push([r[0].data.data, r[0].data.time]);
store.loadData(dataArr);
}
}
});
},
interval: 3000
};
var gridStore= new Ext.data.JsonStore({
fields:['time', 'data'],
autoLoad:true,
baseParams : {
'nodeid' : "",
'tem' :""
},
url :path+'/wenshi/getShishiData',
root : "data"
});
var panel1= new Ext.Panel({
title: '实时曲线图显示',
width: 700,
height: 400,
smooth: true,
type: 'circle',
items: {
xtype: 'linechart',
url: 'extjs3/resources/charts.swf',
store: store,
xField: 'time',
yField: 'data',
xAxis: new Ext.chart.CategoryAxis({
title: '时间(秒)'//00 09:00 分钟 秒:毫秒
}),
yAxis: new Ext.chart.NumericAxis({
title: '数值'
})
},
tbar : [
{
xtype : 'label',
text : '请选择节点: '
},
node, {
xtype : 'label',
text : '请选择温湿度: '
},
temhum,
{
text : '查询',
handler : function(btn, event) {
var nodeid = node.getValue();
var tem = temhum.getValue();
if (nodeid == undefined || nodeid == ''||tem==''){
return;
} else {
dataArr = new Array();
varNodeId = nodeid;
th = tem;
// alert(th);
if(!taskStart) {
Ext.TaskMgr.start(task);//定时执行代码
taskStart =true;
}
}
}
}]
});
Ext.ux.EmRealtimeDisplayPanel.superclass.constructor.call(this, {
id : this.panelId,
title : this.treeNode.text,
layout : 'fit',
closable : true,
preventBodyReset : true,
items : [panel1]
});
};
Ext.extend(Ext.ux.EmRealtimeDisplayPanel, Ext.Panel, {});
Ext.reg('emEmRealtimeDisplayPanel', Ext.ux.EmRealtimeDisplayPanel);
Ext.namespace('Ext.ux');
Ext.ux.WaterRealtimeDisplayPanel = function(treeNode, panelId, config) {
this.treeNode = treeNode;
this.panelId = panelId;
var series=[{"name":"实时数据显示","data":[]}];
var temhum = new Ext.form.ComboBox({
name : 'temhunm',
fieldLabel : '状态',
allowBlank : false,
blankText : '请选择温湿度',
editable : false,
triggerAction : 'all',//all表示把下拉框列表框的列表值全部显示出来
store : new Ext.data.ArrayStore({
fields : [ 'name', 'value' ],
data : [ [ '温度', '1' ], [ '湿度', '2' ] ]
}),
mode : 'local',
displayField : 'name',
valueField : 'value',
width : 60
});
var storeProvince = new Ext.data.JsonStore({
autoLoad:true,
url : path+"/wenshi/getnode",
root : "options",
fields : [ {
name : 'name'
}]
});
var nodeCtl = new Ext.form.ComboBox({
fieldLabel : '节点',
allowBlank : false,
blankText : '请选择节点',
editable : false,
triggerAction : 'all',
store : storeProvince,
mode : 'local',
displayField : 'name',
valueField : 'name',
width : 140
});
var stTime = new Ext.form.DateField({
fieldLabel : '选择时间',
allowBlank : false,
emptyText : '请选择开始日期',
editable : false,
format : 'Y-m-d',
maxValue : new Date(),
width : 130
});
var data = [
['y','年'],
['m','月'],
['d','日']
// ['w','周']
];
var store = new Ext.data.SimpleStore({
fields: ['value', 'text'],
data: data
});
var combo = new Ext.form.ComboBox({
store: store,
fieldLabel:"请选择时间对应的类型",
emptyText: '请选择筛选类型',
mode: 'local',
triggerAction : 'all',
valueField: 'value',
displayField: 'text'
});
Ext.ux.WaterRealtimeDisplayPanel.superclass.constructor.call(this, {
id : this.panelId,
title : this.treeNode.text,
closable : true,
autoScroll : true,
height : 400,
items:[
{
layout:'column',
border:false,
items:[{
//columnWidth: .25 ,
layout:'form',
border:false,
labelAlign:'right',
width : 200,
labelWidth:40,
items:[
temhum, nodeCtl]
}
,{
layout:'form',
width : 200,
labelWidth:60,
border:false,
labelAlign:'left',
items:[stTime]
},//combo
combo
,
{
layout:'form',
border:false,
scope:this,
items:[{
xtype:'button',
border:false,
width:70,
style:"margin-left:10px",
text:'查询',
scope:this,
handler:function(){
// 获取表单对象
var _params_ = this.getForm().getValues(false);
var nodeid = nodeCtl.getValue();//获取节点id
var checktype=combo.getValue();//选择的筛选类型
var checktime=stTime.getValue();//获取时间的值
var th = temhum.getValue();
if (th == undefined || th == ''){
Ext.Msg.alert("提示","节点不能为空");
return;
}
if (nodeid == undefined || nodeid == ''){
Ext.Msg.alert("提示","节点不能为空");
return;
}
if(!stTime.isValid()){
Ext.Msg.alert('信息', '时间为必选项');
return;
}
if (checktype == undefined || checktype == ''){
Ext.Msg.alert("提示","筛选类型不能为空");
return;
}
// 获得统计【就是显示的那个图】 配置文件对象
var _op_ = this.getOptions();
//首先从后台获得x轴上值
var categories=_op_.xAxis.categories;
categories=[];
$.ajax({
type:"POST", // 提交方式
url:path+'/wenshi/collectHositoryDataName', // 提交地址
dataType:"json", // 解释格式
data:{"nodeid":nodeid,"checktime":checktime.format('Y-m-d'),"checktype":checktype,"th":th}, // 请求参数
success:function(iJson){
var results = eval(iJson); // 转换成 JSON 数据
var r = results[0].data;
for(var i=0;i<r.length;i++){
categories.push(r[i]);
}
_op_.xAxis.categories=categories;
},
error:function(){
Ext.Msg.alert('系统操作','网络不通畅或数据格式不对!');
}
});
// 获得统计 对象的 数据
var _series_ = _op_.series;
// 清空 统计 对象的 数据 重新加载
_series_ = [] ;
// 创建一个统计 对象胡方法
var _createChart_ = function (obj){new Highcharts.Chart(obj);};
// 向后台发送请求
var d = new Ext.util.DelayedTask(function(){
$.ajax({
type:"POST", // 提交方式
url:path+'/wenshi/collectHositoryData', // 提交地址
dataType:"json", // 解释格式
data:{"nodeid":nodeid,"checktime":checktime.format('Y-m-d'),"checktype":checktype,"th":th}, // 请求参数
success:function(iJson){
var results = eval(iJson); // 转换成 JSON 数据
for(var i =0 ; i < results.length;i++){ // 解释和装载数据
_series_.push({name:results[i].name,data:results[i].data});
}
_op_.series = _series_; // 赋值
_createChart_(_op_); // 重新创建一个统计
},
error:function(){
Ext.Msg.alert('系统操作','网络不通畅或数据格式不对!');
}
});
});
d.delay(1000);
}
}]
}]
},
{
xtype:'panel', // 创建 Highcharts 所依赖的 div
html:'<div id="'+"test"+'" style="width:1000px; height: 500px; margin: 0 auto"></div>'
}
],
listeners : {
activate : function(p) {
var obj=this.getOptions();
obj.series=series;
var chart =new Highcharts.Chart(obj);
}
},
getOptions:function(){
return {
chart : {
renderTo :"test",
type: 'spline'
},
lang : {
exportButtonTitle : '导出图表',
printButtonTitle : '打印报表'
},
title : {
text : '节点历史参数曲线图'
},
xAxis : {
title : {
text : '采集时间'
}
,
//categories : ['1秒', '2秒','3秒']//设置x轴上分类名称
},
yAxis : {
title : {
text : '节点参数值'
},
plotLines: [{
value: 0,
width: 1,
color: '#808080'
}]
},
tooltip: {
//enabled: false, //是否显示提示框
formatter: function() {
return "时间:"+this.x +'<br/>'+"参数值:"+ this.y;
}
}
//,
// series : [{
// name : '实时数据显示',
// data : [141, 100, 4]
// }]
};
}
});
};
Ext.extend(Ext.ux.WaterRealtimeDisplayPanel, Ext.FormPanel, {
});
Ext.reg('ljsStudentTuPanel', Ext.ux.WaterRealtimeDisplayPanel);
后台导出图片的方法是:
public class ImageController extends Controller{
public void index(){
String type = getPara("type");
String svg =getPara("svg");
String filename = getPara("filename");
ServletOutputStream out1 = null;
try {
filename = filename==null?"chart":filename;
out1 = getResponse().getOutputStream();
if (null != type && null != svg) {
svg = svg.replaceAll(":rect", "rect");
String ext = "";
Transcoder t = null;
if (type.equals("image/png")) {
ext = "png";
t = new PNGTranscoder();
} else if (type.equals("image/jpeg")) {
ext = "jpg";
t = new JPEGTranscoder();
} else if(type.equals("image/svg+xml")) {
ext = "svg";
}else if(type.equals("application/pdf")){
t = new PDFTranscoder();
ext = "pdf";
}
getResponse().addHeader("Content-Disposition", "attachment; filename="+ filename + "."+ext);
getResponse().addHeader("Content-Type", type);
if (null != t) {
TranscoderInput input = new TranscoderInput(new StringReader(svg));
TranscoderOutput output = new TranscoderOutput(out1);
try {
t.transcode(input, output);
} catch (TranscoderException e) {
out1.print("Problem transcoding stream. See the web logs for more details.");
e.printStackTrace();
}
} else if (ext.equals("svg")) {
OutputStreamWriter writer = new OutputStreamWriter(out1, "UTF-8");
writer.append(svg);
writer.flush();
writer.close();
} else
out1.print("Invalid type: " + type);
} else {
//getResponse().addHeader("Content-Type", "text/html");
// out.println("Usage:\n\tParameter [svg]: The DOM Element to be converted." +
// "\n\tParameter [type]: The destination MIME type for the elment to be transcoded.");
}
} catch (Exception e) {
e.printStackTrace();
}finally{
try {
out1.flush();
getResponse().flushBuffer();
out1.close();
} catch (Exception e2) {
}
}
renderNull();//不跳转
}
}
public static int getDaysByMonth(String time){
Calendar rightNow = Calendar.getInstance();
SimpleDateFormat simpleDate = new SimpleDateFormat("yyyy-MM"); //如果写成年月日的形式的话,要写小d,如:"yyyy/MM/dd"
try {
rightNow.setTime(simpleDate.parse(time)); //要计算你想要的月份,改变这里即可
} catch (Exception e) {
e.printStackTrace();
}
int days = rightNow.getActualMaximum(Calendar.DAY_OF_MONTH);
return days;
}
public static List<String> getWeekDay(String str) {
List<String> list = new ArrayList<String>();
Calendar c = Calendar.getInstance();
SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date date = null;
try {
date = sdf.parse(str);
} catch (ParseException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
c.setTime(date);
int week = c.get(Calendar.WEEK_OF_MONTH);//获取是本月的第几周
System.out.println("今天是本月的第" + week + "周");
String nReturn;
switch (c.get(Calendar.DAY_OF_WEEK)) {
case 1:
nReturn = "7";
break;
case 2:
nReturn = "1";
break;
case 3:
nReturn = "2";
break;
case 4:
nReturn = "3";
break;
case 5:
nReturn = "4";
break;
case 6:
nReturn = "5";
break;
case 7:
nReturn = "6";
break;
default:
nReturn = null;
break;
}
list.add(String.valueOf(String.valueOf(week)));
list.add(nReturn);
System.out.println(nReturn);
return list;
}
public static String getWeekOfDate(Date dt) {
String[] weekDays = {"星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六"};
Calendar cal = Calendar.getInstance();
cal.setTime(dt);
int w = cal.get(Calendar.DAY_OF_WEEK) - 1;
if (w < 0)
w = 0;
return weekDays[w];
}
这两个方法都可以用来实现在一个固定时间段之后去执行JavaScript。不过两者各有各的应用场景。
方 法
实际上,setTimeout和setInterval的语法相同。它们都有两个参数,一个是将要执行的代码字符串,还有一个是以毫秒为单位的时间间隔,当过了那个时间段之后就将执行那段代码。
不过这两个函数还是有区别的,setInterval在执行完一次代码之后,经过了那个固定的时间间隔,它还会自动重复执行代码,而setTimeout只执行一次那段代码。
虽然表面上看来setTimeout只能应用在on-off方式的动作上,不过可以通过创建一个函数循环重复调用setTimeout,以实现重复的操作:
showTime();
function showTime()
{
var today = new Date();
alert("The time is: " + today.toString());
setTimeout("showTime()", 5000);
}
一旦调用了这个函数,那么就会每隔5秒钟就显示一次时间。如果使用setInterval,则相应的代码如下所示: setInterval("showTime()", 5000);
function showTime()
{
var today = new Date();
alert("The time is: " + today.toString());
}
这两种方法可能看起来非常像,而且显示的结果也会很相似,不过两者的最大区别就是,setTimeout方法不会每隔5秒钟就执行一次showTime函数,它是在每次调用setTimeout后过5秒钟再去执行showTime函数。这意味着如果showTime函数的主体部分需要2秒钟执行完,那么整个函数则要每7秒钟才执行一次。而setInterval却没有被自己所调用的函数所束缚,它只是简单地每隔一定时间就重复执行一次那个函数。
如果要求在每隔一个固定的时间间隔后就精确地执行某动作,那么最好使用setInterval,而如果不想由于连续调用产生互相干扰的问题,尤其是每次函数的调用需要繁重的计算以及很长的处理时间,那么最好使用setTimeout。
两个计时函数中的第一个参数是一段代码的字符串,其实该参数也可以是一个函数指针,不过Mac下的IE 5对此不支持。
如果用函数指针作为setTimeout和setInterval函数的第二个参数,那么它们就可以去执行一个在别处定义的函数了:
setTimeout(showTime, 500);
function showTime()
{
var today = new Date();
alert("The time is: " + today.toString());
}
另外,匿名函数还可以声明为内联函数:
setTimeout(function(){var today = new Date();
alert("The time is: " + today.toString());}, 500);
如果对计时函数不加以处理,那么setInterval将会持续执行相同的代码,一直到浏览器窗口关闭,或者用户转到了另外一个页面为止。不过还是有办法可以终止setTimeout和setInterval函数的执行。
当setInterval调用执行完毕时,它将返回一个timer ID,将来便可以利用该值对计时器进行访问,如果将该ID传递给clearInterval,便可以终止那段被调用的过程代码的执行了,具体实现如下:
var intervalProcess = setInterval("alert('GOAL!')", 3000);
var stopGoalLink = document.getElementById("stopGoalLink");
attachEventListener(stopGoalLink, "click", stopGoal, false);
function stopGoal()
{
clearInterval(intervalProcess);
}
只要点击了stopGoalLink,不管是什么时候点击,intervalProcess都会被取消掉,以后都不会再继续反复执行intervalProcess。如果在超时时间段内就取消setTimeout,那么这种终止效果也可以在setTimeout身上实现,具体实现如下: var timeoutProcess = setTimeout("alert('GOAL!')", 3000);
var stopGoalLink = document.getElementById("stopGoalLink");
attachEventListener(stopGoalLink, "click", stopGoal, false);
function stopGoal()
{
clearTimeout(timeoutProcess);
}