Servlet 是在服务器上运行的小程序,是Web服务端封装的组件。
没有servlet时是怎样的:
在CS 通讯中,客户端socket 与服务端serversocket 建立通信,serversocket监听接受连接,启动一接收线程IOThread,IOThread读写SOCKET,输出每行的数据,分析每行数据,得到请求方法;这里的serversocket 就是一个servlet 的底层;servlet 对serversocket 封装; 其中把场景切到BS 结构,此时如何启动服务器是一个问题,在cs中有main方法可以启动;所以在java中提供applet小应用程序可以在web中运行java类;所以servlet = service + applet;然而,在服务器上运行Java,这种程序可使用 Java 编程语言实现。在通信量大的服务器上,JavaServlet 的优点在于它们的执行速度更快于 CGI 程序。各个用户请求被激活成单个程序中的一个线程,而无需创建单独的进程,这意味着服务器端处理请求的系统开销将明显降低.
几点优势:
1.Servlet 在 Web 服务器的地址空间内执行。这样它就没有必要再创建一个单独的进程来处理每个客户端请。
2.Servlet 是独立于平台的,因为它们是用 Java 编写的。
3.Java 类库的全部功能对 Servlet 来说都是可用的。它可以通过 sockets 和 RMI 机制与 applets、数据库进行交互。
作用:
1.读取客户端(浏览器)发送的数据如(表单、cookie,媒体类型等浏览器能解析的)
2.处理数据并生成结果
3.发送数据到客户端(浏览器),数据格式可以有很多(html,xml,gif,excel等)
这个问题,可以参考“为什么使用Servlet” 中的解答;
其中提到,在BS中如何运行serversocket 的服务类(假设命名为ServTomcat),说到底,就是在这个ServTomcat类中main 入口方法来启动一个线程处理客户端请求;该线程用来等待接收客户连接,当有客户连接sever.accept(),则得到socket 并且可以得到相应的流 bufferreader。
在ServTomcat 类 (伪servlet)中处理web 上的http请求,从浏览器到服务端的一次请求都会遵循http协议, 或者说在网络上tcp协议,也就是我们所说socket 来处理客户端与服务器交互。根据http协议规则[请求行,消息报头,请求正文],从流中可以得到 GET|Post方法、HTTP1.1等数据信息,最后将这些信息用打印流方式输出给浏览器;
printstream out = socket.getOutputstream();
out.println("http/1.0 200 ok");
out.println("<html>....</html>");
out.close();//关闭
其中注意,为了让服务器一直处于启动状态,该线程要一直处于运行状态 run() { while(true){ }}。
贴上一段代码,便于参与;一个简单的tomcat
package org.great;
import java.io.*;
import java.net.*;
@author ccq
public class WebServer
{
public static void main(String args[])
{
int i=1, PORT=8080;
ServerSocket server=null;
Socket client=null;
try
{
server=new ServerSocket(PORT);
System.out.println("Web Server is listening on port "+server.getLocalPort());
for (;;)
{
client=server.accept(); //接受客户机的连接请求
new ConnectionThread(client,i).start();
i++;
}
}
catch (Exception e) {System.out.println(e);}
}
}
/* ConnnectionThread类完成与一个Web浏览器的通信 */
class ConnectionThread extends Thread
{
Socket client; //连接Web浏览器的socket字
int counter; //计数器
public ConnectionThread(Socket cl,int c)
{
client=cl;
counter=c;
}
public void run() //线程体
{
try
{
String destIP=client.getInetAddress().toString(); //客户机IP地址
int destport=client.getPort(); //客户机端口号
System.out.println("Connection "+counter+":connected to "+destIP+" on port "+destport+".");
PrintStream outstream=new PrintStream(client.getOutputStream());
DataInputStream instream=new DataInputStream(client.getInputStream());
String inline=instream.readLine(); //读取Web浏览器提交的请求信息
System.out.println("Received:"+inline);
if (getrequest(inline))
{ //如果是GET请求
String filename=getfilename(inline);
File file=new File(filename);
if (file.exists())
{ //若文件存在,则将文件送给Web浏览器
System.out.println(filename+" requested.");
outstream.println("HTTP/1.0 200 OK");
outstream.println("MIME_version:1.0");
outstream.println("Content_Type:text/html");
int len=(int)file.length();
outstream.println("Content_Length:"+len);
outstream.println("");
sendfile(outstream,file); //发送文件
outstream.flush();
}
else
{ //文件不存在时
String msg1="<html><head><title>Not Found</title></head><body><h1>hah Error 404-file not found</h1></body></html>";
outstream.println("HTTP/1.0 404 no found");
outstream.println("Content_Type:text/html");
outstream.println("Content_Length:"+msg1.length()+2);
outstream.println("");
outstream.println(msg1);
outstream.flush();
}
}
//instream.close();
//outstream.close();
long m1=1; //延时
while (m1<11100000) {m1++;}
client.close();
}
catch (IOException e)
{
System.out.println("Exception:"+e);
}
}
/* 获取请求类型是否为“GET” */
boolean getrequest(String s)
{
if (s.length()>0)
{
if (s.substring(0,3).equalsIgnoreCase("GET")) return true;
}
return false;
}
/* 获取要访问的文件名 */
String getfilename(String s)
{
String f=s.substring(s.indexOf(' ')+1);
f=f.substring(0,f.indexOf(' '));
try
{
if (f.charAt(0)=='/')
f=f.substring(1);
}
catch (StringIndexOutOfBoundsException e)
{
System.out.println("Exception:"+e);
}
if (f.equals("")) f="index.html";
return f;
}
/*把指定文件发送给Web浏览器 */
void sendfile(PrintStream outs,File file)
{
try
{
DataInputStream in=new DataInputStream(new FileInputStream(file));
int len=(int)file.length();
byte buf[]=new byte[len];
in.readFully(buf);
outs.write(buf,0,len);
/*
DataOutputStream ou=new DataOutputStream(System.out);
ou.write(buf,0,len);
*/
outs.flush();
in.close();
}
catch (Exception e)
{
System.out.println("Error retrieving file.");
System.exit(1);
}
}
}
测试访问路径:http://localhost:8080/上下文名(一般用工程名)/index.html ,另这时run(){ 中没有加while(true) } 所以此例中只能请求一次,服务器就停止;