用Java实现简单的服务器——实现浏览器对Java文件的访问

       在上一篇《Java实现简单的服务器--访问静态HTML页面》的基础上进行修改,实现浏览器对Java文件的访问。没有使用Servlet,但大致呈现了Servlet的运行原理。

项目的目录结构修改如下图:

一、修改服务器StaticWebServer代码

package imitatetomcat;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;

public class StaticWebServer {
	//定义网页所在的目录位置
	public static final String WEB_ROOT=System.getProperty("user.dir") + File.separator+ "webroot"; 
	
    public static void main(String[] args) {
		try {
			ServerSocket server = new ServerSocket(8080);
			
			while(true) {
			Socket socket = server.accept();
			//在控制台输出浏览器的IP地址和端口号
		    System.out.println(socket.getInetAddress()+":"+socket.getPort());
			InputStream in=socket.getInputStream();
			OutputStream out=socket.getOutputStream();
			//把处理请求和响应的工作交给类Request和Response
		    Request	 request=new Request(in);
		    request.parse();
			Response response=new Response(out);
			response.setRequest(request);
			//判断是否是静态页面(假如静态请求资源中有".",动态页面的只写文件名)
			if(request.getUri().contains(".")) {
				response.sendStaticResource();
			}
			else {
				try {
					String[] fileName=request.getUri().split("\\?");
					response.sendDynamicResource(request,response,fileName[0]);
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
			
			in.close();
			out.close();
			socket.close();
		 }
			//server.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
}

二、修改请求类Request类

import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;

/*处理请求信息的类,该类只简单获取首行中请求资源名*/
public class Request{
	 private InputStream input;
	 //存放请求资源文件的字符串
	 private String uri;
	 //存放请求参数(简单处理下,只能放字符串)
	 private Map<String, String>  map=new HashMap<String, String>();

	public Request(InputStream input) {
	    this.input = input;
	  }

	  public void parse() {
	    int i;
	    byte[] buf = new byte[1048];
	    try {
	      i = input.read(buf);
	    }
	    catch (IOException e) {
	      e.printStackTrace();
	      i = -1;
	    }
	    String str=new String(buf);
	    //在控制台输出请求信息
	    System.out.print(str);
	    //截取请求Url
	    uri = parseUri(str);
	    if(uri.contains("?")) {
	    	 //对请求参数进行分割并放到map中
			String parameters=parseParameters(str);
		    String paras[]=parameters.split("\\&");
		    for (int j = 0; j < paras.length; j++) {
				String para[]=paras[j].split("\\=");
				System.out.println(para[0]+":"+para[1]);
				if (para[0]!=null) {
					map.put(para[0],para[1]);
				}
			}
	    }   
	  }
	  
      //从请求信息中截取请求Url,即首行的中间部分
	  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 +2, index2);
	    }
	    return null;
	  }
	  
	//从请求信息中截取请求Url后的请求参数(?name=zhangsan&password=123),先实现只取GET方法的
	  private String parseParameters(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 Map<String, String> getMap() {
			return map;
	  }
}

三、修改请求类Response类

package imitatetomcat;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.OutputStream;

/* 处理响应信息的类 */
public class Response{
	 Request request;
	 OutputStream output;

	  public Response(OutputStream output) {
	    this.output = output;
	  }
      public OutputStream getOutput() {
    	  return  this.output;
      }
	  public void setRequest(Request request) {
	    this.request = request;
	  }
	  
	  //1.加响应头
	  //2.读取文件
	  public void sendStaticResource() throws IOException {
	    byte[] bytes = new byte[1024*1024];//响应的内容假如不超过1024*1024个字节
	    FileInputStream fis = null;
	    try {
	      System.out.println(StaticWebServer.WEB_ROOT+File.separator+request.getUri());
	      File file = new File(StaticWebServer.WEB_ROOT+File.separator+request.getUri());
	      if (file.exists()) {
	      fis = new FileInputStream(file);
	      int ch = fis.read(bytes, 0, 1024*1024);
	      String str="http/1.1 200 ok\r\n\r\n";
	      output.write(str.getBytes());
	      output.write(bytes, 0, ch);
	      }
	      else {
	        //如果没有发现文件,返回404错误
	        String errorMessage = "HTTP/1.1 404 File Not Found\r\n" +
	          "Content-Type: text/html\r\n" +
	          "Content-Length: 23\r\n" +
	          "\r\n" +
	          "<h1>File Not Found</h1>";
	        output.write(errorMessage.getBytes());
	      }
	    }
	    catch (Exception e) {
	      System.out.println(e.toString() );
	    }
	    finally {
	      if (fis!=null)
	        fis.close();
	    }
	  }
	//1.加响应头
	//2.编译并执行文件
     public void sendDynamicResource(Request request,Response response,String dynamicFile) throws Exception{
    	 try {
    	 File file = new File(System.getProperty("user.dir")+File.separator+"src"+File.separator+"test\\"+dynamicFile+".java");
	      if (file.exists()) {
	    	  //Runtime.getRuntime()调用javac命令,编译Java文件到class文件
	     	 String javaAbsolutePath =  System.getProperty("user.dir")+"\\src\\test\\"+dynamicFile+".java";
	     	 Process process = Runtime.getRuntime().exec("javac "+ javaAbsolutePath);
	  		
	  		//加载.class文件
	  		 Class<?> forName = Class.forName("test."+dynamicFile);
	  		 Servleter newInstance = (Servleter)forName.newInstance();
	  		 newInstance.service(request,response);
	      }
	      else {
	        //如果没有发现文件,返回404错误
	        String errorMessage = "HTTP/1.1 404 File Not Found\r\n" +
	          "Content-Type: text/html\r\n" +
	          "Content-Length: 23\r\n" +
	          "\r\n" +
	          "<h1>File Not Found</h1>";
	        output.write(errorMessage.getBytes());
	      }
	    }
	    catch (Exception e) {
	      System.out.println(e.toString() );
	    }
     }
}	

四、制定可访问Java类文件的标准--接口Servleter

package imitatetomcat;

public interface Servleter {
   public void service(Request request,Response response);
}

五、测试时用的可访问的Java类

package test;

import java.io.IOException;
import java.util.Map;

import imitatetomcat.Request;
import imitatetomcat.Response;
import imitatetomcat.Servleter;

public class TestJavaFile implements Servleter{
	
      @Override
       public void service(Request request, Response response) {
       Map<String, String> map=request.getMap();
       String name=map.get("name");
       String password=map.get("password");
       String respString="hello!"+name+"; your password is:"+password;
       String str="http/1.1 200 ok\r\n\r\n";
       try {
		response.getOutput().write(str.getBytes());
		response.getOutput().write(respString.getBytes());
	} catch (IOException e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	}
       
	}
}

运行结果:

浏览器访问时的url和访问结果,如下图:

实现了服务器对浏览器的请求信息进行了处理,并把处理结果发给浏览器。只要在test包中(位置固定,为了代码实现简单)编写任意一个实现了Servleter接口的类,浏览器都可以访问了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值