上述过程中,虽然通过编译java源文件生成class文件,但是class仅仅只是一个定义声明。无法以实体的形式载入内存中进行执行相应的方法。
但是通过Java Class类提供的newInstance接口,可以通过类名来创建类实例(Instance)对象。这样就可以占用内存执行该对象的相应方法。以下将给出载入class对象和执行类对象的实例对象的代码。
以上代码中,载入类实际上就是根据类名生成类对象的实例对象,再将类实例(Instance)对象载入到内存中。//Create URL list by path. URL [] URLs = {new URL("file:///" + path + "/"), null}; //Create Java URLClassLoader by URLs URLClassLoader URLCl = new URLClassLoader(URLs); //Load class by 类名 Class cs = URLCl.loadClass(className); if(cs != null) { //Put 类名 (as key) and class instance object (as value) into container m_ht.put(className, cs.newInstance() ); System.out.println(className + " loaded ok."); return true; } else { System.out.println(className + " loaded faild."); return false; }
对于类的执行,首先我们要清楚的是,我们所生成的类的用途是什么。不同于普通的Java Application,我们所通过jsp源文件生成的类都是服务页(Server Page)类,主要的用途就是从HTTP服务器接受到的参数中获取信息,并将信息的处理结果输出给客户端。所以,这些服务页类的框架应该是一致的,即具备参数解析和客户端应答功能。我们说执行这些服务页类,实际上就是执行定义在类对象的实例对象的相关函数,进行参数解析和客户端应答。以下是执行服务页类的实例代码:
以上代码中,我们根据类名来获取对应的类实例(Instance)对象。并将该类对象的实例对象转换为ServerPage对象(实际上,我们设计的思路就是,所有的网页类都继承于一个叫ServerPage的类),并调用ServerPage 类的Init方法。而Init方法就是所有服务页(Server Page)类的关键函数。Init函数的源代码如下://Get the class instance object by class name, //And convert the object to be ServerPage object obj = (ServerPage)(m_ht.get(className)); if(obj != null) { try { //Call the function Init for ServerPage obj.Init(params, out); } catch (Exception execute) { System.out.println("Initialize server page failure."); return; } }
在ServerPage类的Init方法中,正是使用客户端套接字的输入类对象和输出类对象创建了一个用于解析请求参数的对象和一个用于向客户端输出的对象。//The member which be used for parse the params_list public static HTTPRequest Request = null; //The member which be used for response the result public static HTTPResponse Response = null;…… //---------------------------------------------------------------- //Initialize the member variants public void Init(final String params, final java.io.PrintWriter out) { try { //Create Request member for parse the parameters list Request = new HTTPRequest(params); //Create Respond member for output to client socket Response = new HTTPResponse(out); } catch (java.io.IOException init) { System.out.print("Initialize the params_list and response failure."); return; } }
这里需要补充的是,在本HTTP服务器设计中,设计了三个基本类,分别是:
(A)ServerPage(服务页)类,所有我们jsp源文件生成的类都是继承于ServerPage类。所有由jsp源文件生成的类的java源文件的框架的实例代码为:
以上代码可以看出,HTTP服务器中所有由jsp源文件生成的类,都是继承于ServerPage类,并通过重载ServerPage的Init函数来创建和初始化该类的解析请求参数的对象和向客户端输出的对象。服务页所有输出语句都写在output函数中。//Generate framework of server page fout.println("//Java Server Page intermedia file. All rights reserved by Foolstudio."); fout.println("public class " + className + " extends ServerPage {"); //Overload the function init of class ServerPage fout.println("public void Init(final String __params, final java.io.PrintWriter __out) {"); fout.println("super.Init(__params, __out);"); fout.println("output();"); fout.println("}"); //All of output in the function output fout.println("private void output() {");
ServerPage类具有两个重要的成员。一个是Request类,顾名思义就是对客户端请求进行处理;一个是Respond类,就是对客户端进行回应。
(B)Request类,该类主要用于解析HTTP服务器传递过来的请求的参数,例如:“/login.jsp?name=paul&sex=male”中“?”以后的参数列表。并提供参数制的获取。
以下是Request类的主要方法:
//The member be used for contains the pairs of key and value. private Hashtable m_ht; //---------------------------------------------------------------- //Constructor //Parse the request public HTTPRequest(String params) throws java.io.IOException { //Create key-value container m_ht = new Hashtable(128); if(params.equals("") == true) { return; } //Decode the parameters list (can select GBK and GB2312) params = URLDecoder.decode(params, "GBK"); //Split the key-value list splitRequest(params); } …… //---------------------------------------------------------------- //Get the value by key public String getParameter(final String key)
(C)Respond类,主要用于向客户端进行输出。只需要具备输出函数即可。