public classTest {public static voidmain(String[] args) {
Student s= newStudent();
Map 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 classServer {privateServerSocket server;public static final String CRLF="\r\n";public static final String BLANK=" ";private boolean isShutDown= false;public static voidmain(String[] args) {
Server server= newServer();
server.start();
}/**
* 启动方法*/
public voidstart(){
start(8888);
}/**
* 指定端口的启动方法*/
public void start(intport){try{
server= newServerSocket(port);this.receive();
}catch(IOException e) {
stop();
}
}/**
* 接收客户端*/
private voidreceive(){try{while(!isShutDown){new Thread(newDispatcher(server.accept())).start();
}
}catch(IOException e) {
stop();
}
}/**
* 停止服务器*/
public voidstop(){
isShutDown=true;
CloseUtil.closeSocket(server);
}
}/**
* 一个请求与响应 就一个此对象*/
public classDispatcher implements Runnable{privateSocket client;privateRequest req;privateResponse rep;private int code=200;
Dispatcher(Socket client){this.client=client;try{
req=newRequest(client.getInputStream());
rep=newResponse(client.getOutputStream());
}catch(IOException e) {
code=500;return;
}
}
@Overridepublic voidrun() {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 classWebApp {private staticServletContext contxt;static{
contxt= newServletContext();
Map mapping =contxt.getMapping();
mapping.put("/login", "login");//这样这个context里面的mapping也有了。
mapping.put("/log", "login");
mapping.put("/reg", "register");
Map servlet =contxt.getServlet();
servlet.put("login", newLoginServlet());
servlet.put("register", newRegisterServlet());
}public staticServlet getServlet(String url){if((null == url)||(url = url.trim()).equals("")){return null;
}return contxt.getServlet().get(contxt.getMapping().get(url));
}
}/**
* 上下文,就是一个容器。*/
public classServletContext {//为每一个servlet取个别名 ,login的Servlet名字为 LoginServlet
private Mapservlet;//url -->servlet的名字,例如/log -->login、/login -->login//由于多个路径可能对应一个Servlet,为了避免代码的重复所以要用一个map来存储Servlet和Servlet的名字。否则多个路径对应一个Servlet也写在这里,而对象占用的内存大也会很耗内存。
private Mapmapping;
ServletContext(){
servlet=new HashMap();
mapping=new HashMap();
}public MapgetServlet() {returnservlet;
}public void setServlet(Mapservlet) {this.servlet =servlet;
}public MapgetMapping() {returnmapping;
}public void setMapping(Mapmapping) {this.mapping =mapping;
}
}/**
* 抽象为一个父类*/
public abstract classServlet {public voidservice(Request req,Response rep) throws Exception{this.doGet(req,rep);this.doPost(req,rep);
}public abstract voiddoGet(Request req,Response rep) throws Exception;public abstract voiddoPost(Request req,Response rep) throws Exception;
}public classLoginServlet extends Servlet{
@Overridepublic voiddoGet(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("登录失败");
}
}publicboolean login(String name,String pwd){return name.equals("bjsxt") && pwd.equals("12346");
}
@Overridepublic voiddoPost(Request req,Response rep) throws Exception {
}
}public classRegisterServlet extends Servlet{
@Overridepublic voiddoGet(Request req,Response rep) throws Exception {
}
@Overridepublic voiddoPost(Request req,Response rep) throws Exception {
rep.println("
返回注册");rep.println("
");rep.println("你的用户名为:"+req.getParameter("uname"));
rep.println("");
}
}/**
* 封装request
* 处理请求信息
**/
public classRequest {//请求方式
privateString method;//请求资源
privateString url;//请求参数
private Map>parameterMapValues;//内部
public static final String CRLF="\r\n";private InputStream is;privateString requestInfo;publicRequest(){
method="";
url="";
parameterMapValues=new HashMap>();
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 voidparseRequestInfo(){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 voidparseParams(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());
}
List values =parameterMapValues.get(key);
values.add(value);
}
}/**
* 解决中文
* @param value
* @param code
* @return*/
privateString decode(String value,String code){try{returnjava.net.URLDecoder.decode(value, code);
}catch(UnsupportedEncodingException e) {//e.printStackTrace();
}return null;
}/**
* 根据页面的name 获取对应的多个值
* @param args*/
publicString[] getParameterValues(String name){
List values=null;if((values=parameterMapValues.get(name))==null){return null;
}else{return values.toArray(new String[0]);
}
}/**
* 根据页面的name 获取对应的单个值
* @param args*/
publicString getParameter(String name){
String[] values=getParameterValues(name);if(null==values){return null;
}return values[0];
}publicString getUrl() {returnurl;
}public voidclose(){
CloseUtil.closeIO(is);
}
}/**
* 封装响应信息
* 组装一个符合http规范的字符串然后推出到浏览器
**/
public classResponse {//两个常量
public static final String CRLF="\r\n";public static final String BLANK=" ";//流
privateBufferedWriter bw ;//正文
privateStringBuilder content;//存储头信息
privateStringBuilder headInfo;//存储正文长度
private int len =0;publicResponse(){
headInfo=newStringBuilder();
content=newStringBuilder();
len=0;
}publicResponse(Socket client){this();try{
bw= new BufferedWriter(newOutputStreamWriter(client.getOutputStream()));
}catch(IOException e) {
headInfo=null;
}
}publicResponse(OutputStream os){this();
bw= new BufferedWriter(newOutputStreamWriter(os));
}/**
* 构建正文*/
publicResponse print(String info){
content.append(info);
len+=info.getBytes().length;return this;
}/**
* 构建正文+回车*/
publicResponse println(String info){
content.append(info).append(CRLF);
len+=(info+CRLF).getBytes().length;return this;
}/**
* 构建响应头*/
private void createHeadInfo(intcode){//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(newDate()).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(intcode) throws IOException{if(null==headInfo){
code=500;
}
createHeadInfo(code);//头信息+分割符
bw.append(headInfo.toString());//正文
bw.append(content.toString());
bw.flush();//推出到浏览器,这样浏览器就可以正常显示了。
}public voidclose(){
CloseUtil.closeIO(bw);
}
}
反射-动态语言:在运行期间随意的改变对象的类型+结构 ,例如ruby js-Java不是动态语言,但具有动态属性(反射)1.反射 镜子(反射理解为保留了类的字节码信息,)1)原来是在编译的时候创建对象,现在是在运行的时候创建对象,2)jvm在创建的时自动生成与之对应的Class对象,同一个类的多个对象在jvm只有一个对应的class文件。2.Class1)可以看成类的元数据,每一个对象在创建是jvm会自动生成与之对应的Class,同类型的对象对应一个Class。2)获取Class对象的3种方式:对象.getClass()、类.class(Student.class)、Class.forName("完整类名")。/**
* 获取结构信息Class对象(源头)*/
public classDemo01 {public static voidmain(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 classDemo02 {public static voidmain(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 classWebApp {private staticServletContext contxt;static{
contxt=newServletContext();
Map mapping =contxt.getMapping();
mapping.put("/login", "login");
mapping.put("/log", "login");
mapping.put("/reg", "register");
Map servlet =contxt.getServlet();
servlet.put("login", "com.bjsxt.server.demo3.LoginServlet");
servlet.put("register", "com.bjsxt.server.demo3.RegisterServlet");
}public staticServlet 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();//确保空构造存在
}
}