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();//确保空构造存在 } }