java基础9

装饰设计模式::

	public static void abc(File desc,File src){
		//不可将文件夹复制到它的子文件夹下.
		if(desc.getAbsolutePath().contains(src.getAbsolutePath())){
			System.out.println("父目录不能拷贝到子目录中");
		}
		//超长文件夹删除
		//借助robocopy.rar百度如何使用		
	}
	//文件分隔与合并
	public static void randomaccessfile() throws IOException{
		
		RandomAccessFile raf=new RandomAccessFile(new File(""), "r");
		raf.seek(10);/
		byte[] flush=new byte[1024];
		int len=0;
		while (-1!=(len=raf.read(flush))) {
			System.out.println(new String(flush,0,len));
		}
		
		//文件的分隔思路
		//1.分隔的块数,2.每一块的大小,3.最后一块的大小:总的文件大小-(n-1)*blocksize 4.每块的名称
		//分割:第几块,每块的起点,实际大小
		
	}

文件分割与合并::::::

package basic;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintStream;
import java.io.RandomAccessFile;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.List;

import javax.naming.InitialContext;
public class Basic {
	@SuppressWarnings("unchecked")
	public static void main(String[] args) throws ParseException, FileNotFoundException, IOException {
		SplitFile sf=new SplitFile("E:/a/b.rar",100);
		System.out.println(sf.size);//输出分了多少块
		sf.split("E:/a/b/c.rar");
	}
}

class SplitFile{
	private String filePath;//文件路径
	private String fileName;//文件名称
	private long blockSize;//每块大小
	private long length;//文件大小
	public int size;//块数
	private List<String> blockPath;//每块的名称
	public SplitFile() {
		blockPath=new ArrayList<>();
	}
	public SplitFile(String filePath, long blockSize) {
		this();
		this.filePath = filePath;
		this.blockSize = blockSize;
		init();
	}
	public SplitFile(String filePath) {
		this(filePath,1024);
	}
	public void init(){
		File src=null;
		if(null==filePath || !((src=new File(filePath)).exists())){
			return;
		}
		this.fileName=src.getName();
		this.length=src.length();
		if(this.blockSize>length){
			this.blockSize=length;
		}
		size=(int)(Math.ceil(length*1.0/this.blockSize));
		//initPath();
}
	private void initPath(String destPath){
		for (int i = 0; i < size; i++) {
			this.blockPath.add(destPath+"/"+fileName+".part"+i);
		}
	}
	//文件的分割
	public void split(String destPath){
		//确定文件路径
		initPath(destPath);
		long beginPos=0;
		long actualBlocksize=blockSize;
		for (int i = 0; i < size; i++) {
			if(i==size-1){
				actualBlocksize=this.length-beginPos;
			}
			splitDetail(i,beginPos,actualBlocksize);
			beginPos+=actualBlocksize;
		}
	}
	private void splitDetail(int idx, long beginPos, long actualBlocksize) throws IOException {
		// TODO Auto-generated method stub
		File src=new File(this.filePath);
		File dest=new File(this.blockPath.get(idx));
		RandomAccessFile raf=null;//输入流
		BufferedOutputStream bos=null;//输出流
		raf=new RandomAccessFile(src, "r");
		bos=new BufferedOutputStream(new FileOutputStream(dest));
		raf.seek(beginPos);
		byte[] flush=new byte[1024];
		int len=0;
		while (-1!=(len=raf.read(flush))) {
			if(actualBlocksize-len>=0){
				bos.write(flush, 0, len);
				actualBlocksize-=len;
			}else{
				bos.write(flush, 0,(int)actualBlocksize);
				break;
			}
		}
	}
	//文件合并
	public void mergeFile(String destPath) throws IOException{
		File dest=new File(destPath);
		BufferedOutputStream bos=new BufferedOutputStream(new FileOutputStream(dest,true));//true表示追加
		BufferedInputStream bis=null;
		for(int i=0;i<this.blockPath.size();i++){
			bis=new BufferedInputStream(new FileInputStream(new File(this.blockPath.get(i))));
			byte[] flush=new byte[1024];
			int len=0;
			while(-1!=(len=bis.read(flush))){
				bos.write(flush, 0, len);
			}
		}
		bos.flush();
		bis.close();
		bos.close();
	}
	
}
SequenceInputStream:表示其它输入流的逻辑串联,它从输入流的有序集合开始,并从第一个输入流开始读取,直到到达文件结尾,接者从第二个输入流开始读取,依次类推。

	//文件合并
	public void mergeFile(String destPath) throws IOException{
		File dest=new File(destPath);
		BufferedOutputStream bos=new BufferedOutputStream(new FileOutputStream(dest,true));//true表示追加
		SequenceInputStream sis=null;
		Vector<InputStream> vi=new Vector<>();
		for (int i = 0; i < this.blockPath.size(); i++) {
			vi.add(new BufferedInputStream(new FileInputStream(new File(this.blockPath.get(i)))));
		}
		sis=new SequenceInputStream(vi.elements());//正好是enumeration类型对接
		byte[] flush=new byte[1024];
		int len=0;
		while (-1!=(len=sis.read(flush))) {
			bos.write(flush);
		}
		bos.flush();
	}
IO流总结:

字节流:::可以处理一切纯文本,音频,视频

输入流:InputStream   FileInputStream   ByteArrayInputStream

操作:read(字节数组)




线程::::::

在JAVA中实现多线程的是java.lang.Thread类,可以通过创建Thread类的实例来创建新的线程,每个线程都是通过某个特定Thread对象的对应run方法来完成其操作,方法run()称为线程体。通过调用thread类的start方法来启动一个线程。

线程创建的第一种方式:继承Thread类:

package basic;
/**
 * 模拟龟兔赛跑,创建多线程,继承Thread,重写run方法
 * 使用线程:
 * 创建子类对象,调用对象的start方法
 * */
public class Rabbit extends Thread {
	@Override
	public void run() {
		for (int i = 0; i < 100; i++) {
			System.out.println("兔子跑了"+i+"步");
		}
	}

}
class wugui extends Thread {
	@Override
	public void run() {
		for (int i = 0; i < 100; i++) {
			System.out.println("乌龟跑了"+i+"步");
		}
	}

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

		Rabbit rabbit = new Rabbit();
		wugui wu = new wugui();
		rabbit.start();// 不要调用run方法,run是普通的方法,start为启动一个线程。
		wu.start();

		for (int i = 0; i < 100; i++) {
			System.out.println("主线程执行了");
		}
	}
静态代理模式:::

继承Thread类方式的缺点,那就是如果我们的类已经从一个类继承,则无法再继承Thread类。

通过Runnable接口实现多线程。避免单继承,方便共享资源,同一份资源多个代理访问。

public class Basic {
	@SuppressWarnings("unchecked")
	public static void main(String[] args) {

		marry y=new you();//创建真实角色
		WeddingCompany w=new WeddingCompany(y);//代理角色,持有真实角色的引用
		w.marry();//执行任务
	}
}

// 静态代理模式
/*
 * 实现同一个接口,
 * 真实角色
 * 代理角色
 * */
interface marry {
	void marry();
}

class you implements marry {
	public void marry() {
	}
}

class WeddingCompany implements marry {
	private marry you;

	public void before() {
	}

	public void marry() {
		before();
		you.marry();
		after();
	}

	public void after() {
	}

	public WeddingCompany(basic.marry you) {
		super();
		this.you = you;
	}

	public WeddingCompany() {
		super();
	}

}
Runnable接口就是一个静态代理的例子,Thread类实现了Runnable接口。我们也只要实现Runnable接口,这样便可以了。

/*
 * 使用runnable接口创建线程
 * 启动多线程,使用静态代理。
 * 创建真实角色,创建代理角色加上对真实角色的引用。调用start方法。
 * */
public class Programmer implements Runnable {

	@Override
	public void run() {
		// TODO Auto-generated method stub
		for (int i = 0; i < 1000; i++) {
			System.out.println("一边打架....");
		}
	}

}
public static void main(String[] args) {
Programmer pro=new Programmer();//创建真实角色
Thread thread=new Thread(pro);//创建代理角色
thread.start();//启动线程
for (int i = 0; i < 100; i++) {
System.out.println("一边聊QQ");
}
}

线程创建之三:

通过Callable接口实现:

public class Basic {
	@SuppressWarnings("unchecked")
	public static void main(String[] args) throws Exception, Exception {
		//创建线程
		ExecutorService e=Executors.newFixedThreadPool(1);
		Race race=new Race();
		Future<Integer> future=e.submit(race);
		int num=future.get();
		System.out.println(num);
		e.shutdown();//停止服务
		}
	}
/*
 * 使用callable接口
 * Callable接口可以对外声明异常,同时可以返回值。而runnable接口不可以。
 * */
class Race implements Callable<Integer>{

	@Override
	public Integer call() throws Exception {
		// TODO Auto-generated method stub
		return 1000;
	}
	
}
创建callable实现类,重写call方法。

借助 执行调度服务 ExecutorService获取Future对象。

4.线程状态与停止线程


新生状态,就绪状态,运行状态,就绪状态,死亡状态。

5.线程阻塞:

join:合并线程.....等待该线程终止

public class Basic {
	@SuppressWarnings("unchecked")
	public static void main(String[] args) throws Exception, Exception {
		Race race=new Race();
		Thread t=new Thread(race);//新生状态
		t.start();//就绪状态
		for (int i = 0; i < 1000; i++) {
			if (50==i) {
				t.join();
			}
			System.out.println("主线程"+i);
		}
		}
	}
class Race extends Thread{
	@Override
	public void run() {
		// TODO Auto-generated method stub
		for (int i = 0; i < 1000; i++) {
			System.out.println("race"+i);
		}
	}
}


yield:暂定当前正在执行的线程。并执行其它线程。
			if (50==i) {
				Thread.yield();//静态方法,写在哪个线程中就是暂停哪个线程。
			}
sleep()方法,在指定的毫秒数内让当前正在执行的线程休眠,静态方法……每一个对象都有一把锁,sleep休眠的时候不会释放锁。

sleep()两种场景:一是模拟倒计时,二是模拟网络延时。

public class Basic {
	@SuppressWarnings("unchecked")
	public static void main(String[] args) throws Exception, Exception {
		//倒计时,倒数十个数,一秒打印一个
		int num=10;
		while (true) {
			System.out.println(num--);
			Thread.sleep(1000);
			if(num<=0)
			break;
		}
		}
	public static void test1(){
		//倒计时
		Date endTime=new Date(System.currentTimeMillis()+10*10000);
		long end=endTime.getTime();
		while (true) {
			System.out.println(new SimpleDateFormat("mm:ss").format(endTime));
			endTime=new Date(endTime.getTime()-1000);//减去1秒
			Thread.sleep(1000);
			if(end-10000>endTime.getTime()){
				break;
			}
		}
	}
	public static void test2() {
		int num=40;
		//模拟网络延时
		//多线程中造成的资源冲突与并发问题。
		//三个代理抢票,有可能抢到0,-1张票。
		while(true){
			if(num<=0)
				break;
			try {
				Thread.sleep(2000);
			} catch (Exception e) {
				// TODO: handle exception
			}
			System.out.println(Thread.currentThread().getName()+"抢到了"+num--);
		}
	}
}

线程基本信息,优先级:::

	public static void main(String[] args) throws Exception, Exception {
	
		Programmer programmer=new Programmer();
		Thread thread=new Thread(programmer,"线程名称");
		System.out.println(thread.getName());
		
		thread.setName("纯种名称人");
		System.out.println(thread.getName());
		
		System.out.println(Thread.currentThread().getName());//输出main线程的名称
		thread.start();
		System.out.println(thread.isAlive());//线程是否存活,调用start之后才开始执行该线程.
		
		//优先级代表的是概率,不是绝对的优先级,没有先后的顺序。
		thread.setPriority(Thread.MAX_PRIORITY);
		thread.setPriority(Thread.MIN_PRIORITY);
		thread.setPriority(Thread.NORM_PRIORITY);
		
		}
线程的同步(并发)::::存在多个线程访问同一份资源。必须确保这份资源安全。

synchronized-=------>线程同步。

同步块:

synchronized(引用类型|this|类.class){}用的最多的还是锁定对象。this

//同步包括:1.同步块,2.同步方法。
//在方法名前面加上synchronized关键字即可。

单例设计模式:确保一个类只有一个对象。

//确保一个类只有一个对象
class Jvm{
	//构造器私有化,避免外部直接创建对象
	private Jvm(){}
	//声明一个静态变量 
	private static Jvm instance=null;
	//创建一个对外的公共静态方法访问该变量,如是该变量没有对象,创建该对象。
	public static Jvm of(){
		if(null==instance)
			instance=new Jvm();
		return instance;
	}
}
public class Basic  {
	@SuppressWarnings("unchecked")
	public static void main(String[] args) throws Exception, Exception {
		//线程同步,关键字:synchronized
		//同步包括:1.同步块,2.同步方法。
		//在方法名前面加上synchronized关键字即可。
		Jvm jvm1=Jvm.of();
		Jvm jvm2=Jvm.of();
		System.out.println(jvm1);
		System.out.println(jvm2);//在单线程模式下两个地址是一样。但多线程模式下就不一定了。多线程有可能不安全。
		//因为多线程下访问的是同一份资源。同一个对象。
		//第一种方法前加synchronized
		//第二种方法同步块:::
		
		//单例 应用:Runtime
		
		}

}
//确保一个类只有一个对象,单例 设计模式
class Jvm{
	//构造器私有化,避免外部直接创建对象
	private Jvm(){}
	//声明一个静态变量 
	private static Jvm instance=null;
	//创建一个对外的公共静态方法访问该变量,如是该变量没有对象,创建该对象。
	public static synchronized Jvm of(){//最简单的方式应对多线程
		if(null==instance)
			instance=new Jvm();
		return instance;
	}
	public static Jvm of2(){//同步块方式 ,经典的double checking双重检查。
		if(null==instance){//提高已经存在对象的访问效率
		synchronized (Jvm.class) {//锁定该类的字节码文件.
			if(null==instance)//安全
				instance=new Jvm();	
		}
		}
		return instance;
	}
}
//单例创建的其它方式
//
class Jvm2{
	private Jvm2(){}
	private static Jvm2 instance=new Jvm2();//类加载时创建
	public static Jvm2 getJvm(){
		return instance;//肯定是安全的
	}
}
//单例创建的其它方式
//为了提高效率的另一种写法。类在使用的时候才会加载。
class Jvm3{
	private Jvm3(){}
	private static class JVMHolder{//延缓了加载时机,当使用到这个实例 时才加载。若不访问,则无需加载。
	private static Jvm3 instance=new Jvm3();
	public static Jvm3 getJvm(){
		return instance;//肯定是安全的
	}
	}
}
设计模式之单例……
死锁::过多的同步方法造成死锁。容易造成死锁,不一定会死锁。

生产者消费者模式,信号灯法:解决多线程容易死锁的一个方案。不属于设计模式。

//一个场景,共同的资源。wait()等待会释放锁,与sleep不同。
//flag=true,生产者生产,消费者等待,生产完成后通知消费者。
//flag=false,生产者等待,消费者消费,消费完后通知生产者。
class Movie{
	private String picString;
	private boolean flag=true;
	
	public synchronized void play(String pic) throws Exception{
		if(!flag){
			this.wait();//生产者等待
		}
		Thread.sleep(500);//开始生产
		this.picString=pic;//生产完毕
		this.notify();//通知消费
		this.flag=false;
	}
	
	public synchronized void watch() throws Exception{
		if(flag){
			this.wait();
		}
		Thread.sleep(500);
		System.out.println(picString);
		this.notifyAll();
		this.flag=true;
	}
}
::::::::::::::::::

wait()与notify()方法一定要与同步在一起使用,没有同步,则无法等待。与synchronized一起使用。

任务调度:

Timer定时器类

TimerTask任务类

通过java Timer,TimerTask:(spring的任务调度就是通过它们实现的)

Timer实现的是类似闹钟的功能,Timer类本身实现的就是一个线程,只是这个线程被用来调用其它线程。而TimerTask类是一个抽象类,该类实现了Runnable接口。

在实际应用中,一个Timer可以启动多个TimerTask实现的线程,但是多个线程之间会存在阻塞。所以如果多个线程之间需要完全独立运行的话,最好还是一个Timer启动一个TimerTask实现。

	public static void main(String[] args) throws Exception, Exception {
		//任务调度,可以自学一下quartz
		Timer timer=new Timer();
		timer.schedule(new TimerTask() {//安排在什么时候开始执行
			
			@Override
			public void run() {
				// TODO Auto-generated method stub
				System.out.println("aaa");
			}
		}, new Date(System.currentTimeMillis()+1000), 1000);
		
		}
网络编程::::

InetAddress,InetSocketAddress:
InetAddress:封装计算机的ip地址以及DNS.,没有端口。

InetSocketAddress包含了端口:

getHostAddress()返回IP地址……

getHostName()返回域 名,本机为计算机名。

InetAddress.getLocalHost();

InetAddress.getByName("ip地址|域 名")

	public static void main(String[] args) throws Exception, Exception {

		InetAddress addr = InetAddress.getLocalHost();
		System.out.println(addr.getHostAddress());// IP地址
		System.out.println(addr.getHostName());// 计算机名

		// 根据域 名得到InetAddress对象
		addr = InetAddress.getByName("www.163.com");
		System.out.println(addr.getHostAddress());// IP地址
		System.out.println(addr.getHostName());// 计算机名

		// 根据IP得到InetAddress对象
		addr = InetAddress.getByName("61.135.253.15");
		System.out.println(addr.getHostAddress());// IP地址
		System.out.println(addr.getHostName());// 计算机名,如果无法解析返回该IP地址。
		
		//
		InetSocketAddress isa=new InetSocketAddress("127.0.0.1",11111);
		System.out.println(isa.getHostName());
		System.out.println(isa.getPort());
		
	}
URL:指向互联网资源的指针。

URL类:创建:

	public static void main(String[] args) throws Exception, Exception {
		//绝对路径构建
		URL url=new URL("http://www.baidu.com:80/index.html#aa?uname=bjsxt");
		System.out.println(url.getProtocol());//协义
		System.out.println(url.getPort());//端口
		System.out.println(url.getHost());//域名
		System.out.println(url.getFile());//资源
		System.out.println(url.getPath());//相对路径
		System.out.println(url.getRef());//锚点
		System.out.println(url.getQuery());//参数,存在锚点即为空。如果不存在返回正确。
		//相对路径构建
		url=new URL("http://www.baidu.com:80/");
		url=new URL(url,"b.html");
		url=new URL("http://www.baidu.com");//访问主页
		//获取资源
		InputStream is=url.openStream();
		byte[] flush=new byte[1024];
		int len=0;
		while(-1!=(len=is.read(flush))){
			//System.out.println(new String(flush));中文 乱码
		}
		//使用转换流解码
		BufferedReader br=new BufferedReader(new InputStreamReader(url.openStream(),"utf-8"));
		BufferedWriter bw=new BufferedWriter(new OutputStreamWriter(new FileOutputStream(new File("E:/a/b.html")),"utf-8"));
		String msg=null;
		while((msg=br.readLine())!=null){
			System.out.println(msg);
			bw.append(msg);
			bw.newLine();
		}
		bw.flush();
		bw.close();
		br.close();
	}
爬虫的基本原理:后期要用到正则表达式来做。
UDP通信:

客户端:

1.创建:DatagramSocket类+指定端口

2.准备数据,字节数组。

3.打包,DatagramPacket+服务器地址及端口。

服务器端:

1.创建DatagramSocket类+指定端口

2.准备接收容器,字节数组。封装DatagramPacket

3.包接收数据

4.分析并释放资源。

public class Basic {
	public static void main(String[] args) throws Exception, Exception {
		//创建服务端+端口
		DatagramSocket ds=new DatagramSocket(8888);
		//准备接收容器
		byte[] contains=new byte[1024];
		//datagrampacket
		DatagramPacket dp=new DatagramPacket(contains, contains.length);
		//接收数据
		ds.receive(dp);
		//分析数据
		byte[] data=dp.getData();
		int len=dp.getLength();
		System.out.println(new String(data, 0, len));
		//释放
		ds.close();
	}
}
public class MyClient {
	public static void main(String[] args) throws Exception {
		//创建客户端
		DatagramSocket ds=new DatagramSocket(6666);
		//准备数据
		String msg="udp编程";
		byte[] data=msg.getBytes();
		DatagramPacket dp=new DatagramPacket(data, data.length,new InetSocketAddress("127.0.0.1", 8888) );
		//打包
		ds.send(dp);
		ds.close();
	}
}
发送类型:double<->byte[]

	public static byte[] convert(double d) throws Exception{
		byte[] data = null;
		ByteArrayOutputStream bos=new ByteArrayOutputStream();
		DataOutputStream dos=new DataOutputStream(bos);
		dos.writeDouble(d);
		dos.flush();
		data=bos.toByteArray();
		dos.close();
		return data;
	}
public static double convert(byte[] data) throws Exception{
DataInputStream dis=new DataInputStream(new ByteArrayInputStream(data));
return dis.readDouble();
}

Socket编程:基于TCP

ServerSocket,Socket

public class Basic {
	public static void main(String[] args) throws Exception, Exception {
		//创建服务端,指定端口
		ServerSocket sever=new ServerSocket(8888);
		Socket socket=sever.accept();//接收客户端连接,阻塞式
		System.out.println("建立连接");
		//发送数据
		String msg="欢迎使用";
		BufferedWriter bw=new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));//DataoutputStream换
		bw.write(msg);
		bw.newLine();//加上,否则读取readLine的时候出错。
		bw.flush();
	}
	//创建客户端,必须指定服务器和端口。此时就在连接
	public static void name() throws Exception, Exception {
		Socket socket=new Socket("localhost",8888);//TCP客户端端口由系统分配
		BufferedReader br=new BufferedReader(new InputStreamReader(socket.getInputStream()));//换DataInputStream
		String msg=br.readLine();
		System.out.println(msg);
	}
	
}
这里连接的是一个客户端,如果连接多个客户端呢。?

public class Basic {
	public static void main(String[] args) throws Exception, Exception {
		//创建服务端,指定端口
		ServerSocket sever=new ServerSocket(8888);
		//死循环,多个客户端
		while(true){
		Socket socket=sever.accept();//接收客户端连接,阻塞式
		DataInputStream dis=new DataInputStream(socket.getInputStream());
		String msg=dis.readUTF();
		DataOutputStream dos=new DataOutputStream(socket.getOutputStream());
		dos.writeUTF("服务器端--->"+msg);
		dos.flush();
		}
	}
}
public class MyClient {
	public static void main(String[] args) throws Exception {
		Socket socket=new Socket("localhost",8888);//TCP客户端端口由系统分配
		
		DataOutputStream dos=new DataOutputStream(socket.getOutputStream());
		BufferedReader console=new BufferedReader(new InputStreamReader(System.in));
		dos.writeUTF(console.readLine());//从控制台读入一行
		dos.flush();
		DataInputStream dis=new DataInputStream(socket.getInputStream());
		System.out.println(dis.readUTF());
		
	}
	
}
聊天室之转发:

package basic;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.List;

public class Basic {
	private List<MyChannel> list = new ArrayList<>();
	public static void main(String[] args) throws Exception, Exception {
		new Basic().start();
	}
	public void start() throws IOException{
		//创建服务端,指定端口
		ServerSocket sever=new ServerSocket(8888);
		//死循环,多个客户端
		while(true){
		Socket socket=sever.accept();//接收客户端连接,阻塞式
		MyChannel myChannel=new MyChannel(socket);//成员内部类放在了静态方法中,会出错
		list.add(myChannel);
		new Thread(myChannel).start();
	}
}
	class MyChannel implements Runnable{
		private DataInputStream dis;
		private DataOutputStream dos;
		private boolean isRunning=true;
		public MyChannel(Socket socket){
			try {
				dis=new DataInputStream(socket.getInputStream());
				dos=new DataOutputStream(socket.getOutputStream());
			} catch (IOException e) {
				// TODO Auto-generated catch block
				//e.printStackTrace();
				isRunning=false;
				list.remove(this);
			}
			
		}
		public void run() {
			while (isRunning) {
				sendOthers();
			}
		}
		//发送给其它客户端
		public void sendOthers(){
			String msg=receive();
			for(MyChannel myChannel:list){
				if(myChannel==this)
					continue;
				//发送其它
				myChannel.send(msg);
			}
		}
		public String receive(){
			String msgString="";
			try {
				msgString=dis.readUTF();
			} catch (IOException e) {
				isRunning=false;
			}
			return msgString;
		}
		public void send(String msg){
			if(msg!=null&&!msg.equals("")){
				try {
					dos.writeUTF(msg);
					dos.flush();//强制刷新
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
	}

}
package basic;

import java.net.Socket;

//输入流与输出流在同一个线程内,应该独立出来。
public class MyClient {
	public static void main(String[] args) throws Exception {
		Socket socket=new Socket("localhost",8888);//TCP客户端端口由系统分配
		new Thread(new Send(socket)).start();//发送线程
		new Thread(new Receive(socket)).start();//接收线程
	}
	
}

package basic;
import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.Socket;

//发送数据线程
public class Send implements Runnable {

	private BufferedReader console;
	private DataOutputStream dos;
	
	public Send() {
		super();
		console=new BufferedReader(new InputStreamReader(System.in));
	}

	public Send(Socket client) throws IOException {
		this();
		this.dos = new DataOutputStream(client.getOutputStream());
	}

	@Override
	public void run() {
		// TODO Auto-generated method stub
		while (true) {
			send();
		}
	}
	public void send(){
		String msg=getStringFromConsole();
		if(msg!=null&&!msg.equals("")){
			try {
				dos.writeUTF(msg);
				dos.flush();//强制刷新
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}
	private String getStringFromConsole(){
		try {
			return console.readLine();
		} catch (IOException e) {
			return "";
		}
	}
}

package basic;

import java.io.DataInputStream;
import java.io.IOException;
import java.net.Socket;

//接收数据线程
public class Receive implements Runnable {

	private DataInputStream dis;
	private boolean isRunning=true;
	
	public Receive(Socket socket){
		try {
			dis=new DataInputStream(socket.getInputStream());
		} catch (IOException e) {
			isRunning=false;
		}
	}
	@Override
	public void run() {
		while(isRunning){
			System.out.println(receive());
		}
	}
	public String receive(){
		String msgString="";
		try {
			msgString=dis.readUTF();
		} catch (IOException e) {
			isRunning=false;
		}
		return msgString;
	}
}
私聊::

手写服务器:httpServer::::::::

前台表单中:name是给后台区分的,id是给前台区分的。

package basic;

import java.io.BufferedWriter;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Date;

//创建服务器,并启动
public class Basic {

	public static void main(String[] args) throws Exception, Exception {
		Basic basic=new Basic();
		basic.start();
	}
	//启动方法
	public void start(){	
		ServerSocket server;
		try {
			server = new ServerSocket(8888);
			receive(server);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

	}
	//接受客户端
	public void receive(ServerSocket server){
		try {
			Socket client=server.accept();
			String msg=null;//接收客户端的请求信息
			StringBuilder sb=new StringBuilder();
//			BufferedReader br=new BufferedReader(new InputStreamReader(client.getInputStream()));
//			while ((msg=br.readLine()).length()>0) {//使用readLine的话会出现问题,post的情况下.get情况下可以。因为post的数据中会有一个空行
//				sb.append(msg);
//				sb.append("\r\n");
//			}
			byte[] data=new byte[20480];
			int len=client.getInputStream().read(data);
			String requestInfo=new String(data,0,len).trim();
			
			System.out.println(requestInfo);
			//响应
			StringBuilder responseContext=new StringBuilder();
			responseContext.append("<html><head><title>che</title></head><body>cheaaa</body></html>");
			StringBuilder response=new StringBuilder();
			//http协议,状态码
			response.append("HTTP/1.1").append(BLANK).append("200").append(BLANK).append("ok").append(CRLF);
			//响应头
			response.append("Server:bjsss Server/1.1.1").append(CRLF);
			response.append("Date:").append(new Date()).append(CRLF);
			response.append("Content-type:text/html;charset=GBK").append(CRLF);
			//正文长度,字节长度
			response.append("Content-Length:").append(responseContext.toString().getBytes().length).append(CRLF);
			response.append(CRLF);
			response.append(responseContext);
			//输出
			BufferedWriter bw=new BufferedWriter(new OutputStreamWriter(client.getOutputStream()));
			System.out.println(response.toString());
			bw.write(response.toString());
			bw.flush();//造成别忘了使用
			bw.close();
		} catch (IOException e) {
			e.printStackTrace();
		}	
	}
	//停止
	public void stop(){
		
	}
	public static final String CRLF="\r\n";
	public static final String BLANK=" ";
}
HTTP中的响应分析:

最重要的两个:

Content-type:text/html;charset=GBK

                      text/plain;charset=GBK  纯文本

                     application/octet-stream 流的类型

借助于工具:HttpWatcherPro查看响应内容 IE浏览器。

封装Response::::

package basic;

import java.io.BufferedOutputStream;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.net.Socket;
import java.util.Date;

public class Response {

	private StringBuilder response;
	public static final String CRLF="\r\n";
	public static final String BLANK=" ";
	//正文长度
	private int len=0;
	//正文 
	private StringBuilder content;
	//构建流
	private BufferedWriter bw;
	public Response() {
		super();
		response=new StringBuilder();
		content=new StringBuilder();
	}
	public Response(OutputStream os) {
		super();
		response=new StringBuilder();
		content=new StringBuilder();
		bw=new BufferedWriter(new OutputStreamWriter(os));
	}
	public Response(Socket client) throws IOException {
		super();
		response=new StringBuilder();
		content=new StringBuilder();
		bw=new BufferedWriter(new OutputStreamWriter(client.getOutputStream()));
	}
	public void pushToClient(int code) throws IOException{
		createHeadInfo(code);
		bw.append(response);
		bw.append(content);
		bw.flush();
	}
	public void close(){
		try {
			bw.close();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	//构建正文
	public Response print(String content){
		this.content.append(content);
		len+=content.getBytes().length;
		return this;
	}
	public Response println(String content){
		this.content.append(content).append(CRLF);
		len+=(content+CRLF).getBytes().length;
		return this;
	}
	private void createHeadInfo(int code){
		//http协议,状态码
		response.append("HTTP/1.1").append(BLANK).append(code).append(BLANK);
		switch (code) {
		case 200:
			response.append("ok");
			break;
		case 404:
			response.append("not found");
		default:
			break;
		}
		response.append(CRLF);
		//响应头
		response.append("Server:bjsss Server/1.1.1").append(CRLF);
		response.append("Date:").append(new Date()).append(CRLF);
		response.append("Content-type:text/html;charset=GBK").append(CRLF);
		//正文长度,字节长度
		response.append("Content-Length:").append(len).append(CRLF);
		response.append(CRLF);
	}
	
}
封装request::::::

package basic;

import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.StringTokenizer;

public class Request {

	//请求方式
	private String method;
	//请求资源
	private String url;
	//请求参数
	private Map<String, List<String>> parameterMapValues;
	
	public static final String CRLF = "\r\n";
	public static final String BLANK = " ";
	
	private InputStream is;
	private String requestInfo;
	
	public Request(){
		method="";
		url="";
		parameterMapValues=new HashMap<String, List<String>>();
		requestInfo="";
	}
	public Request(InputStream is) {
		this();
		this.is=is;
		byte[] data=new byte[20480];
		int len=0;
		try {
			len = is.read(data);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		requestInfo=new String(data,0,len).trim();
		System.out.println(requestInfo);
		//分析头信息
		parseRequestInfo();
	}
	private void parseRequestInfo() {
		// TODO Auto-generated method stub
		if (null==requestInfo&&requestInfo.equals("")) {
			return;
		}
		//从信息的首行分解出请求方式,请求参数,请求路径
		String  paramString="";
		
		String firstLine=requestInfo.substring(0, requestInfo.indexOf(CRLF));
		int idx=firstLine.indexOf('/');
		this.method=firstLine.substring(0,idx-1);//获取方法,去掉后面那个空格
		String urlString=firstLine.substring(idx,firstLine.indexOf("HTTP/")).trim();
		System.out.println(urlString+" urlString");
		if (this.method.equalsIgnoreCase("post")) {
			this.url=urlString;
			paramString=requestInfo.substring(requestInfo.lastIndexOf(CRLF));
		}else if(this.method.equalsIgnoreCase("get")){
			System.out.println(urlString.contains("?"));
			if(urlString.contains("?")){
				String[] urlArray=urlString.split("\\?");//必须是\\,第一个是转\,第二个转?
				this.url=urlArray[0];
				System.out.println("aaa");
				paramString=urlArray[1];
			}else{
				this.url=urlString;
			}
		}
	}
	//将字符串转成map
	public void parseParams(String paramString){
		StringTokenizer tokenizer=new StringTokenizer(paramString, "&");
		while (tokenizer.hasMoreElements()) {
			String object = (String) tokenizer.nextElement();
			String[] keyValues=object.split("=");
			if(keyValues.length==1){
				keyValues=Arrays.copyOf(keyValues, 2);
				keyValues[1]=null;
			}
			String key=keyValues[0].trim();
			String value=null==keyValues[1]?null:decode(keyValues[1].trim(),"gbk");//中文解码 
			if(!parameterMapValues.containsKey(key)){//包含key
				parameterMapValues.put(key, new ArrayList<String>());
			}
			List<String> values=parameterMapValues.get(key);
			values.add(value);
		}
	}
	//根据页面name获取对应的多个值。
	public String[] getParamValues(String name){
		List<String> values=null;
		if((values=parameterMapValues.get(name))==null){
			return null;
		}else{
			return values.toArray(new String[0]);
		}
	}
	//根据页面name获取单个值
	public String getParamValue(String name){
		String[] values=getParamValues(name);
		if(null==values)
			return null;
		return values[0];
	}
	//解决中文
	public String decode(String value,String code){
		try {
			return java.net.URLDecoder.decode(value, code);
		} catch (UnsupportedEncodingException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return null;
	}
	@Override
	public String toString() {
		return "Request [method=" + method + ", url=" + url + ", parameterMapValues=" + parameterMapValues + ", is=" + is + "]";
	}
	
}

封装分发器:

package com.bjsxt.server.demo1;

import java.io.IOException;
import java.net.Socket;

import com.bjsxt.util.CloseUtil;

/**
 * 一个请求与响应 就一个此对象
 * @author Administrator
 *
 */
public class Dispatcher implements Runnable{
	private Socket client;
	private Request req;
	private Response rep;
	private int code=200;
	Dispatcher(Socket client){
		this.client=client;
		try {
			req =new Request(client.getInputStream());
			rep =new Response(client.getOutputStream());
		} catch (IOException e) {
			//e.printStackTrace();
			code =500;
			return ;
		}
	}
	
	
	
	
	
	@Override
	public void run() {
		Servlet serv =new Servlet();
		serv.service(req,rep); 				
		try {
			rep.pushToClient(code); //推送到客户端
		} catch (IOException e) {
			//e.printStackTrace();
			
		}	
		try {
			rep.pushToClient(500);
		} catch (IOException e) {
			e.printStackTrace();
		}
		CloseUtil.closeSocket(client);
	}

}

package com.bjsxt.server.demo1;

public class Servlet {
	public void service(Request req,Response rep){
		rep.println("<html><head><title>HTTP响应示例</title>");
		rep.println("</head><body>");
		rep.println("欢迎:").println(req.getParameter("uname")).println("回来");
		rep.println("</body></html>");
	}
}
多请求处理,多态::::::::::

package com.bjsxt.server.demo2;

import java.util.HashMap;
import java.util.Map;

/**
 * 上下文
 * @author Administrator
 *
 */
public class ServletContext {
	//为每一个servlet取个别名,Servlet是一个对象,这样可以节省资源。  
	// login  -->LoginServlet
	private Map<String,Servlet> servlet ;
	//url -->login
	//   /log -->login
	//   /login -->login
	private Map<String,String> mapping;
	
	ServletContext(){
		servlet =new HashMap<String,Servlet>();
		mapping =new HashMap<String,String>();
	}
	
	
	public Map<String, Servlet> getServlet() {
		return servlet;
	}
	public void setServlet(Map<String, Servlet> servlet) {
		this.servlet = servlet;
	}
	public Map<String, String> getMapping() {
		return mapping;
	}
	public void setMapping(Map<String, String> mapping) {
		this.mapping = mapping;
	}
	
	
	
	
}
package com.bjsxt.server.demo2;

import java.util.Map;

public class WebApp {
	private static ServletContext contxt;
	static{
		contxt =new ServletContext();
		
		Map<String,String> mapping =contxt.getMapping();
		mapping.put("/login", "login");
		mapping.put("/log", "login");
		mapping.put("/reg", "register");
		
		Map<String,Servlet> servlet =contxt.getServlet();
		servlet.put("login", new LoginServlet());
		servlet.put("register", new RegisterServlet());
	}
	
	public static Servlet getServlet(String url){
		if((null==url)||(url=url.trim()).equals("")){
			return null;
		}
		
		return contxt.getServlet().get(contxt.getMapping().get(url));
		
	}
}
package com.bjsxt.server.demo2;
/**
 * 抽象为一个父类
 * @author Administrator
 *
 */
public abstract class Servlet {
	public void service(Request req,Response rep) throws Exception{
		this.doGet(req,rep);
		this.doPost(req,rep);
	}
	
	public abstract void doGet(Request req,Response rep) throws Exception;
	public abstract void doPost(Request req,Response rep) throws Exception;
}
package com.bjsxt.server.demo2;

public class LoginServlet extends Servlet{

	@Override
	public void doGet(Request req,Response rep) throws Exception {
		String name = req.getParameter("uname");
		String pwd =req.getParameter("pwd");
		if(login(name,pwd)){
			rep.println("登录成功");
		}else{
			rep.println("登录失败");
		}
		
		
		
	}
	
	
	public boolean login(String name,String pwd){
		return name.equals("bjsxt") && pwd.equals("12346");
	}
	
	
	@Override
	public void doPost(Request req,Response rep) throws Exception {
		
	}

}
package com.bjsxt.server.demo2;

public class RegisterServlet extends Servlet{

	@Override
	public void doGet(Request req,Response rep) throws Exception {
		
	}
	
	
	@Override
	public void doPost(Request req,Response rep) throws Exception {
		rep.println("<html><head><title>返回注册</title>");
		rep.println("</head><body>");
		rep.println("你的用户名为:"+req.getParameter("uname"));
		rep.println("</body></html>");
	}

}

package com.bjsxt.server.demo2;

import java.io.IOException;
import java.net.Socket;

import com.bjsxt.util.CloseUtil;

/**
 * 一个请求与响应 就一个此对象
 * @author Administrator
 *
 */
public class Dispatcher implements Runnable{
	private Socket client;
	private Request req;
	private Response rep;
	private int code=200;
	Dispatcher(Socket client){
		this.client=client;
		try {
			req =new Request(client.getInputStream());
			rep =new Response(client.getOutputStream());
		} catch (IOException e) {
			//e.printStackTrace();
			code =500;
			return ;
		}
	}
	
	
	
	
	
	@Override
	public void run() {
		try {
			Servlet serv =WebApp.getServlet(req.getUrl());
			if(null==serv){
				this.code=404; //找不到处理
			}else{
				serv.service(req, rep);
			}
			rep.pushToClient(code); //推送到客户端
		}catch (Exception e) {
			e.printStackTrace();
			this.code=500;
		}	
		try {
			rep.pushToClient(500);
		} catch (IOException e) {
			e.printStackTrace();
		}
		req.close();
		rep.close();		
		CloseUtil.closeSocket(client);
	}
我们存的是一个servlet对象,在map中,存对象是很耗性能的,接下来就是要处理这个对象。

改成存字符串。

package com.bjsxt.server.demo3;

import java.util.HashMap;
import java.util.Map;

/**
 * 上下文
 * @author Administrator
 *
 */
public class ServletContext {
	//为每一个servlet取个别名  
	// login  -->com.bjsxt.server.demo03.LoginServlet
	private Map<String,String> servlet ;
	//url -->login
	//   /log -->login
	//   /login -->login
	private Map<String,String> mapping;
	
	ServletContext(){
		servlet =new HashMap<String,String>();
		mapping =new HashMap<String,String>();
	}
	
	
	public Map<String, String> getServlet() {
		return servlet;
	}
	public void setServlet(Map<String, String> servlet) {
		this.servlet = servlet;
	}
	public Map<String, String> getMapping() {
		return mapping;
	}
	public void setMapping(Map<String, String> mapping) {
		this.mapping = mapping;
	}
	
	
	
	
}
反射::::::

package com.bjsxt.server.demo3;

import java.util.Map;

public class WebApp {
	private static ServletContext contxt;
	static{
		contxt =new ServletContext();
		
		Map<String,String> mapping =contxt.getMapping();
		mapping.put("/login", "login");
		mapping.put("/log", "login");
		mapping.put("/reg", "register");
		
		Map<String,String> servlet =contxt.getServlet();
		servlet.put("login", "com.bjsxt.server.demo3.LoginServlet");
		servlet.put("register", "com.bjsxt.server.demo3.RegisterServlet");
	}
	
	public static Servlet getServlet(String url) throws InstantiationException, IllegalAccessException, ClassNotFoundException{
		if((null==url)||(url=url.trim()).equals("")){
			return null;
		}
		//根据字符串(完整路径)创建对象
		
		//return contxt.getServlet().get(contxt.getMapping().get(url));
		String name=contxt.getServlet().get(contxt.getMapping().get(url));
		return (Servlet)Class.forName(name).newInstance();//确保空构造存在
	}
}
public class Demo01 {
	public static void main(String[] args) throws ClassNotFoundException {
		String  str ="abc";
		//Class对象
		//对象.getClass()
		Class<?> clz =str.getClass();
		//类.class
		clz =String.class;
		//完整路径
		clz=Class.forName("java.lang.String");
		
	}
}
	public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException {
		Class<?> clz =Class.forName("com.bjsxt.server.demo03.LoginServlet");
		// 调用空构造 确保空构造存在
		Servlet ser=(Servlet)clz.newInstance(); 
		//retrun ser;
	}

}
修改配置::加入配置文件:::::

web.xml

<?xml version="1.0" encoding="UTF-8"?>

 <web-app>
	 <servlet>
	 	<servlet-name>login</servlet-name>
	 	<servlet-class>com.bjsxt.server.demo4.LoginServlet</servlet-class>
	 </servlet>
	 <servlet-mapping>
	 	<servlet-name>login</servlet-name>
	 	<url-pattern>/login</url-pattern> 
	 	<url-pattern>/g</url-pattern> 
	 </servlet-mapping>	 
	  <servlet>
	 	<servlet-name>reg</servlet-name>
	 	<servlet-class>com.bjsxt.server.demo4.RegisterServlet</servlet-class>
	 </servlet>
	 
	 <servlet-mapping>
	 	<servlet-name>reg</servlet-name>
	 	<url-pattern>/reg</url-pattern> 
	 </servlet-mapping>
 </web-app>


<?xml version="1.0" encoding="UTF-8" ?>
<persons>
	<person>
		<name>至尊宝</name>
		<age>9000</age>
	</person>
	<person>
		<name>白晶晶</name>
		<age>7000</age>
	</person>
</persons>
package com.bjsxt.xml;

public class Person {
	private String name;
	private int age;

	public Person() {
		// TODO Auto-generated constructor stub
	}

	public Person(String name, int age) {
		super();
		this.name = name;
		this.age = age;
	}

	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;
	}

}

package com.bjsxt.xml;

import java.io.IOException;
import java.util.List;

import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;

import org.xml.sax.SAXException;

public class ParseDemo01 {

	/**
	 * @param args
	 * @throws SAXException 
	 * @throws ParserConfigurationException 
	 * @throws IOException 
	 */
	public static void main(String[] args) throws ParserConfigurationException, SAXException, IOException {
		//1、获取解析工厂
		SAXParserFactory factory=SAXParserFactory.newInstance();
		//2、从解析工厂获取解析器
		SAXParser parse =factory.newSAXParser();
		//3、加载文档 Document 注册处理器
		//4、编写处理器
		PersonHandler handler=new PersonHandler();
		parse.parse(Thread.currentThread().getContextClassLoader()
				.getResourceAsStream("com/bjsxt/xml/person.xml")
				,handler );
		
		List<Person> persons =handler.getPersons();
		for(Person p:persons){
			System.out.println(p.getName()+"-->"+p.getAge());
		}
		
	}

}

package com.bjsxt.xml;

import java.util.ArrayList;
import java.util.List;

import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
/**
 * 存储对象
 * @author Administrator
 *
 */
public class PersonHandler extends DefaultHandler {
	private List<Person> persons;
	private Person person;
	private String tag;//记录标签名
	@Override
	public void startDocument() throws SAXException {
		// TODO Auto-generated method stub
		//System.out.println("处理文档开始");
		persons =new ArrayList<Person>();
	}
	@Override
	public void startElement(String uri, String localName, String qName,
			Attributes attributes) throws SAXException {
		System.out.println("开始一个元素" +qName);
		if(null!=qName){
			tag=qName;
		}
		if(null!=qName &&qName.equals("person")){
			person =new Person();
		}
	}

	
	
	@Override
	public void characters(char[] ch, int start, int length)
			throws SAXException {
		String str =new String(ch,start,length);
		if(null!=tag &&tag.equals("name")){
			//System.out.println(new String(ch,start,length));
			person.setName(str);
		}else if(null!=tag &&tag.equals("age")){
			Integer age = Integer.valueOf(str);
			person.setAge(age);
		}
	}
	
	@Override
	public void endElement(String uri, String localName, String qName)
			throws SAXException {
		//System.out.println("结束一个元素" +qName);
		if(qName.equals("person")){
			this.persons.add(person);
		}
		tag =null;
	}
	
	@Override
	public void endDocument() throws SAXException {
		System.out.println("文档处理结束");
	}
	public List<Person> getPersons() {
		return persons;
	}
	public void setPersons(List<Person> persons) {
		this.persons = persons;
	}

	
	

	
	

}



<?xml version="1.0" encoding="UTF-8"?>

 <web-app>
	 <servlet>
	 	<servlet-name>login</servlet-name>
	 	<servlet-class>com.bjsxt.server.demo4.LoginServlet</servlet-class>
	 </servlet>
	 <servlet-mapping>
	 	<servlet-name>login</servlet-name>
	 	<url-pattern>/login</url-pattern> 
	 	<url-pattern>/g</url-pattern> 
	 </servlet-mapping>	 
	  <servlet>
	 	<servlet-name>reg</servlet-name>
	 	<servlet-class>com.bjsxt.server.demo4.RegisterServlet</servlet-class>
	 </servlet>
	 
	 <servlet-mapping>
	 	<servlet-name>reg</servlet-name>
	 	<url-pattern>/reg</url-pattern> 
	 </servlet-mapping>
 </web-app>

package com.bjsxt.server.demo4;
/*  
 <servlet>
	 	<servlet-name>login</servlet-name>
	 	<servlet-class>com.bjsxt.server.demo4.LoginServlet</servlet-class>
	 </servlet> 
 */
public class Entity {
	private String name;
	private String clz;
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public String getClz() {
		return clz;
	}
	public void setClz(String clz) {
		this.clz = clz;
	}
	
}

package com.bjsxt.server.demo4;

import java.util.ArrayList;
import java.util.List;

/*
 <servlet-mapping>
	 	<servlet-name>login</servlet-name>
	 	<url-pattern>/login</url-pattern> 
	 </servlet-mapping>
	  <servlet-mapping>
	 	<servlet-name>login</servlet-name>
	 	<url-pattern>/log</url-pattern> 
	 </servlet-mapping>
 
  
 */
public class Mapping {
	private String name;
	private List<String> urlPattern;
	
	public Mapping(){
		urlPattern =new ArrayList<String>();
	}
	
	
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public List<String> getUrlPattern() {
		return urlPattern;
	}
	public void setUrlPattern(List<String> urlPattern) {
		this.urlPattern = urlPattern;
	}
	
	
	
}

package com.bjsxt.server.demo4;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;

import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;

public class WebHandler extends DefaultHandler{
	private List<Entity> entityList;
	private List<Mapping> mappingList;
	private Entity entity;
	private Mapping mapping;
	private String beginTag ;	
	private boolean isMap; 
	
	
 	@Override
	public void startDocument() throws SAXException {
		//文档解析开始
 		entityList =new ArrayList<Entity>() ;
 		mappingList =new ArrayList<Mapping>() ;
 		
	}
	@Override
	public void startElement(String uri, String localName, String qName,
			Attributes attributes) throws SAXException {
		//开始元素
		if(null!=qName){
			beginTag=qName;
			
			if(qName.equals("servlet")){
				isMap=false;
				entity=new Entity();
			}else if(qName.equals("servlet-mapping")){
				isMap=true;
				mapping=new Mapping();
			}		
			
		}
		
	}
	
	
	@Override
	public void characters(char[] ch, int start, int length)
			throws SAXException {
		//处理内容
		if(null!=beginTag){
			String str =new String(ch,start,length);
			if(isMap ){
				
				if(beginTag.equals("servlet-name")){
					mapping.setName(str);
				}else if(beginTag.equals("url-pattern")){
					mapping.getUrlPattern().add(str);
				}
			}else{
				if(beginTag.equals("servlet-name")){
					entity.setName(str);					
				}else if(beginTag.equals("servlet-class")){
					entity.setClz(str);
				}
			}
		}
	}

	@Override
	public void endElement(String uri, String localName, String qName)
			throws SAXException {
		//结束元素
		if(null!=qName){
			
			if(qName.equals("servlet")){
				entityList.add(entity);
			}else if(qName.equals("servlet-mapping")){
				mappingList.add(mapping);
			}
			
		}
		beginTag=null;
	}

	
	@Override
	public void endDocument() throws SAXException {
		//文档解析结束
	}

	
	public static void main(String[] args) throws ParserConfigurationException, SAXException, IOException {
		//获取解析工厂
		SAXParserFactory factory =SAXParserFactory.newInstance();
		//获取解析器
		SAXParser sax =factory.newSAXParser();
		//指定xml+处理器
		WebHandler web = new WebHandler();
		sax.parse(Thread.currentThread().getContextClassLoader()
				.getResourceAsStream("com/bjsxt/server/demo4/web.xml")
				,web);
		
		System.out.println(web.getEntityList());
	}
	public List<Entity> getEntityList() {
		return entityList;
	}
	public void setEntityList(List<Entity> entityList) {
		this.entityList = entityList;
	}
	public List<Mapping> getMappingList() {
		return mappingList;
	}
	public void setMappingList(List<Mapping> mappingList) {
		this.mappingList = mappingList;
	}
	
	
	

}
package com.bjsxt.server.demo4;

import java.util.List;
import java.util.Map;

import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;

public class WebApp {
	private static ServletContext contxt;
	static{
		try {
			//获取解析工厂
			SAXParserFactory factory = SAXParserFactory.newInstance();
			//获取解析器
			SAXParser sax = factory.newSAXParser();
			//指定xml+处理器
			WebHandler web = new WebHandler();
			sax.parse(Thread.currentThread().getContextClassLoader()
					.getResourceAsStream("com/bjsxt/server/demo4/web.xml"), web);
			
			
			//将list 转成Map
			contxt =new ServletContext();			
			Map<String,String> servlet =contxt.getServlet();
			
			//servlet-name  servlet-class 
			for(Entity entity:web.getEntityList()){
				servlet.put(entity.getName(), entity.getClz());
				
			}
			
			//url-pattern servlet-name			
			Map<String,String> mapping =contxt.getMapping();
			for(Mapping mapp:web.getMappingList()){
				List<String> urls =mapp.getUrlPattern();
				for(String url:urls ){
					mapping.put(url, mapp.getName());
				}
			}
			
		} catch (Exception e) {
			
		}
		
		
	}
	
	public static Servlet getServlet(String url) throws InstantiationException, IllegalAccessException, ClassNotFoundException{
		if((null==url)||(url=url.trim()).equals("")){
			return null;
		}
		//根据字符串(完整路径)创建对象
		
		//return contxt.getServlet().get(contxt.getMapping().get(url));
		String name=contxt.getServlet().get(contxt.getMapping().get(url));
		return (Servlet)Class.forName(name).newInstance();//确保空构造存在
	}
}
注解::::

/**
 * 测试内置注解用法
 * @author 尚学堂高淇
 *
 */
@SuppressWarnings("all")
public class Demo01  /*extends Object*/ {
	
	@Override
	public String toString(){
		return "";
	}

	@Deprecated
	public static void test001(){
		System.out.println("test001");
	}
	

	
	public static void test002(){
		List list = new ArrayList();
		List list2 = new ArrayList();
		
	}
	
	public static void main(String[] args) {
		Date d = new Date();
		test001();
	}
}
注解也是一个类,点进去可以查看。

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(value={CONSTRUCTOR, FIELD, LOCAL_VARIABLE, METHOD, PACKAGE, PARAMETER, TYPE})
public @interface Deprecated {
}


@SuppressWarnings

用来抑制编译时的警告信息,与前两个注释有所不同,你需要添加一个参数才能正确使用。这些参数都定义好的。

@SuppressWarnings("unchecked")

@SuppressWarnings("all")

自定义注解:::

元注解@Retention:

SOURCE:在源文件中有效

CLASS:在CLASS文件中有效

RUNTIME:在运行时有效,可被反射读取。

package basic;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target(value={ElementType.METHOD,ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface SxtAnnotation01 {
	
	String studentName() default "";
	int age() default 0;
	int id() default -1;   //String indexOf("abc")  -1
	
	String[] schools() default {"清华大学","北京上学堂"};
	
}

package basic;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target(value={ElementType.METHOD,ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface SxtAnnotation02 {
	String value();
}
/**
 * 测试自定义注解的使用
 *
 */
@SxtAnnotation01
public class Demo02 {
	
	@SxtAnnotation01(age=19,studentName="老高",id=1001,
			schools={"北京大学","北京航空航天大学"})
	public void test(){
	}
	
	@SxtAnnotation02("aaaa")
	public void test2(){
	}
	
}
田田田田田田田田田田田田田田田田田lll
@Target(value={ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
public @interface SxtField {
	String columnName();
	String type();
	int length();
}

@Target(value={ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface SxtTable {
	String value();
}
@SxtTable("tb_student")
public class SxtStudent {
	
	@SxtField(columnName="id",type="int",length=10)
	private int id;
	@SxtField(columnName="sname",type="varchar",length=10)
	private String studentName;
	@SxtField(columnName="age",type="int",length=3)
	private int age;
	
	
	public int getId() {
		return id;
	}
	public void setId(int id) {
		this.id = id;
	}
	public String getStudentName() {
		return studentName;
	}
	public void setStudentName(String studentName) {
		this.studentName = studentName;
	}
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
	
	
}
/**
 * 使用反射读取注解的信息,模拟处理注解信息的流程
 * @author 尚学堂高淇
 *
 */
public class Demo03 {
	
	public static void main(String[] args) {
		try {
			Class clazz = Class.forName("com.bjsxt.test.annotation.SxtStudent");
			
			//获得类的所有有效注解
			Annotation[] annotations=clazz.getAnnotations();
			for (Annotation a : annotations) {
				System.out.println(a);
			}
			//获得类的指定的注解
			SxtTable st = (SxtTable) clazz.getAnnotation(SxtTable.class);
			System.out.println(st.value());
			
			//获得类的属性的注解
			Field f = clazz.getDeclaredField("studentName");
			SxtField sxtField = f.getAnnotation(SxtField.class);
			System.out.println(sxtField.columnName()+"--"+sxtField.type()+"--"+sxtField.length());
			
			//根据获得的表名、字段的信息,拼出DDL语句,然后,使用JDBC执行这个SQL,在数据库中生成相关的表
			
		} catch (Exception e) {
			e.printStackTrace();
		}
		
	}
}

JAVA动态性之反射机制:reflection

JAVA的动态性:反射机制,动态编译,动态执行JAVASCRIPT代码。动态字节码操作。

package basic.bean;

public class User {
	
	private int id;
	private int age;
	private String uname;
	
	public int getId() {
		return id;
	}
	public void setId(int id) {
		this.id = id;
	}
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
	public String getUname() {
		return uname;
	}
	
	public void setUname(String uname) {
		this.uname = uname;
	}
	
	public void setUname() {
		this.uname = "高淇";
	}
	
	public User(int id, int age, String uname) {
		super();
		this.id = id;
		this.age = age;
		this.uname = uname;
	}
	
	//javabean必须要有无参的构造方法!
	public User() {
	}
}

/**
 * 测试各种类型(class,interface,enum,annotation,primitive type,void)对应的java.lang.Class对象的获取方式
 * @author 尚学堂高淇    www.sxt.cn
 *
 */
@SuppressWarnings("all")
public class Demo01 {
	
	public static void main(String[] args) {
		String path = "basic.bean.User";
		
		try {
			
			Class clazz = Class.forName(path);
			//对象是表示或封装一些数据。  一个类被加载后,JVM会创建一个对应该类的Class对象,类的整个结构信息会放到对应的Class对象中。
			//这个Class对象就像一面镜子一样,通过这面镜子我可以看到对应类的全部信息。
			System.out.println(clazz.hashCode());
			
			Class clazz2 = Class.forName(path);	//一个类只对应一个Class对象
			System.out.println(clazz2.hashCode());
			
			Class strClazz = String.class;
			Class strClazz2 = path.getClass(); 
			System.out.println(strClazz==strClazz2);//true
			
			Class intClazz =int.class;
			
			int[] arr01 = new int[10];
			int[][] arr02 = new int[30][3];
			int[] arr03 = new int[30];
			double[] arr04 = new double[10];
			
			System.out.println(arr01.getClass().hashCode());
			System.out.println(arr02.getClass().hashCode());
			System.out.println(arr03.getClass().hashCode());//与arr01相同
			System.out.println(arr04.getClass().hashCode());
			
			
		} catch (Exception e) {
			e.printStackTrace();
		}
		
	}
	
}
/**
 * 应用反射的API,获取类的信息(类的名字、属性、方法、构造器等)
 * @author 尚学堂高淇  www.sxt.cn
 *
 */
public class Demo02 {
	public static void main(String[] args) {
		String path = "basic.bean.User";
		
		try {
			Class clazz = Class.forName(path);
			
			//获取类的名字
			System.out.println(clazz.getName());//获得包名+类名:com.bjsxt.test.bean.User
			System.out.println(clazz.getSimpleName());	//获的类名:User
			
			//获取属性信息
//			Field[] fields = clazz.getFields(); //只能获得public的field
			Field[] fields = clazz.getDeclaredFields();//获得所有的field
			Field f = clazz.getDeclaredField("uname");
			System.out.println(fields.length);
			for(Field temp:fields){
				System.out.println("属性:"+temp);
			}
			//获取方法信息
			Method[] methods = clazz.getDeclaredMethods();
			Method m01 = clazz.getDeclaredMethod("getUname", null);
			//如果方法有参,则必须传递参数类型对应的class对象
			Method m02 = clazz.getDeclaredMethod("setUname", String.class); 
			for(Method m:methods){
				System.out.println("方法:"+m);
			}
			
			//获得构造器信息
			Constructor[] constructors = clazz.getDeclaredConstructors();
			Constructor c = clazz.getDeclaredConstructor(int.class,int.class,String.class);
			System.out.println("获得构造器:"+c);
			for(Constructor temp:constructors){
				System.out.println("构造器:"+temp);
			}
			
			
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}

/**
 * 通过反射API动态的操作:构造器、方法、属性
 * @author 尚学堂高淇 www.sxt.cn
 *
 */
public class Demo03 {
	public static void main(String[] args) {

		String path = "basic.bean.User";
		
		try {
			Class<User> clazz = (Class<User>) Class.forName(path);
			
			//通过反射API调用构造方法,构造对象
			User u = clazz.newInstance();	//其实是调用了User的无参构造方法
			System.out.println(u);
			
			Constructor<User> c = clazz.getDeclaredConstructor(int.class,int.class,String.class);
			User u2 = c.newInstance(1001,18,"高淇二");
			System.out.println(u2.getUname());
			
			//通过反射API调用普通方法
			User u3 = clazz.newInstance();
			Method method = clazz.getDeclaredMethod("setUname", String.class);
			method.invoke(u3, "高淇三");   //u3.setUname("高淇三");
			System.out.println(u3.getUname());
			
			//通过反射API操作属性
			User u4 = clazz.newInstance();
			Field f = clazz.getDeclaredField("uname");
			f.setAccessible(true); //这个属性不需要做安全检查了,可以直接访问
			f.set(u4, "高淇四");		//通过反射直接写属性
			System.out.println(u4.getUname());	//通过反射直接读属性的值
			System.out.println(f.get(u4));
			
			
		} catch (Exception e) {
			e.printStackTrace();
		}
	
		
	}
}

反射性能问题:

setAccessible:启用和禁用访问安全检查的开关,true表示取消安全访问检查。禁止安全检查,可以提高反射的效率。

可以考虑使用:cglib/javaassist

/**
 * 通过跳过安全检查,提高反射效率
 * 三种执行方法的效率差异比较
 * 
 * @author 尚学堂高淇 www.sxt.cn
 *
 */
public class Demo06 {
	
	public static void test01(){
		User u = new User();
		
		long startTime = System.currentTimeMillis();
		
		for (int i = 0; i < 1000000000L; i++) {
			u.getUname();
		}
		
		long endTime = System.currentTimeMillis();
		System.out.println("普通方法调用,执行10亿次,耗时:"+(endTime-startTime)+"ms"); 
	}
	
	public static void test02() throws Exception{
		User u = new User();
		Class clazz = u.getClass();
		Method m = clazz.getDeclaredMethod("getUname", null);
//		m.setAccessible(true);
		
		long startTime = System.currentTimeMillis();
		
		for (int i = 0; i < 1000000000L; i++) {
			m.invoke(u, null);
		}
		
		long endTime = System.currentTimeMillis();
		System.out.println("反射动态方法调用,执行10亿次,耗时:"+(endTime-startTime)+"ms");
	}
	
	public static void test03() throws Exception{
		User u = new User();
		Class clazz = u.getClass();
		Method m = clazz.getDeclaredMethod("getUname", null);
		m.setAccessible(true);	//不需要执行访问安全检查
		
		long startTime = System.currentTimeMillis();
		
		for (int i = 0; i < 1000000000L; i++) {
			m.invoke(u, null);
		}
		
		long endTime = System.currentTimeMillis();
		System.out.println("反射动态方法调用,跳过安全检查,执行10亿次,耗时:"+(endTime-startTime)+"ms");
	}
	
	
	public static void main(String[] args) throws Exception {
		test01();
		test02();
		test03();
	}
}

反身的效率大概是有30倍的差距。

反射操作泛型:

  • ParameterizedType: 表示一种参数化的类型,比如Collection<String>
  • GenericArrayType: 表示一种元素类型参数化类型或者类型变量数组类型
  • TypeVariable: 是各种类型变量公共父接口
  • WildcardType: 代表一种通配符类型表达式,比如?, ? extends Number, ? super Integer【wildcard是一个单词:就是“通配符”】
package basic;

import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.List;
import java.util.Map;

import basic.bean.User;

/**
 * 通过反射获取泛型信息
 * @author dell
 *
 */
public class Demo04 {
	
	public void test01(Map<String,User> map,List<User> list){
		System.out.println("Demo04.test01()");
	}
	
	public Map<Integer,User> test02(){
		System.out.println("Demo04.test02()");
		return null;
	}
	
	public static void main(String[] args) {

		try {
			
			//获得指定方法参数泛型信息
			Method m = Demo04.class.getMethod("test01", Map.class,List.class);
			Type[] t = m.getGenericParameterTypes();
			for (Type paramType : t) {
				System.out.println("#"+paramType);
				if(paramType instanceof ParameterizedType){
					Type[] genericTypes = ((ParameterizedType) paramType).getActualTypeArguments();
					for (Type genericType : genericTypes) {
						System.out.println("泛型类型:"+genericType);
					}
				}
			}
			
			//获得指定方法返回值泛型信息
			Method m2 = Demo04.class.getMethod("test02", null);
			Type returnType = m2.getGenericReturnType();
			if(returnType instanceof ParameterizedType){
					Type[] genericTypes = ((ParameterizedType) returnType).getActualTypeArguments();

					for (Type genericType : genericTypes) {
						System.out.println("返回值,泛型类型:"+genericType);
					}
					
			}
			
			
		} catch (Exception e) {
			e.printStackTrace();
		}
	
		
	
	}
}

/**
 * 通过反射获取注解信息
 * @author 尚学堂高淇
 *
 */
public class Demo05 {
	public static void main(String[] args) {

		try {
			Class clazz = Class.forName("com.bjsxt.test.annotation.SxtStudent");
			
			//获得类的所有有效注解
			Annotation[] annotations=clazz.getAnnotations();
			for (Annotation a : annotations) {
				System.out.println(a);
			}
			//获得类的指定的注解
			SxtTable st = (SxtTable) clazz.getAnnotation(SxtTable.class);
			System.out.println(st.value());
			
			//获得类的属性的注解
			Field f = clazz.getDeclaredField("studentName");
			SxtField sxtField = f.getAnnotation(SxtField.class);
			System.out.println(sxtField.columnName()+"--"+sxtField.type()+"--"+sxtField.length());
			
			//根据获得的表名、字段的信息,拼出DDL语句,然后,使用JDBC执行这个SQL,在数据库中生成相关的表
			
		} catch (Exception e) {
			e.printStackTrace();
		}
		
	
	}
}















































评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值