最近完成tomcat中,有以下两个类
public class PrimitiveServlet implements Servlet {
public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
PrintWriter writer = servletResponse.getWriter();
String message = "HTTP/1.1 200 OK\r\n"+
"Content-Type: text/html\r\n"+
"\r\n";
writer.println(message);
writer.println("Hello. Roses are red.");
writer.println("Violets are blue.");
}
}
public class ServletProcessor1 {
public void process(Request request, Response response){
String uri = request.getUri();
String servletName = uri.substring(uri.lastIndexOf('/')+1);
URLClassLoader loader = null;
try {
URL[] urls = new URL[1];
URLStreamHandler streamHandler = null;
File classPath = new File(Constants.WEB_ROOT);
String repository = (new URL("file", null, classPath.getCanonicalPath()+File.separator)).toString();
urls[0] = new URL(null, repository, streamHandler);
loader = new URLClassLoader(urls);
}catch (Exception e){
e.printStackTrace();
}
Class myclass = null;
try {
myclass = loader.loadClass("servlet."+servletName);
}catch (ClassNotFoundException e){
e.printStackTrace();
}
Servlet servlet = null;
try {
servlet = (Servlet) myclass.newInstance();
servlet.service(request, response);
}catch (Exception e){
e.printStackTrace();
}
}
}
在Process类中,通过类加载,并通过映射的方式调用方法,调用方法时候,将Requst和Response(分别是ServletRequest和ServletResponse的子类)向上转型,以此来实现调用。
但该做法存在一定的安全问题。
当有人了解该代码。
可以在加载的类中,再将参数进行下转型以此获得子类的Request和Response,以此在一些不合适的地方调用子类各自的公共方法。
为了使向上转型得类没有向下转型并调用子类独有得方法。可以使用外观类来避免这个问题。
外观类:实现子类相同得接口,并将父类得引用指向子类(该引用私有)。而实现接口得方法相应的调用子类对象的方法。以此避免安全问题。
具体代码:
子类代码
public class Request implements ServletRequest {
private InputStream input;
private String uri;
public Request(InputStream stream){
input = stream;
}
public void parse(){
StringBuffer request = new StringBuffer(2048);
int i;
byte[] buffer = new byte[2048];
try {
i = input.read(buffer);
}catch (IOException e){
e.printStackTrace();
i = -1;
}
for (int j = 0; j<i ; j++){
request.append((char)buffer[j]);
}
System.out.println(request.toString());
uri = parseUri(request.toString());
}
private String parseUri(String requestString){
int index1, index2 ;
index1 = requestString.indexOf(' ');
if (index1!=-1){
index2 = requestString.indexOf(' ', index1+1);
if (index2>index1){
return requestString.substring(index1+1, index2);
}
}
return null;
}
public String getUri(){
return uri;
}
public InputStream getInput() {
return input;
}
外观类
public class FaceRequest implements ServletRequest {
private ServletRequest servletRequest;
public FaceRequest(ServletRequest servletRequest){
this.servletRequest = servletRequest;
}
public Locale getLocale() {
return servletRequest.getLocale();
}
public String getContentType() {
return servletRequest.getContentType();
}
}