组件实现
在HttpServer中
public void await() {
//…
// create Response object
Response response = new Response(output);
response.setRequest(request);
// 不再有response自己处理
//response.sendStaticResource();
// 而是如果以/servlet/开头,则委托ServletProcessor处理
if (request.getUri().startsWith("/servlet/")) {
ServletProcessor1 processor = new ServletProcessor1();
processor.process(request, response);
} else {
// 原有的静态资源处理
StaticResourceProcessor processor = new StaticResourceProcessor();
processor.process(request, response);
}
// ....
}
ServletProcessor 如何处理的?
public class ServletProcessor1 {
public void process(Request request, Response response) {
// 获取servlet名字
String uri = request.getUri();
String servletName = uri.substring(uri.lastIndexOf("/") + 1);
// 初始化URLClassLoader
URLClassLoader loader = null;
try {
// create a URLClassLoader
URL[] urls = new URL[1];
URLStreamHandler streamHandler = null;
File classPath = new File(Constants.WEB_ROOT);
// the forming of repository is taken from the createClassLoader method in
// org.apache.catalina.startup.ClassLoaderFactory
String repository = (new URL("file", null, classPath.getCanonicalPath() + File.separator)).toString() ;
// the code for forming the URL is taken from the addRepository method in
// org.apache.catalina.loader.StandardClassLoader class.
urls[0] = new URL(null, repository, streamHandler);
loader = new URLClassLoader(urls);
} catch (IOException e) {
System.out.println(e.toString() );
}
// 用classLoader加载上面的servlet
Class myClass = null;
try {
myClass = loader.loadClass(servletName);
}
catch (ClassNotFoundException e) {
System.out.println(e.toString());
}
// 将加载到的class转成Servlet,并调用service方法处理
Servlet servlet = null;
try {
servlet = (Servlet) myClass.newInstance();
servlet.service((ServletRequest) request, (ServletResponse) response);
} catch (Exception e) {
System.out.println(e.toString());
} catch (Throwable e) {
System.out.println(e.toString());
}
}
}
Repsonse
public class PrimitiveServlet implements Servlet {
public void init(ServletConfig config) throws ServletException {
System.out.println(“init”);
}
public void service(ServletRequest request, ServletResponse response)
throws ServletException, IOException {
System.out.println(“from service”);
PrintWriter out = response.getWriter();
out.println(“Hello. Roses are red.”);
out.print(“Violets are blue.”);
}
public void destroy() {
System.out.println(“destroy”);
}
public String getServletInfo() {
return null;
}
public ServletConfig getServletConfig() {
return null;
}
}
访问 URL
利用外观模式改造
上述代码存在一个问题,
// 将加载到的class转成Servlet,并调用service方法处理
Servlet servlet = null;
try {
servlet = (Servlet) myClass.newInstance();
servlet.service((ServletRequest) request, (ServletResponse) response);
} catch (Exception e) {
System.out.println(e.toString());
} catch (Throwable e) {
System.out.println(e.toString());
}
这里直接处理将request和response传给servlet处理是不安全的,因为request可以向下转型为Request类,从而ServeletRequest便具备了访问Request中方法的能力。
public class Request implements ServletRequest {
// 一些public方法
}
public class Response implements ServletResponse {
}
解决的方法便是通过外观模式进行改造:
RequestFacade为例
public class RequestFacade implements ServletRequest {
private ServletRequest request = null;
public RequestFacade(Request request) {
this.request = request;
}
/* implementation of the ServletRequest*/
public Object getAttribute(String attribute) {
return request.getAttribute(attribute);
}
public Enumeration getAttributeNames() {
return request.getAttributeNames();
}
public String getRealPath(String path) {
return request.getRealPath(path);
}
…
Process中由传入外观类
Servlet servlet = null;
RequestFacade requestFacade = new RequestFacade(request); // 转换成外观类
ResponseFacade responseFacade = new ResponseFacade(response);// 转换成外观类
try {
servlet = (Servlet) myClass.newInstance();
servlet.service((ServletRequest) requestFacade, (ServletResponse) responseFacade);
}
catch (Exception e) {
System.out.println(e.toString());
}
catch (Throwable e) {
System.out.println(e.toString());
}
亚马逊测评 www.yisuping.cn
USB Microphone https://www.soft-voice.com/
Wooden Speakers https://www.zeshuiplatform.com/