目录

Package Explorer目录

server包 

CloseUtil.java

 Dispatcher.java

Entity.java

Mapping.java

 Request.java

 Response.java

 Server.java

 ServletContext.java

 WebApp.java

WebHandler.java

servlet包

LoginServlet.java

RegisterServlet.java

 Servlet.java

WEB_INFO包

web.xml

 测试文件

text.html

 测试实例

补充相关姿势

get/post请求方式

 HTTP响应格式及相关

 多请求处理——反射

xml配置文件解析


Package Explorer目录

首先先看下我的Package Explorer,就是server这个java project,其中有三个包,分别是server、servlet、WEB_INFO,用途对应是服务器、实际业务、配置文件;

server包 

CloseUtil.java

按顺序来看,第一个为CloseUtil.java,该文件用于关闭文件

package server;

import java.io.Closeable;

public class CloseUtil {
	/**
	 * 关闭IO流
	 */
	 public static void closeAll(Closeable... io){
		 for(Closeable temp:io){
			 try {
				 if (null != temp) {
					 temp.close();
	             }
	         } catch (Exception e) {
	         
	         }
		 }
	 }

	/**
	 * 使用泛型方法实现关闭IO流
	 */
	public static <T extends Closeable> void closeIO(T ... io) {
		for(Closeable temp:io) {
			try {
				if(null != temp) {
					temp.close();
				}
			}catch(Exception e){
				
			}
		}
	}
}

 Dispatcher.java

package server;

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

import servlet.Servlet;

/**
 * 一个请求与相应 就一个此对象
 */
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) {
			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 {//500就再推一次
			rep.pushToClient(500);
		} catch (IOException e) {
			e.printStackTrace();
		}
        
        CloseUtil.closeAll(client);
	}
	
}

Entity.java

package server;
/*
 <servlet>
		<servlet-name>login</servlet-name>
		<servlet-class> server.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;
	}
	
}

Mapping.java

package server;

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

 Request.java

package server;

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;
  
/**
 * 封装request
 * @author DUGAN
 *
 */
public class Request {
       //请求方式
       private String method;
       //请求资源
       private String url;
       //请求参数
       private Map<String,List<String>> parameterMapValues;
       
       //内部
       public static final String CRLF="\r\n";
       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;
              try {
                     byte[] data = new byte[20480];
                     int len = is.read(data);
                     requestInfo = new String(data, 0, len);
              } catch (Exception e) {
                     return ;
              }
              //分析请求信息
              parseRequestInfo();
       }
       /**
        * 分析请求信息
        */
       private void parseRequestInfo(){
              if(null==requestInfo ||(requestInfo=requestInfo.trim()).equals("")){
                     return ;
              }           
              /**
               * =====================================
               * 从信息的首行分解出 :请求方式    请求路径   请求参数(get可能存在)
               *   如:GET /index.html?name=123&pwd=5456 HTTP/1.1
               * 
               * 如果为post方式,请求参数可能在 最后正文中
               * 
               * 思路:
               * 1)请求方式 :找出第一个/  截取即可
               * 2)请求资源:找出第一个/   HTTP/ 
               * =====================================
               */
              String paramString =""; //接收请求参数 
              
              //1、获取请求方式
              String firstLine =requestInfo.substring(0,requestInfo.indexOf(CRLF));
              int idx =requestInfo.indexOf("/"); // /的位置
              this.method=firstLine.substring(0, idx).trim();
              String urlStr =firstLine.substring(idx,firstLine.indexOf("HTTP/")).
              trim();
              if(this.method.equalsIgnoreCase("post")){
                     this.url=urlStr;           
                     paramString=requestInfo.substring(requestInfo.
                     lastIndexOf(CRLF)).trim();
                     
              }else if(this.method.equalsIgnoreCase("get")){
                     if(urlStr.contains("?")){ //是否存在参数
                            String[] urlArray=urlStr.split("\\?");
                            this.url=urlArray[0];
                            paramString=urlArray[1];//接收请求参数 
                     }else{
                            this.url=urlStr;                  
                     }
              }
              
              //不存在请求参数
              if(paramString.equals("")){
                     return ;
              }
              //2、将请求参数封装到Map中 
              parseParams(paramString);
       }
       private void parseParams(String paramString){
              //分割 将字符串转成数组
              StringTokenizer token=new StringTokenizer(paramString,"&");
              while(token.hasMoreTokens()){
                     String keyValue =token.nextToken();
                     String[] keyValues=keyValue.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");
                     //转换成Map 分拣
                     if(!parameterMapValues.containsKey(key)){
                            parameterMapValues.put(key,new ArrayList<String>());
                     }
                     List<String> values =parameterMapValues.get(key);
                     values.add(value);                    
              }           
              
       }
       /**
        * 解决中文
        * @param value
        * @param code
        * @return
        */
       private String decode(String value,String code){
              try {
                     return java.net.URLDecoder.decode(value, code);
              } catch (UnsupportedEncodingException e) {
                     //e.printStackTrace();
              }
              return null;
       }
       /**
        * 根据页面的name 获取对应的多个值
        * @param args
        */
       public String[] getParameterValues(String name){
              List<String> values=null;
              if((values=parameterMapValues.get(name))==null){
                     return null;
              }else{
                     return values.toArray(new String[0]);
              }
       }
       /**
        * 根据页面的name 获取对应的单个值
        * @param args
        */
       public String getParameter(String name){
              String[] values =getParameterValues(name);
              if(null==values){
                     return null;
              }
              return values[0];
       }
       public String getUrl() {
              return url;
       }
       
}

 Response.java

package server;

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

/**
 * 封装响应信息
 * @author 84079
 *
 */
public class Response {
	//两个常量
	public static final String CRLF="\r\n";
    public static final String BLANK=" ";
    //流
    private BufferedWriter bw;
    //正文
    private StringBuilder content;
    //存储头信息
	private StringBuilder headInfo;
	//存储正文长度
	private int len = 0;
	public Response() {
		headInfo = new StringBuilder();
		content = new StringBuilder();
		len = 0;
	}
	public Response(OutputStream os) {
		this();
		bw = new BufferedWriter(new OutputStreamWriter(os));
	}
	public Response(Socket client) {
		this();
		try {
			bw = new BufferedWriter(new OutputStreamWriter(client.getOutputStream()));
		} catch (IOException e) {
			headInfo = null;
		}
	}
	/*
	 * 构建正文
	 */
	public Response print(String info) {
		content.append(info);
		len+=info.getBytes().length;
		return this;
	}
	/**
	 * 构建正文+回车
	 */
	public Response println(String info) {
		content.append(info).append(CRLF);
		len+=(info+CRLF).getBytes().length;
		return this;
	}
	/**
	 * 构建响应头
	 */
	private void createHeadInfo(int code) {
		//1)  HTTP协议版本、状态代码、描述
		headInfo.append("HTTP/1.1").append(BLANK).append(code).append(BLANK);
		switch(code) {
		case 200:
			headInfo.append("OK");
		case 404:
			headInfo.append("NOT FOUND");
		case 500:
			headInfo.append("SEVER ERROR");
		}
		headInfo.append(CRLF);
        //2)  响应头(Response Head)
		headInfo.append("Server:bjsxt Server/0.0.1").append(CRLF);
		headInfo.append("Date:").append(new Date()).append(CRLF);
		headInfo.append("Content-type:text/html;charset=GBK").append(CRLF);
        //正文长度 :字节长度
		headInfo.append("Content-Length:").append(len).append(CRLF);
		headInfo.append(CRLF);//分隔符
	}
	//推送到客户端
	void pushToClient(int code) throws IOException {
		if(null==headInfo) {
			code = 500;
		}
		createHeadInfo(code);
		//头信息+分割符
		bw.append(headInfo.toString());
		//正文
		bw.append(content).toString();
		bw.flush();
	}
	public void close() {
		CloseUtil.closeIO(bw);
	}
}

 Server.java

package server;

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

/**
 * 创建服务器,并启动
 * 1.请求
 * 2.响应
 * @author DUGAN
 *
 */
public class Server {
	private ServerSocket server;
    public static final String CRLF="\r\n";
    public static final String BLANK=" ";
    
    private boolean isShutDown = false;

    public static void main(String[] args) {
    
           Server server = new Server();
           server.start();          
    }
    /**
     * 启动方法
     */
    public void start() {
    	start(8888);
    }
    /**
     * 指定端口的启动方法
     */
    public void start(int port){            
           try {
                  server = new ServerSocket(port);
                  this.receive();
           } catch (IOException e) {
                  stop();
           }
    }
    /**
     * 接收客户端
     */
    private void receive(){
    	try {
    		while(!isShutDown) {
    			new Thread(new Dispatcher(server.accept())).start();
    		}           
    	}catch(IOException e) {
    		stop();
    	}
    }
    
    /**
     * 停止服务器
     */
    public void stop(){
           isShutDown = true;
           CloseUtil.closeIO(server);
    }
    
    
}

 ServletContext.java

package server;

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

/**
 * 上下文
 * @author DUGAN
 *
 */
public class ServletContext {
	//为每个servlet取个别名
	//login --> server.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;
	}
	
	
}

 WebApp.java

package server;

import java.util.List;
import java.util.Map;
  
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;

import servlet.Servlet;
  
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("WEB_INFO\\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();//确保空构造存在
	}
}

WebHandler.java

package server;

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("server/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;
	}
}

servlet包

LoginServlet.java

package servlet;

import server.Request;
import server.Response;

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("<html><head><title>欢迎回来</title>");
			rep.println("</head><body>");
			rep.println("欢迎:").println(req.getParameter("uname")).println("回来");
			rep.println("</body></html>");
		}else {
			rep.print("登录失败");
		}
		
		
		
	}

	public boolean login(String name,String pwd) {
		return name.equals("DUGAN")&& pwd.equals("123456");
	}
	
	
	@Override
	public void doPost(Request req,Response rep) throws Exception {
		// TODO Auto-generated method stub
		
	}

}

RegisterServlet.java

package servlet;

import server.Request;
import server.Response;

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

}

 Servlet.java

package servlet;

import server.Request;
import server.Response;

/**
 * 抽象为一个父类
 * @author DUGAN
 *
 */
public abstract class Servlet {
	public void service(Request req,Response rep) throws Exception {
        this.doGet(req,rep);
        this.doPost(req,rep);
	}
	protected abstract void doGet(Request req,Response rep) throws Exception;
	protected abstract void doPost(Request req,Response rep) throws Exception;
	
}

WEB_INFO包

web.xml

<?xml version="1.0" encoding="UTF-8"?>
  
 <web-app>
 <servlet>
  <servlet-name>login</servlet-name>
  <servlet-class>servlet.LoginServlet</servlet-class>
 </servlet>
 <servlet-mapping>
  <servlet-name>login</servlet-name>
  <url-pattern>/login</url-pattern> 
  <url-pattern>/log</url-pattern> 
 </servlet-mapping>  
  <servlet>
  <servlet-name>reg</servlet-name>
  <servlet-class>servlet.RegisterServlet</servlet-class>
 </servlet>
 <servlet-mapping>
  <servlet-name>reg</servlet-name>
  <url-pattern>/reg</url-pattern> 
 </servlet-mapping>
 </web-app>

 测试文件

text.html

<html>
       <head>
              <title>登录</title>
       </head>
       <body>                
		<form method="post" action="http://localhost:8888/log">
             		用户名:<input type="text" name="uname" id="uname"/>
                    密码:<input type="password" name="pwd" id="pwd"/>
                    <input type="submit" value="登录"/>
              </form>
       </body>
</html>

 测试实例

首先启动server,(Server.java是main的入口,可以直接启动该文件),打开text.html

 因为在servlet包中的LoginServlet.java中设置了一个唯一正确的账号和密码

所以呢,如果你输入的账号秘密不这个,点击登录会显示

否则则会是这个的页面

 

补充相关姿势

get/post请求方式

<html>
	<head>
		<title>第一个表单</title>
	</head>
	<body>
		<pre>
              	method:请求方式 get/post  
                     get: 默认方式,数据量小,安全性不高
                     post:量大,安全性相对高
              	action:请求的服务器路径
              	id:编号,前端区分唯一性 ,js中使用
              	name:名称,后端(服务器)区分唯一性 ,获取值
              	只要提交数据给后台,必须存在name
		
        </pre>
            <form method="post/get" action="http://localhost:8888/index.html">
                     用户名:<input type="text" name="uname" id="uname"/>
                     密码:<input type="password" name="pwd" id="pwd"/>
            <input type="submit" value="登录"/>
            </form>
		
	</body>
</html>

post的请求方式:
POST /index.html HTTP/1.1
Accept: text/html, application/xhtml+xml, image/jxr, */*
Accept-Language: zh-CN
Content-Type: application/x-www-form-urlencoded
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/42.0.2311.135 Safari/537.36 Edge/12.10240
Accept-Encoding: gzip, deflate
Host: localhost:8888
Content-Length: 17
Connection: Keep-Alive
Cache-Control: no-cache

uname=123&pwd=123
====================================================================================================================
get的请求方式:
GET /index.html?uname=bjsxt&pwd=123456 HTTP/1.1
Accept: text/html, application/xhtml+xml, image/jxr, */*
Accept-Language: zh-CN
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/42.0.2311.135 Safari/537.36 Edge/12.10240
Accept-Encoding: gzip, deflate
Host: localhost:8888
Connection: Keep-Alive

 HTTP响应格式及相关

HTTP响应格式
三部分:
1)HTTP协议版本、状态代码、描述
2)响应头(Response Head)
3)响应正文(Response Content)
例子:
HTTP/1.1 200 OK
Server:Apache Tomcat/6.0.12
Date:Mon,6Pct2012 16:36:42 GMT
Content-type:text/html:charset=GBK
Content-Length:112

<html><head>
<title>HTTP响应实例<title>
</head>
<body>Hello Tomcat!</body>
</html>

常见响应HTTP应答码:
200 OK
404 资源不存在
500 服务器错误

常见类型
Content-type:text/html:charset=GBK   html
Content-type:text/plain:charset=GBK  纯文本
Content-type:text/cation:charset=GBK  下载 流

 多请求处理——反射

上述项目中运用到了反射的方法,这里用例子表示

package reflect;
/**
 * 获取结构信息Class对象(源头)
 * @author DUGAN
 *
 */
public class Demo01 {

	public static void main(String[] args) {
		String str = "abc";
		//Class对象
		//对象.getclass()
		Class<?> clz = str.getClass();
		//类.class
		clz = String.class;
		//完整路径
		try {
			clz = Class.forName("java.lang.String");
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}

	}

}
package reflect;

import server.Servlet;

/**
 * 常见实例 调用空构造
 * @author DUGAN
 *
 */
public class Demo02 {

	public static void main(String[] args) throws InstantiationException, IllegalAccessException, ClassNotFoundException {
		Class<?> clz = Class.forName("server.LoginServlet");
		//调用空构造 确保空构造存在
		Servlet ser = (Servlet) clz.newInstance();
		//return ser
	}

}

xml配置文件解析

同样也是个栗子

ParseDemo01.java

package 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("xml/person.xml")
				,handler );
 
		List<Person> persons =handler.getPersons();
		for(Person p:persons){
			System.out.println(p.getName()+"-->"+p.getAge());
		}
	}	
  
}

Person.java

package xml;

public class Person {
	private String name;
	private int age;
  
	public Person() {
 
	}
  
	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;
	}
}

 PersonHandler.java

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

person.xml

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