java22

public class Test {
    public static void main(String[] args) {
        Student s = new Student();
        Map<String,String> mapping = s.getMapping();
        mapping.put("/login", "login");
        mapping.put("/log", "login");
        mapping.put("/reg", "register");//这样这个s里面的mapping也有值了。
        Student s1 = s;
        s1.setName("ererer");//s里面的name也有值了。
        System.out.println(s.getName());//ererer
        System.out.println(s1 == s);//true
        Teacher t = s.getTeacher();//t和s里面的teacher是同一个,地址是相同的。
        t.setName("teacher");
        t.setId("eee");//这样这个s里面的teacher也有值了。
        System.out.println(s.getTeacher().getName());
        System.out.println(s.getTeacher().getId());
        System.out.println(t==s.getTeacher());//true
    }

    
服务器新版本:
/**
 * 创建服务器,并启动
 * 
 * 1、请求
 * 2、响应
 */
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.closeSocket(server);
    }
}


/**
 * 一个请求与响应 就一个此对象
 */
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());//用到此处的WebApp时会去加载WebApp的静态代码快。
            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);
    }
}



public class WebApp {
    private static ServletContext contxt;
    static{
        contxt = new ServletContext();
        
        Map<String,String> mapping = contxt.getMapping();
        mapping.put("/login", "login");//这样这个context里面的mapping也有了。
        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));
    }
}


/**
 * 上下文,就是一个容器。
 */
public class ServletContext {
    //为每一个servlet取个别名 ,login的Servlet名字为 LoginServlet
    private Map<String,Servlet> servlet;
    //url -->servlet的名字,例如/log -->login、/login -->login
    //由于多个路径可能对应一个Servlet,为了避免代码的重复所以要用一个map来存储Servlet和Servlet的名字。否则多个路径对应一个Servlet也写在这里,而对象占用的内存大也会很耗内存。
    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;
    }
}


/**
 * 抽象为一个父类
 */
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;
}




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

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


/**
 * 封装request
 * 处理请求信息
 *
 */
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;
    }
    
    public void close(){
        CloseUtil.closeIO(is);
    }
}



/**
 * 封装响应信息
 * 组装一个符合http规范的字符串然后推出到浏览器
 *
 */
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(Socket client){
        this();
        try {
            bw= new BufferedWriter(new OutputStreamWriter(client.getOutputStream()));
        } catch (IOException e) {
            headInfo=null;
        }
    }
    public Response(OutputStream os){
        this();
        bw= new BufferedWriter(new OutputStreamWriter(os));
    }
    /**
     * 构建正文
     */
    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");
                break;
            case 404:
                headInfo.append("NOT FOUND");
                break;
            case 505:
                headInfo.append("SEVER ERROR");
                break;    
        }
        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);
    }
}





反射
-动态语言:在运行期间随意的改变对象的类型+结构 ,例如ruby js
-Java不是动态语言,但具有动态属性(反射)
1.反射 镜子(反射理解为保留了类的字节码信息,)
1)原来是在编译的时候创建对象,现在是在运行的时候创建对象,
2)jvm在创建的时自动生成与之对应的Class对象,同一个类的多个对象在jvm只有一个对应的class文件。
2.Class
1)可以看成类的元数据,每一个对象在创建是jvm会自动生成与之对应的Class,同类型的对象对应一个Class。
2)获取Class对象的3种方式:对象.getClass()、类.class(Student.class)、Class.forName("完整类名")。



/**
 * 获取结构信息Class对象(源头)
 */
public class Demo01 {
    public static void main(String[] args) throws ClassNotFoundException {
        String  str ="abc";
        //Class对象
        //对象.getClass()
        Class<?> clz =str.getClass();//class java.lang.String
        //类.class
        clz =String.class;//class java.lang.String
        //完整路径
        clz=Class.forName("java.lang.String");//class java.lang.String
    }
}



/**
 * 创建实例  调用空构造
 */
public class Demo02 {
    public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException {
        Class<?> clz =Class.forName("com.bjsxt.server.demo3.LoginServlet");//clz=class com.bjsxt.server.demo3.LoginServlet
        // 调用空构造 确保空构造存在
        Servlet ser=(Servlet)clz.newInstance(); //返回Object,会有强制类型转换,ser=com.bjsxt.server.demo3.LoginServlet@a61164
        //retrun ser;
    }
}




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;
        }
        //根据字符串(类完整路径)创建对象
        
        String name=contxt.getServlet().get(contxt.getMapping().get(url));
        return (Servlet)Class.forName(name).newInstance();//确保空构造存在
    }
}

 

posted @ 2015-09-23 21:57  无天666  阅读(417)  评论(0编辑  收藏  举报